mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
FlatAnimatorTest: added standard-easing and line chart
(line chart copied from `FlatSmoothScrollingTest.LineChartPanel` in branch `smooth-scrolling` commit 331ab06b0087d3a70f7c131368b88e5e7c92102f)
This commit is contained in:
@@ -17,9 +17,19 @@
|
|||||||
package com.formdev.flatlaf.testing;
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
import com.formdev.flatlaf.util.Animator;
|
import com.formdev.flatlaf.util.Animator;
|
||||||
import com.formdev.flatlaf.util.CubicBezierEasing;
|
import com.formdev.flatlaf.util.CubicBezierEasing;
|
||||||
|
import com.formdev.flatlaf.util.HSLColor;
|
||||||
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
import com.formdev.flatlaf.util.Animator.Interpolator;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,8 +38,13 @@ import net.miginfocom.swing.*;
|
|||||||
public class FlatAnimatorTest
|
public class FlatAnimatorTest
|
||||||
extends FlatTestPanel
|
extends FlatTestPanel
|
||||||
{
|
{
|
||||||
|
private static final Color CHART_LINEAR = Color.blue;
|
||||||
|
private static final Color CHART_EASE_IN_OUT = Color.magenta;
|
||||||
|
private static final Color CHART_STANDARD_EASING = Color.red;
|
||||||
|
|
||||||
private Animator linearAnimator;
|
private Animator linearAnimator;
|
||||||
private Animator easeInOutAnimator;
|
private Animator easeInOutAnimator;
|
||||||
|
private Animator standardEasingAnimator;
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
@@ -40,85 +55,483 @@ public class FlatAnimatorTest
|
|||||||
|
|
||||||
FlatAnimatorTest() {
|
FlatAnimatorTest() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
|
linearChartColor.setForeground( CHART_LINEAR );
|
||||||
|
easeInOutChartColor.setForeground( CHART_EASE_IN_OUT );
|
||||||
|
standardEasingChartColor.setForeground( CHART_STANDARD_EASING );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void start() {
|
private void start() {
|
||||||
startLinear();
|
linearAnimator = start( linearAnimator, null, linearScrollBar, CHART_LINEAR );
|
||||||
startEaseInOut();
|
easeInOutAnimator = start( easeInOutAnimator, CubicBezierEasing.EASE_IN_OUT, easeInOutScrollBar, CHART_EASE_IN_OUT );
|
||||||
|
standardEasingAnimator = start( standardEasingAnimator, CubicBezierEasing.STANDARD_EASING, standardEasingScrollBar, CHART_STANDARD_EASING );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startLinear() {
|
private Animator start( Animator animator, Interpolator interpolator, JScrollBar scrollBar, Color chartColor ) {
|
||||||
if( linearAnimator != null ) {
|
if( animator != null ) {
|
||||||
linearAnimator.stop();
|
animator.stop();
|
||||||
linearAnimator.start();
|
animator.start();
|
||||||
} else {
|
} else {
|
||||||
linearAnimator = new Animator( 1000, fraction -> {
|
animator = new Animator( 1000, fraction -> {
|
||||||
linearScrollBar.setValue( Math.round( fraction * linearScrollBar.getMaximum() ) );
|
scrollBar.setValue( Math.round( fraction * scrollBar.getMaximum() ) );
|
||||||
|
lineChartPanel.lineChart.addValue( fraction, chartColor );
|
||||||
} );
|
} );
|
||||||
linearAnimator.start();
|
animator.setInterpolator( interpolator );
|
||||||
}
|
animator.start();
|
||||||
}
|
|
||||||
|
|
||||||
private void startEaseInOut() {
|
|
||||||
if( easeInOutAnimator != null ) {
|
|
||||||
easeInOutAnimator.stop();
|
|
||||||
easeInOutAnimator.start();
|
|
||||||
} else {
|
|
||||||
easeInOutAnimator = new Animator( 1000, fraction -> {
|
|
||||||
easeInOutScrollBar.setValue( Math.round( fraction * easeInOutScrollBar.getMaximum() ) );
|
|
||||||
} );
|
|
||||||
easeInOutAnimator.setInterpolator( CubicBezierEasing.EASE_IN_OUT );
|
|
||||||
easeInOutAnimator.start();
|
|
||||||
}
|
}
|
||||||
|
return animator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
JLabel label1 = new JLabel();
|
linearLabel = new JLabel();
|
||||||
|
linearChartColor = new FlatAnimatorTest.JChartColor();
|
||||||
linearScrollBar = new JScrollBar();
|
linearScrollBar = new JScrollBar();
|
||||||
JLabel label2 = new JLabel();
|
easeInOutLabel = new JLabel();
|
||||||
|
easeInOutChartColor = new FlatAnimatorTest.JChartColor();
|
||||||
easeInOutScrollBar = new JScrollBar();
|
easeInOutScrollBar = new JScrollBar();
|
||||||
|
standardEasingLabel = new JLabel();
|
||||||
|
standardEasingChartColor = new FlatAnimatorTest.JChartColor();
|
||||||
|
standardEasingScrollBar = new JScrollBar();
|
||||||
startButton = new JButton();
|
startButton = new JButton();
|
||||||
|
lineChartPanel = new FlatAnimatorTest.LineChartPanel();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
setLayout(new MigLayout(
|
setLayout(new MigLayout(
|
||||||
"ltr,insets dialog,hidemode 3",
|
"ltr,insets dialog,hidemode 3",
|
||||||
// columns
|
// columns
|
||||||
"[fill]" +
|
"[fill]" +
|
||||||
|
"[fill]" +
|
||||||
"[grow,fill]",
|
"[grow,fill]",
|
||||||
// rows
|
// rows
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]"));
|
"[]" +
|
||||||
|
"[]para" +
|
||||||
|
"[400,grow,fill]"));
|
||||||
|
|
||||||
//---- label1 ----
|
//---- linearLabel ----
|
||||||
label1.setText("Linear:");
|
linearLabel.setText("Linear:");
|
||||||
add(label1, "cell 0 0");
|
add(linearLabel, "cell 0 0");
|
||||||
|
add(linearChartColor, "cell 1 0");
|
||||||
|
|
||||||
//---- linearScrollBar ----
|
//---- linearScrollBar ----
|
||||||
linearScrollBar.setOrientation(Adjustable.HORIZONTAL);
|
linearScrollBar.setOrientation(Adjustable.HORIZONTAL);
|
||||||
linearScrollBar.setBlockIncrement(1);
|
linearScrollBar.setBlockIncrement(1);
|
||||||
add(linearScrollBar, "cell 1 0");
|
add(linearScrollBar, "cell 2 0");
|
||||||
|
|
||||||
//---- label2 ----
|
//---- easeInOutLabel ----
|
||||||
label2.setText("Ease in out:");
|
easeInOutLabel.setText("Ease in out:");
|
||||||
add(label2, "cell 0 1");
|
add(easeInOutLabel, "cell 0 1");
|
||||||
|
add(easeInOutChartColor, "cell 1 1");
|
||||||
|
|
||||||
//---- easeInOutScrollBar ----
|
//---- easeInOutScrollBar ----
|
||||||
easeInOutScrollBar.setOrientation(Adjustable.HORIZONTAL);
|
easeInOutScrollBar.setOrientation(Adjustable.HORIZONTAL);
|
||||||
easeInOutScrollBar.setBlockIncrement(1);
|
easeInOutScrollBar.setBlockIncrement(1);
|
||||||
add(easeInOutScrollBar, "cell 1 1");
|
add(easeInOutScrollBar, "cell 2 1");
|
||||||
|
|
||||||
|
//---- standardEasingLabel ----
|
||||||
|
standardEasingLabel.setText("Standard easing:");
|
||||||
|
add(standardEasingLabel, "cell 0 2");
|
||||||
|
add(standardEasingChartColor, "cell 1 2");
|
||||||
|
|
||||||
|
//---- standardEasingScrollBar ----
|
||||||
|
standardEasingScrollBar.setOrientation(Adjustable.HORIZONTAL);
|
||||||
|
standardEasingScrollBar.setBlockIncrement(1);
|
||||||
|
add(standardEasingScrollBar, "cell 2 2");
|
||||||
|
|
||||||
//---- startButton ----
|
//---- startButton ----
|
||||||
startButton.setText("Start");
|
startButton.setText("Start");
|
||||||
startButton.addActionListener(e -> start());
|
startButton.addActionListener(e -> start());
|
||||||
add(startButton, "cell 0 2");
|
add(startButton, "cell 0 3");
|
||||||
|
add(lineChartPanel, "cell 0 4 3 1");
|
||||||
// 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 JLabel linearLabel;
|
||||||
|
private FlatAnimatorTest.JChartColor linearChartColor;
|
||||||
private JScrollBar linearScrollBar;
|
private JScrollBar linearScrollBar;
|
||||||
|
private JLabel easeInOutLabel;
|
||||||
|
private FlatAnimatorTest.JChartColor easeInOutChartColor;
|
||||||
private JScrollBar easeInOutScrollBar;
|
private JScrollBar easeInOutScrollBar;
|
||||||
|
private JLabel standardEasingLabel;
|
||||||
|
private FlatAnimatorTest.JChartColor standardEasingChartColor;
|
||||||
|
private JScrollBar standardEasingScrollBar;
|
||||||
private JButton startButton;
|
private JButton startButton;
|
||||||
|
private FlatAnimatorTest.LineChartPanel lineChartPanel;
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
|
//---- class LineChartPanel -----------------------------------------------
|
||||||
|
|
||||||
|
static class LineChartPanel
|
||||||
|
extends JPanel
|
||||||
|
{
|
||||||
|
LineChartPanel() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
updateChartDelayedChanged();
|
||||||
|
lineChart.setSecondWidth( 500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChartDelayedChanged() {
|
||||||
|
lineChart.setUpdateDelayed( updateChartDelayedCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearChart() {
|
||||||
|
lineChart.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JScrollPane lineChartScrollPane = new JScrollPane();
|
||||||
|
lineChart = new FlatAnimatorTest.LineChart();
|
||||||
|
JLabel lineChartInfoLabel = new JLabel();
|
||||||
|
updateChartDelayedCheckBox = new JCheckBox();
|
||||||
|
JButton clearChartButton = new JButton();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setLayout(new MigLayout(
|
||||||
|
"ltr,insets 0,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[fill]" +
|
||||||
|
"[grow,fill]",
|
||||||
|
// rows
|
||||||
|
"[400,grow,fill]" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//======== lineChartScrollPane ========
|
||||||
|
{
|
||||||
|
lineChartScrollPane.putClientProperty("JScrollPane.smoothScrolling", false);
|
||||||
|
lineChartScrollPane.setViewportView(lineChart);
|
||||||
|
}
|
||||||
|
add(lineChartScrollPane, "cell 0 0 2 1");
|
||||||
|
|
||||||
|
//---- lineChartInfoLabel ----
|
||||||
|
lineChartInfoLabel.setText("X: time (500ms per line) / Y: value (10% per line)");
|
||||||
|
add(lineChartInfoLabel, "cell 0 1 2 1");
|
||||||
|
|
||||||
|
//---- updateChartDelayedCheckBox ----
|
||||||
|
updateChartDelayedCheckBox.setText("Update chart delayed");
|
||||||
|
updateChartDelayedCheckBox.setMnemonic('U');
|
||||||
|
updateChartDelayedCheckBox.addActionListener(e -> updateChartDelayedChanged());
|
||||||
|
add(updateChartDelayedCheckBox, "cell 0 1 2 1,alignx right,growx 0");
|
||||||
|
|
||||||
|
//---- clearChartButton ----
|
||||||
|
clearChartButton.setText("Clear Chart");
|
||||||
|
clearChartButton.setMnemonic('C');
|
||||||
|
clearChartButton.addActionListener(e -> clearChart());
|
||||||
|
add(clearChartButton, "cell 0 1 2 1,alignx right,growx 0");
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
FlatAnimatorTest.LineChart lineChart;
|
||||||
|
private JCheckBox updateChartDelayedCheckBox;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class LineChart ----------------------------------------------------
|
||||||
|
|
||||||
|
static class LineChart
|
||||||
|
extends JComponent
|
||||||
|
implements Scrollable
|
||||||
|
{
|
||||||
|
private static final int NEW_SEQUENCE_TIME_LAG = 500;
|
||||||
|
private static final int NEW_SEQUENCE_GAP = 50;
|
||||||
|
|
||||||
|
private int secondWidth = 1000;
|
||||||
|
|
||||||
|
private static class Data {
|
||||||
|
final double value;
|
||||||
|
final boolean dot;
|
||||||
|
final long time; // in milliseconds
|
||||||
|
|
||||||
|
Data( double value, boolean dot, long time ) {
|
||||||
|
this.value = value;
|
||||||
|
this.dot = dot;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
// for debugging
|
||||||
|
return String.valueOf( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<Color, List<Data>> color2dataMap = new HashMap<>();
|
||||||
|
private final Timer repaintTime;
|
||||||
|
private Color lastUsedChartColor;
|
||||||
|
private boolean updateDelayed;
|
||||||
|
|
||||||
|
LineChart() {
|
||||||
|
repaintTime = new Timer( 20, e -> repaintAndRevalidate() );
|
||||||
|
repaintTime.setRepeats( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addValue( double value, Color chartColor ) {
|
||||||
|
addValue( value, false, chartColor );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addValue( double value, boolean dot, Color chartColor ) {
|
||||||
|
List<Data> chartData = color2dataMap.computeIfAbsent( chartColor, k -> new ArrayList<>() );
|
||||||
|
chartData.add( new Data( value, dot, System.nanoTime() / 1000000) );
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSecondWidth( int secondWidth ) {
|
||||||
|
this.secondWidth = secondWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repaintAndRevalidate() {
|
||||||
|
repaint();
|
||||||
|
revalidate();
|
||||||
|
|
||||||
|
// scroll horizontally
|
||||||
|
if( lastUsedChartColor != null ) {
|
||||||
|
// compute chart width of last used color and start of last sequence
|
||||||
|
int[] lastSeqX = new int[1];
|
||||||
|
int cw = chartWidth( color2dataMap.get( lastUsedChartColor ), lastSeqX );
|
||||||
|
|
||||||
|
// scroll to end of last sequence (of last used color)
|
||||||
|
int lastSeqWidth = cw - lastSeqX[0];
|
||||||
|
int width = Math.min( lastSeqWidth, getParent().getWidth() );
|
||||||
|
int x = cw - width;
|
||||||
|
scrollRectToVisible( new Rectangle( x, 0, width, 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) (this.secondWidth * scaleFactor);
|
||||||
|
int seqGapWidth = (int) (NEW_SEQUENCE_GAP * scaleFactor);
|
||||||
|
|
||||||
|
Color lineColor = FlatUIUtils.getUIColor( "Component.borderColor", Color.lightGray );
|
||||||
|
Color lineColor2 = FlatLaf.isLafDark()
|
||||||
|
? new HSLColor( lineColor ).adjustTone( 30 )
|
||||||
|
: new HSLColor( lineColor ).adjustShade( 30 );
|
||||||
|
|
||||||
|
g.translate( x, y );
|
||||||
|
|
||||||
|
// fill background
|
||||||
|
g.setColor( UIManager.getColor( "Table.background" ) );
|
||||||
|
g.fillRect( x, y, width, height );
|
||||||
|
|
||||||
|
// paint horizontal lines
|
||||||
|
for( int i = 1; i < 10; i++ ) {
|
||||||
|
int hy = (height * i) / 10;
|
||||||
|
g.setColor( (i != 5) ? lineColor : lineColor2 );
|
||||||
|
g.drawLine( 0, hy, width, hy );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint vertical lines
|
||||||
|
int twoHundredMillisWidth = secondWidth / 5;
|
||||||
|
for( int i = twoHundredMillisWidth; i < width; i += twoHundredMillisWidth ) {
|
||||||
|
g.setColor( (i % secondWidth != 0) ? lineColor : lineColor2 );
|
||||||
|
g.drawLine( i, 0, i, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint lines
|
||||||
|
for( Map.Entry<Color, List<Data>> e : color2dataMap.entrySet() ) {
|
||||||
|
List<Data> chartData = e.getValue();
|
||||||
|
Color chartColor = e.getKey();
|
||||||
|
if( FlatLaf.isLafDark() )
|
||||||
|
chartColor = new HSLColor( chartColor ).adjustTone( 50 );
|
||||||
|
Color temporaryValueColor = new Color( (chartColor.getRGB() & 0xffffff) | 0x40000000, true );
|
||||||
|
|
||||||
|
long seqTime = 0;
|
||||||
|
int seqX = 0;
|
||||||
|
long ptime = 0;
|
||||||
|
int px = 0;
|
||||||
|
int py = 0;
|
||||||
|
int pcount = 0;
|
||||||
|
|
||||||
|
g.setColor( chartColor );
|
||||||
|
|
||||||
|
boolean first = true;
|
||||||
|
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.dot ) {
|
||||||
|
int dotx = px;
|
||||||
|
if( i > 0 && data.time > ptime + NEW_SEQUENCE_TIME_LAG )
|
||||||
|
dotx += seqGapWidth;
|
||||||
|
int o = UIScale.scale( 1 );
|
||||||
|
int s = UIScale.scale( 3 );
|
||||||
|
g.fillRect( dotx - o, dy - o, s, s );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.time > ptime + NEW_SEQUENCE_TIME_LAG ) {
|
||||||
|
if( !first && pcount == 0 )
|
||||||
|
g.drawLine( px, py, px + (int) (4 * scaleFactor), py );
|
||||||
|
|
||||||
|
// start new sequence
|
||||||
|
seqTime = data.time;
|
||||||
|
seqX = !first ? px + seqGapWidth : 0;
|
||||||
|
px = seqX;
|
||||||
|
pcount = 0;
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
boolean isTemporaryValue = isTemporaryValue( chartData, i ) || isTemporaryValue( chartData, i - 1 );
|
||||||
|
if( isTemporaryValue )
|
||||||
|
g.setColor( temporaryValueColor );
|
||||||
|
|
||||||
|
// line in sequence
|
||||||
|
int dx = (int) (seqX + (((data.time - seqTime) / 1000.) * secondWidth));
|
||||||
|
g.drawLine( px, py, dx, dy );
|
||||||
|
px = dx;
|
||||||
|
pcount++;
|
||||||
|
|
||||||
|
if( isTemporaryValue )
|
||||||
|
g.setColor( chartColor );
|
||||||
|
}
|
||||||
|
|
||||||
|
py = dy;
|
||||||
|
ptime = data.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One or two values between two equal values are considered "temporary",
|
||||||
|
* which means that they are the target value for the following scroll animation.
|
||||||
|
*/
|
||||||
|
private boolean isTemporaryValue( List<Data> chartData, int i ) {
|
||||||
|
if( i == 0 || i == chartData.size() - 1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Data dataBefore = chartData.get( i - 1 );
|
||||||
|
Data dataAfter = chartData.get( i + 1 );
|
||||||
|
|
||||||
|
if( dataBefore.dot || dataAfter.dot )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double valueBefore = dataBefore.value;
|
||||||
|
double valueAfter = dataAfter.value;
|
||||||
|
|
||||||
|
return valueBefore == valueAfter ||
|
||||||
|
(i < chartData.size() - 2 && valueBefore == chartData.get( i + 2 ).value) ||
|
||||||
|
(i > 1 && chartData.get( i - 2 ).value == valueAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.) * secondWidth));
|
||||||
|
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 secondWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 JChartColor --------------------------------------------------
|
||||||
|
|
||||||
|
static class JChartColor
|
||||||
|
extends JComponent
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize() {
|
||||||
|
return new Dimension( UIScale.scale( 24 ), UIScale.scale( 12 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent( Graphics g ) {
|
||||||
|
g.setColor( getForeground() );
|
||||||
|
g.fillRect( 0, 0, UIScale.scale( 24 ), UIScale.scale( 12 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14.0.2" encoding: "UTF-8"
|
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -8,16 +8,27 @@ 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": "[fill][grow,fill]"
|
"$columnConstraints": "[fill][fill][grow,fill]"
|
||||||
"$rowConstraints": "[][][]"
|
"$rowConstraints": "[][][][]para[400,grow,fill]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "this"
|
name: "this"
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label1"
|
name: "linearLabel"
|
||||||
"text": "Linear:"
|
"text": "Linear:"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 0"
|
"value": "cell 0 0"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
|
||||||
|
name: "linearChartColor"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||||
name: "linearScrollBar"
|
name: "linearScrollBar"
|
||||||
"orientation": 0
|
"orientation": 0
|
||||||
@@ -26,14 +37,25 @@ new FormModel {
|
|||||||
"JavaCodeGenerator.variableLocal": false
|
"JavaCodeGenerator.variableLocal": false
|
||||||
}
|
}
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 0"
|
"value": "cell 2 0"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "label2"
|
name: "easeInOutLabel"
|
||||||
"text": "Ease in out:"
|
"text": "Ease in out:"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 1"
|
"value": "cell 0 1"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
|
||||||
|
name: "easeInOutChartColor"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 1"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||||
name: "easeInOutScrollBar"
|
name: "easeInOutScrollBar"
|
||||||
"orientation": 0
|
"orientation": 0
|
||||||
@@ -42,7 +64,34 @@ new FormModel {
|
|||||||
"JavaCodeGenerator.variableLocal": false
|
"JavaCodeGenerator.variableLocal": false
|
||||||
}
|
}
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 1"
|
"value": "cell 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "standardEasingLabel"
|
||||||
|
"text": "Standard easing:"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
|
||||||
|
name: "standardEasingChartColor"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||||
|
name: "standardEasingScrollBar"
|
||||||
|
"orientation": 0
|
||||||
|
"blockIncrement": 1
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 2"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
name: "startButton"
|
name: "startButton"
|
||||||
@@ -52,11 +101,70 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "start", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "start", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 2"
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$LineChartPanel" ) {
|
||||||
|
name: "lineChartPanel"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4 3 1"
|
||||||
} )
|
} )
|
||||||
}, 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( 415, 350 )
|
"size": new java.awt.Dimension( 625, 625 )
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$columnConstraints": "[fill][grow,fill]"
|
||||||
|
"$rowConstraints": "[400,grow,fill][]"
|
||||||
|
"$layoutConstraints": "ltr,insets 0,hidemode 3"
|
||||||
|
} ) {
|
||||||
|
name: "lineChartPanelNested"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.className": "LineChartPanel"
|
||||||
|
}
|
||||||
|
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||||
|
name: "lineChartScrollPane"
|
||||||
|
"$client.JScrollPane.smoothScrolling": false
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$LineChart" ) {
|
||||||
|
name: "lineChart"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.variableModifiers": 0
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "lineChartInfoLabel"
|
||||||
|
"text": "X: time (500ms per line) / Y: value (10% per line)"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "updateChartDelayedCheckBox"
|
||||||
|
"text": "Update chart delayed"
|
||||||
|
"mnemonic": 85
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "updateChartDelayedChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1 2 1,alignx right,growx 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "clearChartButton"
|
||||||
|
"text": "Clear Chart"
|
||||||
|
"mnemonic": 67
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "clearChart", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1 2 1,alignx right,growx 0"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 650 )
|
||||||
|
"size": new java.awt.Dimension( 603, 325 )
|
||||||
} )
|
} )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user