mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-13 23:37:13 -06:00
FlatSmoothScrollingTest: added simple line chart that shows changes to scrollbar values
This commit is contained in:
@@ -16,15 +16,27 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.testing;
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.AdjustmentEvent;
|
import java.awt.event.AdjustmentEvent;
|
||||||
import java.awt.event.AdjustmentListener;
|
import java.awt.event.AdjustmentListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
import javax.swing.tree.*;
|
import javax.swing.tree.*;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,6 +56,8 @@ public class FlatSmoothScrollingTest
|
|||||||
FlatSmoothScrollingTest() {
|
FlatSmoothScrollingTest() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
|
updateChartDelayedChanged();
|
||||||
|
|
||||||
// allow enabling/disabling smooth scrolling with Alt+S without moving focus to checkbox
|
// allow enabling/disabling smooth scrolling with Alt+S without moving focus to checkbox
|
||||||
registerKeyboardAction(
|
registerKeyboardAction(
|
||||||
e -> {
|
e -> {
|
||||||
@@ -53,23 +67,30 @@ public class FlatSmoothScrollingTest
|
|||||||
KeyStroke.getKeyStroke( "alt " + (char) smoothScrollingCheckBox.getMnemonic() ),
|
KeyStroke.getKeyStroke( "alt " + (char) smoothScrollingCheckBox.getMnemonic() ),
|
||||||
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
||||||
|
|
||||||
listScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "list vert" ) );
|
listLabel.setIcon( new ColorIcon( Color.red.darker() ) );
|
||||||
listScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "list horz" ) );
|
treeLabel.setIcon( new ColorIcon( Color.blue.darker() ) );
|
||||||
|
tableLabel.setIcon( new ColorIcon( Color.green.darker() ) );
|
||||||
|
textAreaLabel.setIcon( new ColorIcon( Color.magenta.darker() ) );
|
||||||
|
textPaneLabel.setIcon( new ColorIcon( Color.cyan.darker() ) );
|
||||||
|
editorPaneLabel.setIcon( new ColorIcon( Color.orange.darker() ) );
|
||||||
|
|
||||||
treeScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "tree vert" ) );
|
listScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "list vert", Color.red.darker() ) );
|
||||||
treeScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "tree horz" ) );
|
listScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "list horz", Color.red ) );
|
||||||
|
|
||||||
tableScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "table vert" ) );
|
treeScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "tree vert", Color.blue.darker() ) );
|
||||||
tableScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "table horz" ) );
|
treeScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "tree horz", Color.blue ) );
|
||||||
|
|
||||||
textAreaScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textArea vert" ) );
|
tableScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "table vert", Color.green.darker() ) );
|
||||||
textAreaScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textArea horz" ) );
|
tableScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "table horz", Color.green ) );
|
||||||
|
|
||||||
textPaneScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textPane vert" ) );
|
textAreaScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textArea vert", Color.magenta.darker() ) );
|
||||||
textPaneScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textPane horz" ) );
|
textAreaScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textArea horz", Color.magenta ) );
|
||||||
|
|
||||||
editorPaneScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "editorPane vert" ) );
|
textPaneScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textPane vert", Color.cyan.darker() ) );
|
||||||
editorPaneScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "editorPane horz" ) );
|
textPaneScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "textPane horz", Color.cyan ) );
|
||||||
|
|
||||||
|
editorPaneScrollPane.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "editorPane vert", Color.orange.darker() ) );
|
||||||
|
editorPaneScrollPane.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "editorPane horz", Color.orange ) );
|
||||||
|
|
||||||
ArrayList<String> items = new ArrayList<>();
|
ArrayList<String> items = new ArrayList<>();
|
||||||
for( char ch = '0'; ch < 'z'; ch++ ) {
|
for( char ch = '0'; ch < 'z'; ch++ ) {
|
||||||
@@ -138,27 +159,40 @@ public class FlatSmoothScrollingTest
|
|||||||
UIManager.put( "ScrollPane.smoothScrolling", smoothScrollingCheckBox.isSelected() );
|
UIManager.put( "ScrollPane.smoothScrolling", smoothScrollingCheckBox.isSelected() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearChart() {
|
||||||
|
lineChartPanel.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChartDelayedChanged() {
|
||||||
|
lineChartPanel.setUpdateDelayed( updateChartDelayedCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
smoothScrollingCheckBox = new JCheckBox();
|
smoothScrollingCheckBox = new JCheckBox();
|
||||||
listLabel = new JLabel();
|
listLabel = new JLabel();
|
||||||
label1 = new JLabel();
|
treeLabel = new JLabel();
|
||||||
label5 = new JLabel();
|
tableLabel = new JLabel();
|
||||||
listScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
listScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
list = new JList<>();
|
list = new JList<>();
|
||||||
treeScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
treeScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
tree = new JTree();
|
tree = new JTree();
|
||||||
tableScrollPane = new JScrollPane();
|
tableScrollPane = new JScrollPane();
|
||||||
table = new JTable();
|
table = new JTable();
|
||||||
label2 = new JLabel();
|
textAreaLabel = new JLabel();
|
||||||
label3 = new JLabel();
|
textPaneLabel = new JLabel();
|
||||||
label4 = new JLabel();
|
editorPaneLabel = new JLabel();
|
||||||
textAreaScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
textAreaScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
textArea = new JTextArea();
|
textArea = new JTextArea();
|
||||||
textPaneScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
textPaneScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
textPane = new JTextPane();
|
textPane = new JTextPane();
|
||||||
editorPaneScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
editorPaneScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
editorPane = new JEditorPane();
|
editorPane = new JEditorPane();
|
||||||
|
panel1 = new JPanel();
|
||||||
|
updateChartDelayedCheckBox = new JCheckBox();
|
||||||
|
clearChartButton = new JButton();
|
||||||
|
scrollPane1 = new JScrollPane();
|
||||||
|
lineChartPanel = new FlatSmoothScrollingTest.LineChartPanel();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
setLayout(new MigLayout(
|
setLayout(new MigLayout(
|
||||||
@@ -173,7 +207,8 @@ public class FlatSmoothScrollingTest
|
|||||||
"[]" +
|
"[]" +
|
||||||
"[200,grow,fill]" +
|
"[200,grow,fill]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[200,grow,fill]"));
|
"[200,grow,fill]" +
|
||||||
|
"[300,grow,fill]"));
|
||||||
|
|
||||||
//---- smoothScrollingCheckBox ----
|
//---- smoothScrollingCheckBox ----
|
||||||
smoothScrollingCheckBox.setText("Smooth scrolling");
|
smoothScrollingCheckBox.setText("Smooth scrolling");
|
||||||
@@ -184,15 +219,18 @@ public class FlatSmoothScrollingTest
|
|||||||
|
|
||||||
//---- listLabel ----
|
//---- listLabel ----
|
||||||
listLabel.setText("JList:");
|
listLabel.setText("JList:");
|
||||||
|
listLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
add(listLabel, "cell 0 1,aligny top,growy 0");
|
add(listLabel, "cell 0 1,aligny top,growy 0");
|
||||||
|
|
||||||
//---- label1 ----
|
//---- treeLabel ----
|
||||||
label1.setText("JTree:");
|
treeLabel.setText("JTree:");
|
||||||
add(label1, "cell 1 1");
|
treeLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
|
add(treeLabel, "cell 1 1");
|
||||||
|
|
||||||
//---- label5 ----
|
//---- tableLabel ----
|
||||||
label5.setText("JTable:");
|
tableLabel.setText("JTable:");
|
||||||
add(label5, "cell 2 1");
|
tableLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
|
add(tableLabel, "cell 2 1");
|
||||||
|
|
||||||
//======== listScrollPane ========
|
//======== listScrollPane ========
|
||||||
{
|
{
|
||||||
@@ -212,17 +250,20 @@ public class FlatSmoothScrollingTest
|
|||||||
}
|
}
|
||||||
add(tableScrollPane, "cell 2 2 2 1,width 100,height 100");
|
add(tableScrollPane, "cell 2 2 2 1,width 100,height 100");
|
||||||
|
|
||||||
//---- label2 ----
|
//---- textAreaLabel ----
|
||||||
label2.setText("JTextArea:");
|
textAreaLabel.setText("JTextArea:");
|
||||||
add(label2, "cell 0 3");
|
textAreaLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
|
add(textAreaLabel, "cell 0 3");
|
||||||
|
|
||||||
//---- label3 ----
|
//---- textPaneLabel ----
|
||||||
label3.setText("JTextPane:");
|
textPaneLabel.setText("JTextPane:");
|
||||||
add(label3, "cell 1 3");
|
textPaneLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
|
add(textPaneLabel, "cell 1 3");
|
||||||
|
|
||||||
//---- label4 ----
|
//---- editorPaneLabel ----
|
||||||
label4.setText("JEditorPane:");
|
editorPaneLabel.setText("JEditorPane:");
|
||||||
add(label4, "cell 2 3");
|
editorPaneLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
|
add(editorPaneLabel, "cell 2 3");
|
||||||
|
|
||||||
//======== textAreaScrollPane ========
|
//======== textAreaScrollPane ========
|
||||||
{
|
{
|
||||||
@@ -241,45 +282,92 @@ public class FlatSmoothScrollingTest
|
|||||||
editorPaneScrollPane.setViewportView(editorPane);
|
editorPaneScrollPane.setViewportView(editorPane);
|
||||||
}
|
}
|
||||||
add(editorPaneScrollPane, "cell 2 4");
|
add(editorPaneScrollPane, "cell 2 4");
|
||||||
|
|
||||||
|
//======== panel1 ========
|
||||||
|
{
|
||||||
|
panel1.setLayout(new MigLayout(
|
||||||
|
"ltr,insets 0,hidemode 3,aligny bottom",
|
||||||
|
// columns
|
||||||
|
"[200,right]",
|
||||||
|
// rows
|
||||||
|
"[]" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- updateChartDelayedCheckBox ----
|
||||||
|
updateChartDelayedCheckBox.setText("Update chart delayed");
|
||||||
|
updateChartDelayedCheckBox.setMnemonic('U');
|
||||||
|
updateChartDelayedCheckBox.setSelected(true);
|
||||||
|
updateChartDelayedCheckBox.addActionListener(e -> updateChartDelayedChanged());
|
||||||
|
panel1.add(updateChartDelayedCheckBox, "cell 0 0");
|
||||||
|
|
||||||
|
//---- clearChartButton ----
|
||||||
|
clearChartButton.setText("Clear Chart");
|
||||||
|
clearChartButton.addActionListener(e -> clearChart());
|
||||||
|
panel1.add(clearChartButton, "cell 0 1");
|
||||||
|
}
|
||||||
|
add(panel1, "cell 3 4");
|
||||||
|
|
||||||
|
//======== scrollPane1 ========
|
||||||
|
{
|
||||||
|
scrollPane1.setViewportView(lineChartPanel);
|
||||||
|
}
|
||||||
|
add(scrollPane1, "cell 0 5 4 1,width 100");
|
||||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
}
|
}
|
||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
private JCheckBox smoothScrollingCheckBox;
|
private JCheckBox smoothScrollingCheckBox;
|
||||||
private JLabel listLabel;
|
private JLabel listLabel;
|
||||||
private JLabel label1;
|
private JLabel treeLabel;
|
||||||
private JLabel label5;
|
private JLabel tableLabel;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane listScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane listScrollPane;
|
||||||
private JList<String> list;
|
private JList<String> list;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane treeScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane treeScrollPane;
|
||||||
private JTree tree;
|
private JTree tree;
|
||||||
private JScrollPane tableScrollPane;
|
private JScrollPane tableScrollPane;
|
||||||
private JTable table;
|
private JTable table;
|
||||||
private JLabel label2;
|
private JLabel textAreaLabel;
|
||||||
private JLabel label3;
|
private JLabel textPaneLabel;
|
||||||
private JLabel label4;
|
private JLabel editorPaneLabel;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane textAreaScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane textAreaScrollPane;
|
||||||
private JTextArea textArea;
|
private JTextArea textArea;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane textPaneScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane textPaneScrollPane;
|
||||||
private JTextPane textPane;
|
private JTextPane textPane;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane editorPaneScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane editorPaneScrollPane;
|
||||||
private JEditorPane editorPane;
|
private JEditorPane editorPane;
|
||||||
|
private JPanel panel1;
|
||||||
|
private JCheckBox updateChartDelayedCheckBox;
|
||||||
|
private JButton clearChartButton;
|
||||||
|
private JScrollPane scrollPane1;
|
||||||
|
private FlatSmoothScrollingTest.LineChartPanel lineChartPanel;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
//---- class AdjustmentHandler --------------------------------------------
|
//---- class AdjustmentHandler --------------------------------------------
|
||||||
|
|
||||||
private static class AdjustmentHandler
|
private class AdjustmentHandler
|
||||||
implements AdjustmentListener
|
implements AdjustmentListener
|
||||||
{
|
{
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final Color chartColor;
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
AdjustmentHandler( String name ) {
|
AdjustmentHandler( String name ) {
|
||||||
|
this( name, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
AdjustmentHandler( String name, Color chartColor ) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.chartColor = chartColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustmentValueChanged( AdjustmentEvent e ) {
|
public void adjustmentValueChanged( AdjustmentEvent e ) {
|
||||||
|
if( chartColor != null ) {
|
||||||
|
JScrollBar sb = (JScrollBar) e.getSource();
|
||||||
|
double value = (double) (e.getValue() - sb.getMinimum()) / (double) (sb.getMaximum() - sb.getVisibleAmount());
|
||||||
|
lineChartPanel.addValue( value, chartColor );
|
||||||
|
}
|
||||||
|
|
||||||
System.out.printf( "%s (%d): %s %3d %b%n",
|
System.out.printf( "%s (%d): %s %3d %b%n",
|
||||||
name, ++count,
|
name, ++count,
|
||||||
adjustmentType2Str( e.getAdjustmentType() ),
|
adjustmentType2Str( e.getAdjustmentType() ),
|
||||||
@@ -316,4 +404,251 @@ public class FlatSmoothScrollingTest
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class LineChartPanel -----------------------------------------------
|
||||||
|
|
||||||
|
private static class LineChartPanel
|
||||||
|
extends JComponent
|
||||||
|
implements Scrollable
|
||||||
|
{
|
||||||
|
private static final int SECOND_WIDTH = 200;
|
||||||
|
private static final int NEW_SEQUENCE_TIME_LAG = 500;
|
||||||
|
private static final int NEW_SEQUENCE_GAP = 20;
|
||||||
|
|
||||||
|
private static class Data {
|
||||||
|
final double value;
|
||||||
|
final long time; // in milliseconds
|
||||||
|
|
||||||
|
Data( double value, long time ) {
|
||||||
|
this.value = value;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<Color, List<Data>> color2dataMap = new HashMap<>();
|
||||||
|
private final Timer repaintTime;
|
||||||
|
private Color lastUsedChartColor;
|
||||||
|
private boolean updateDelayed;
|
||||||
|
|
||||||
|
LineChartPanel() {
|
||||||
|
int resolution = FlatUIUtils.getUIInt( "ScrollPane.smoothScrolling.resolution", 10 );
|
||||||
|
|
||||||
|
repaintTime = new Timer( resolution * 2, e -> repaintAndRevalidate() );
|
||||||
|
repaintTime.setRepeats( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addValue( double value, Color chartColor ) {
|
||||||
|
List<Data> chartData = color2dataMap.computeIfAbsent( chartColor, k -> new ArrayList<>() );
|
||||||
|
chartData.add( new Data( value, System.currentTimeMillis()) );
|
||||||
|
|
||||||
|
lastUsedChartColor = chartColor;
|
||||||
|
|
||||||
|
if( updateDelayed ) {
|
||||||
|
repaintTime.stop();
|
||||||
|
repaintTime.start();
|
||||||
|
} else
|
||||||
|
repaintAndRevalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
color2dataMap.clear();
|
||||||
|
lastUsedChartColor = null;
|
||||||
|
|
||||||
|
repaint();
|
||||||
|
revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpdateDelayed( boolean updateDelayed ) {
|
||||||
|
this.updateDelayed = updateDelayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repaintAndRevalidate() {
|
||||||
|
repaint();
|
||||||
|
revalidate();
|
||||||
|
|
||||||
|
// scroll horizontally
|
||||||
|
if( lastUsedChartColor != null ) {
|
||||||
|
int[] lastSeqX = new int[1];
|
||||||
|
int cw = chartWidth( color2dataMap.get( lastUsedChartColor ), lastSeqX );
|
||||||
|
scrollRectToVisible( new Rectangle( lastSeqX[0], 0, cw - lastSeqX[0], getHeight() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent( Graphics g ) {
|
||||||
|
Graphics g2 = g.create();
|
||||||
|
try {
|
||||||
|
HiDPIUtils.paintAtScale1x( (Graphics2D) g2, this, this::paintImpl );
|
||||||
|
} finally {
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||||
|
FlatUIUtils.setRenderingHints( g );
|
||||||
|
|
||||||
|
int secondWidth = (int) (SECOND_WIDTH * scaleFactor);
|
||||||
|
int seqGapWidth = (int) (NEW_SEQUENCE_GAP * scaleFactor);
|
||||||
|
|
||||||
|
g.translate( x, y );
|
||||||
|
|
||||||
|
// fill background
|
||||||
|
g.setColor( Color.white );
|
||||||
|
g.fillRect( x, y, width, height );
|
||||||
|
|
||||||
|
// paint horizontal lines
|
||||||
|
g.setColor( Color.LIGHT_GRAY );
|
||||||
|
for( int i = 1; i < 10; i++ ) {
|
||||||
|
int hy = (height * i) / 10;
|
||||||
|
g.drawLine( 0, hy, width, hy );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint vertical lines
|
||||||
|
g.setColor( Color.LIGHT_GRAY );
|
||||||
|
for( int i = secondWidth; i < width; i += secondWidth )
|
||||||
|
g.drawLine( i, 0, i, height );
|
||||||
|
|
||||||
|
// paint lines
|
||||||
|
for( Map.Entry<Color, List<Data>> e : color2dataMap.entrySet() ) {
|
||||||
|
Color chartColor = e.getKey();
|
||||||
|
List<Data> chartData = e.getValue();
|
||||||
|
|
||||||
|
long seqTime = 0;
|
||||||
|
int seqX = 0;
|
||||||
|
long ptime = 0;
|
||||||
|
int px = 0;
|
||||||
|
int py = 0;
|
||||||
|
int pcount = 0;
|
||||||
|
|
||||||
|
g.setColor( chartColor );
|
||||||
|
|
||||||
|
int size = chartData.size();
|
||||||
|
for( int i = 0; i < size; i++ ) {
|
||||||
|
Data data = chartData.get( i );
|
||||||
|
int dy = (int) ((height - 1) * data.value);
|
||||||
|
|
||||||
|
if( data.time > ptime + NEW_SEQUENCE_TIME_LAG ) {
|
||||||
|
if( i > 0 && pcount == 0 )
|
||||||
|
g.drawLine( px, py, px + (int) (4 * scaleFactor), py );
|
||||||
|
|
||||||
|
// start new sequence
|
||||||
|
seqTime = data.time;
|
||||||
|
seqX = (i > 0) ? px + seqGapWidth : 0;
|
||||||
|
px = seqX;
|
||||||
|
pcount = 0;
|
||||||
|
} else {
|
||||||
|
// line in sequence
|
||||||
|
int dx = (int) (seqX + (((data.time - seqTime) / 1000.) * secondWidth));
|
||||||
|
g.drawLine( px, py, dx, dy );
|
||||||
|
px = dx;
|
||||||
|
pcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
py = dy;
|
||||||
|
ptime = data.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int chartWidth() {
|
||||||
|
int width = 0;
|
||||||
|
for( List<Data> chartData : color2dataMap.values() )
|
||||||
|
width = Math.max( width, chartWidth( chartData, null ) );
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int chartWidth( List<Data> chartData, int[] lastSeqX ) {
|
||||||
|
long seqTime = 0;
|
||||||
|
int seqX = 0;
|
||||||
|
long ptime = 0;
|
||||||
|
int px = 0;
|
||||||
|
|
||||||
|
int size = chartData.size();
|
||||||
|
for( int i = 0; i < size; i++ ) {
|
||||||
|
Data data = chartData.get( i );
|
||||||
|
|
||||||
|
if( data.time > ptime + NEW_SEQUENCE_TIME_LAG ) {
|
||||||
|
// start new sequence
|
||||||
|
seqTime = data.time;
|
||||||
|
seqX = (i > 0) ? px + NEW_SEQUENCE_GAP : 0;
|
||||||
|
px = seqX;
|
||||||
|
} else {
|
||||||
|
// line in sequence
|
||||||
|
int dx = (int) (seqX + (((data.time - seqTime) / 1000.) * SECOND_WIDTH));
|
||||||
|
px = dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptime = data.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lastSeqX != null )
|
||||||
|
lastSeqX[0] = seqX;
|
||||||
|
|
||||||
|
return px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize() {
|
||||||
|
return new Dimension( chartWidth(), 200 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredScrollableViewportSize() {
|
||||||
|
return new Dimension( chartWidth(), 200 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScrollableUnitIncrement( Rectangle visibleRect, int orientation, int direction ) {
|
||||||
|
return SECOND_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScrollableBlockIncrement( Rectangle visibleRect, int orientation, int direction ) {
|
||||||
|
JViewport viewport = (JViewport) SwingUtilities.getAncestorOfClass( JViewport.class, this );
|
||||||
|
return (viewport != null) ? viewport.getWidth() : 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getScrollableTracksViewportWidth() {
|
||||||
|
JViewport viewport = (JViewport) SwingUtilities.getAncestorOfClass( JViewport.class, this );
|
||||||
|
return (viewport != null) ? viewport.getWidth() > chartWidth() : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getScrollableTracksViewportHeight() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class ColorIcon ----------------------------------------------------
|
||||||
|
|
||||||
|
private static class ColorIcon
|
||||||
|
implements Icon
|
||||||
|
{
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
ColorIcon( Color color ) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||||
|
int width = getIconWidth();
|
||||||
|
int height = getIconHeight();
|
||||||
|
|
||||||
|
g.setColor( color );
|
||||||
|
g.fillRect( x, y, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconWidth() {
|
||||||
|
return UIScale.scale( 24 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconHeight() {
|
||||||
|
return UIScale.scale( 12 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ new FormModel {
|
|||||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||||
"$columnConstraints": "[200,fill][200,fill][200,fill][200,fill]"
|
"$columnConstraints": "[200,fill][200,fill][200,fill][200,fill]"
|
||||||
"$rowConstraints": "[][][200,grow,fill][][200,grow,fill]"
|
"$rowConstraints": "[][][200,grow,fill][][200,grow,fill][300,grow,fill]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "this"
|
name: "this"
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
@@ -21,18 +21,21 @@ new FormModel {
|
|||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "listLabel"
|
name: "listLabel"
|
||||||
"text": "JList:"
|
"text": "JList:"
|
||||||
|
"horizontalTextPosition": 10
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 1,aligny top,growy 0"
|
"value": "cell 0 1,aligny top,growy 0"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label1"
|
name: "treeLabel"
|
||||||
"text": "JTree:"
|
"text": "JTree:"
|
||||||
|
"horizontalTextPosition": 10
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 1"
|
"value": "cell 1 1"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label5"
|
name: "tableLabel"
|
||||||
"text": "JTable:"
|
"text": "JTable:"
|
||||||
|
"horizontalTextPosition": 10
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 1"
|
"value": "cell 2 1"
|
||||||
} )
|
} )
|
||||||
@@ -65,20 +68,23 @@ new FormModel {
|
|||||||
"value": "cell 2 2 2 1,width 100,height 100"
|
"value": "cell 2 2 2 1,width 100,height 100"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label2"
|
name: "textAreaLabel"
|
||||||
"text": "JTextArea:"
|
"text": "JTextArea:"
|
||||||
|
"horizontalTextPosition": 10
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 3"
|
"value": "cell 0 3"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label3"
|
name: "textPaneLabel"
|
||||||
"text": "JTextPane:"
|
"text": "JTextPane:"
|
||||||
|
"horizontalTextPosition": 10
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 3"
|
"value": "cell 1 3"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label4"
|
name: "editorPaneLabel"
|
||||||
"text": "JEditorPane:"
|
"text": "JEditorPane:"
|
||||||
|
"horizontalTextPosition": 10
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 3"
|
"value": "cell 2 3"
|
||||||
} )
|
} )
|
||||||
@@ -106,6 +112,39 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 4"
|
"value": "cell 2 4"
|
||||||
} )
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$columnConstraints": "[200,right]"
|
||||||
|
"$rowConstraints": "[][]"
|
||||||
|
"$layoutConstraints": "ltr,insets 0,hidemode 3,aligny bottom"
|
||||||
|
} ) {
|
||||||
|
name: "panel1"
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "updateChartDelayedCheckBox"
|
||||||
|
"text": "Update chart delayed"
|
||||||
|
"mnemonic": 85
|
||||||
|
"selected": true
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "updateChartDelayedChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "clearChartButton"
|
||||||
|
"text": "Clear Chart"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "clearChart", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 3 4"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||||
|
name: "scrollPane1"
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatSmoothScrollingTest$LineChartPanel" ) {
|
||||||
|
name: "lineChartPanel"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5 4 1,width 100"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 0, 0 )
|
"location": new java.awt.Point( 0, 0 )
|
||||||
"size": new java.awt.Dimension( 790, 715 )
|
"size": new java.awt.Dimension( 790, 715 )
|
||||||
|
|||||||
Reference in New Issue
Block a user