mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
FlatSmoothScrollingTest:
- better list/tree/etc items for easier recognizing jittery scrolling - sliders to modify animation duration and resolution - slider to invoke `scrollRectToVisible()` - option to show row header for table - use viewport.viewPosition for chart (instead of scrollbar.value) - highlight methods in stack of tooltip (e.g. JViewport.setViewPosition())
This commit is contained in:
@@ -180,7 +180,7 @@ public class FlatAnimatorTest
|
|||||||
value = startValue + Math.round( (targetValue - startValue) * fraction );
|
value = startValue + Math.round( (targetValue - startValue) * fraction );
|
||||||
valueLabel.setText( String.valueOf( value ) );
|
valueLabel.setText( String.valueOf( value ) );
|
||||||
|
|
||||||
lineChartPanel.addValue( value / (double) MAX_VALUE, value, false, Color.red, null );
|
lineChartPanel.addValue( Color.red, value / (double) MAX_VALUE, value, null );
|
||||||
}, () -> {
|
}, () -> {
|
||||||
targetValue = -1;
|
targetValue = -1;
|
||||||
} );
|
} );
|
||||||
@@ -198,7 +198,7 @@ public class FlatAnimatorTest
|
|||||||
// for unprecise wheels the rotation value is usually -1 or +1
|
// for unprecise wheels the rotation value is usually -1 or +1
|
||||||
// for precise wheels the rotation value is in range ca. -10 to +10,
|
// for precise wheels the rotation value is in range ca. -10 to +10,
|
||||||
// depending how fast the wheel is rotated
|
// depending how fast the wheel is rotated
|
||||||
lineChartPanel.addValue( 0.5 + (preciseWheelRotation / 20.), (int) (preciseWheelRotation * 1000), true, Color.red, null );
|
lineChartPanel.addDot( Color.red, 0.5 + (preciseWheelRotation / 20.), (int) (preciseWheelRotation * 1000), null, null );
|
||||||
|
|
||||||
// increase/decrease target value if animation is in progress
|
// increase/decrease target value if animation is in progress
|
||||||
int newValue = (int) ((targetValue < 0 ? value : targetValue) + (STEP * preciseWheelRotation));
|
int newValue = (int) ((targetValue < 0 ? value : targetValue) + (STEP * preciseWheelRotation));
|
||||||
@@ -215,7 +215,7 @@ public class FlatAnimatorTest
|
|||||||
value = newValue;
|
value = newValue;
|
||||||
valueLabel.setText( String.valueOf( value ) );
|
valueLabel.setText( String.valueOf( value ) );
|
||||||
|
|
||||||
lineChartPanel.addValue( value / (double) MAX_VALUE, value, false, Color.red, null );
|
lineChartPanel.addValue( Color.red, value / (double) MAX_VALUE, value, null );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.awt.Dimension;
|
|||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -30,6 +31,8 @@ import javax.swing.event.ChangeEvent;
|
|||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
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.Animator;
|
||||||
import com.formdev.flatlaf.util.ColorFunctions;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
@@ -51,8 +54,7 @@ public class FlatSmoothScrollingTest
|
|||||||
FlatSmoothScrollingTest() {
|
FlatSmoothScrollingTest() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
ToolTipManager.sharedInstance().setInitialDelay( 0 );
|
initializeDurationAndResolution();
|
||||||
ToolTipManager.sharedInstance().setDismissDelay( Integer.MAX_VALUE );
|
|
||||||
|
|
||||||
// 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(
|
||||||
@@ -93,13 +95,15 @@ public class FlatSmoothScrollingTest
|
|||||||
customScrollPane.getHorizontalScrollBar().getModel().addChangeListener( new ScrollBarChangeHandler( customScrollPane, false, "custom horz", Color.pink.darker() ) );
|
customScrollPane.getHorizontalScrollBar().getModel().addChangeListener( new ScrollBarChangeHandler( customScrollPane, false, "custom horz", Color.pink.darker() ) );
|
||||||
|
|
||||||
ArrayList<String> items = new ArrayList<>();
|
ArrayList<String> items = new ArrayList<>();
|
||||||
for( char ch = '0'; ch < 'z'; ch++ ) {
|
for( int i = 0; i < 10; i++ ) {
|
||||||
if( (ch > '9' && ch < 'A') || (ch > 'Z' && ch < 'a') )
|
for( int j = 0; j < 10; j++ ) {
|
||||||
continue;
|
char[] chars = new char[i*10 + j + 1];
|
||||||
|
Arrays.fill( chars, ' ' );
|
||||||
char[] chars = new char[ch - '0' + 1];
|
chars[chars.length - 1] = (char) ('0' + j);
|
||||||
Arrays.fill( chars, ch );
|
if( i >= 5 )
|
||||||
items.add( new String( chars ) );
|
chars[50 - 1 - ((i-5)*10) - j] = (char) ('0' + j);
|
||||||
|
items.add( new String( chars ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// list model
|
// list model
|
||||||
@@ -137,12 +141,10 @@ public class FlatSmoothScrollingTest
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getColumnCount() {
|
public int getColumnCount() {
|
||||||
return 4;
|
return (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF) ? 100 : 2;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Object getValueAt( int rowIndex, int columnIndex ) {
|
public Object getValueAt( int rowIndex, int columnIndex ) {
|
||||||
if( columnIndex > 0 )
|
|
||||||
rowIndex = (items.size() + rowIndex - ((items.size() / 4) * columnIndex)) % items.size();
|
|
||||||
return items.get( rowIndex );
|
return items.get( rowIndex );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
@@ -155,17 +157,49 @@ public class FlatSmoothScrollingTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// text components
|
// text components
|
||||||
String longText = items.stream().collect( Collectors.joining( " " ) ) + ' '
|
String longText = "";
|
||||||
+ items.stream().limit( 20 ).collect( Collectors.joining( " " ) );
|
for( int i = 0; i < 100; i++ )
|
||||||
|
longText += String.format( "%-5d ", i );
|
||||||
|
longText += "100";
|
||||||
String text = items.stream().collect( Collectors.joining( "\n" ) ) + '\n';
|
String text = items.stream().collect( Collectors.joining( "\n" ) ) + '\n';
|
||||||
textArea.setText( longText + '\n' + text );
|
textArea.setText( longText + '\n' + text );
|
||||||
textPane.setText( text );
|
textPane.setText( text );
|
||||||
editorPane.setText( text );
|
editorPane.setText( text );
|
||||||
|
|
||||||
|
// move selection to beginning in text components
|
||||||
textArea.select( 0, 0 );
|
textArea.select( 0, 0 );
|
||||||
textPane.select( 0, 0 );
|
textPane.select( 0, 0 );
|
||||||
editorPane.select( 0, 0 );
|
editorPane.select( 0, 0 );
|
||||||
|
|
||||||
|
// custom scrollable
|
||||||
|
StringBuilder buf = new StringBuilder()
|
||||||
|
.append( "<html>" )
|
||||||
|
.append( customButton.getText() );
|
||||||
|
for( String item : items ) {
|
||||||
|
buf.append( "<br>" );
|
||||||
|
for( int i = 0; i < item.length(); i++ ) {
|
||||||
|
char ch = item.charAt( i );
|
||||||
|
if( ch == ' ' )
|
||||||
|
buf.append( " " );
|
||||||
|
else
|
||||||
|
buf.append( ch );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append( "</html>" );
|
||||||
|
customButton.setText( buf.toString() );
|
||||||
|
|
||||||
|
// line chart
|
||||||
|
lineChartPanel.addMethodHighlight( JViewport.class.getName() + ".setViewPosition", "#0000bb" );
|
||||||
|
lineChartPanel.addMethodHighlight( JViewport.class.getName() + ".scrollRectToVisible", "#00bbbb" );
|
||||||
|
lineChartPanel.addMethodHighlight( JScrollBar.class.getName() + ".setValue", "#00aa00" );
|
||||||
|
lineChartPanel.addMethodHighlight( Animator.class.getName() + ".timingEvent", "#bb0000" );
|
||||||
|
lineChartPanel.addMethodHighlight( JComponent.class.getName() + ".processKeyBinding", "#bb0000" );
|
||||||
|
lineChartPanel.addMethodHighlight( Component.class.getName() + ".processMouseEvent", "#bb0000" );
|
||||||
|
lineChartPanel.addMethodHighlight( Component.class.getName() + ".processMouseWheelEvent", "#bb0000" );
|
||||||
|
lineChartPanel.addMethodHighlight( Component.class.getName() + ".processMouseMotionEvent", "#bb0000" );
|
||||||
|
lineChartPanel.addMethodHighlight( "actionPerformed", "#bbbb00" );
|
||||||
|
|
||||||
|
// request focus for list
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
list.requestFocusInWindow();
|
list.requestFocusInWindow();
|
||||||
@@ -177,6 +211,82 @@ public class FlatSmoothScrollingTest
|
|||||||
UIManager.put( "ScrollPane.smoothScrolling", smoothScrollingCheckBox.isSelected() );
|
UIManager.put( "ScrollPane.smoothScrolling", smoothScrollingCheckBox.isSelected() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeDurationAndResolution() {
|
||||||
|
int duration = FlatUIUtils.getUIInt( "ScrollPane.smoothScrolling.duration", 200 );
|
||||||
|
int resolution = FlatUIUtils.getUIInt( "ScrollPane.smoothScrolling.resolution", 10 );
|
||||||
|
|
||||||
|
durationSlider.setValue( duration );
|
||||||
|
resolutionSlider.setValue( resolution );
|
||||||
|
|
||||||
|
updateDurationAndResolutionLabels( duration, resolution );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void durationOrResolutionChanged() {
|
||||||
|
int duration = durationSlider.getValue();
|
||||||
|
int resolution = resolutionSlider.getValue();
|
||||||
|
|
||||||
|
updateDurationAndResolutionLabels( duration, resolution );
|
||||||
|
|
||||||
|
UIManager.put( "ScrollPane.smoothScrolling.duration", duration );
|
||||||
|
UIManager.put( "ScrollPane.smoothScrolling.resolution", resolution );
|
||||||
|
|
||||||
|
// update UI of scroll bars to force re-creation of animator
|
||||||
|
JScrollPane[] scrollPanes = { listScrollPane, treeScrollPane, tableScrollPane,
|
||||||
|
textAreaScrollPane, textPaneScrollPane, editorPaneScrollPane, customScrollPane };
|
||||||
|
for( JScrollPane scrollPane : scrollPanes ) {
|
||||||
|
scrollPane.getVerticalScrollBar().updateUI();
|
||||||
|
scrollPane.getHorizontalScrollBar().updateUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDurationAndResolutionLabels( int duration, int resolution ) {
|
||||||
|
durationValueLabel.setText( duration + " ms" );
|
||||||
|
resolutionValueLabel.setText( resolution + " ms" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scrollToChanged() {
|
||||||
|
if( scrollToSlider.getValueIsAdjusting() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int value = scrollToSlider.getValue();
|
||||||
|
JComponent[] comps = { list, tree, table, textArea, textPane, editorPane, customButton };
|
||||||
|
for( JComponent c : comps ) {
|
||||||
|
int x = (c.getWidth() * value) / 100;
|
||||||
|
int y = (c.getHeight() * value) / 100;
|
||||||
|
c.scrollRectToVisible( new Rectangle( x, y, 1, 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rowHeaderChanged() {
|
||||||
|
JTable rowHeader = null;
|
||||||
|
if( rowHeaderCheckBox.isSelected() ) {
|
||||||
|
rowHeader = new JTable();
|
||||||
|
rowHeader.setPreferredScrollableViewportSize( new Dimension( UIScale.scale( 50 ), 100 ) );
|
||||||
|
rowHeader.setModel( new AbstractTableModel() {
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return table.getRowCount();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Object getValueAt( int rowIndex, int columnIndex ) {
|
||||||
|
char[] chars = new char[10];
|
||||||
|
Arrays.fill( chars, ' ' );
|
||||||
|
int i = rowIndex % 10;
|
||||||
|
if( (rowIndex / 10) % 2 == 0 )
|
||||||
|
chars[i] = (char) ('0' + i);
|
||||||
|
else
|
||||||
|
chars[9 - i] = (char) ('A' + i);
|
||||||
|
return new String( chars );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
tableScrollPane.setRowHeaderView( rowHeader );
|
||||||
|
}
|
||||||
|
|
||||||
private void showTableGridChanged() {
|
private void showTableGridChanged() {
|
||||||
boolean showGrid = showTableGridCheckBox.isSelected();
|
boolean showGrid = showTableGridCheckBox.isSelected();
|
||||||
table.setShowHorizontalLines( showGrid );
|
table.setShowHorizontalLines( showGrid );
|
||||||
@@ -187,6 +297,7 @@ public class FlatSmoothScrollingTest
|
|||||||
|
|
||||||
private void autoResizeModeChanged() {
|
private void autoResizeModeChanged() {
|
||||||
table.setAutoResizeMode( autoResizeModeCheckBox.isSelected() ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_OFF );
|
table.setAutoResizeMode( autoResizeModeCheckBox.isSelected() ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_OFF );
|
||||||
|
((AbstractTableModel)table.getModel()).fireTableStructureChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -201,12 +312,20 @@ public class FlatSmoothScrollingTest
|
|||||||
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();
|
||||||
|
JPanel hSpacer1 = new JPanel(null);
|
||||||
|
JLabel durationLabel = new JLabel();
|
||||||
|
durationSlider = new JSlider();
|
||||||
|
durationValueLabel = new JLabel();
|
||||||
|
JLabel resolutionLabel = new JLabel();
|
||||||
|
resolutionSlider = new JSlider();
|
||||||
|
resolutionValueLabel = new JLabel();
|
||||||
splitPane1 = new JSplitPane();
|
splitPane1 = new JSplitPane();
|
||||||
splitPane2 = new JSplitPane();
|
splitPane2 = new JSplitPane();
|
||||||
panel1 = new JPanel();
|
panel1 = new JPanel();
|
||||||
listLabel = new JLabel();
|
listLabel = new JLabel();
|
||||||
treeLabel = new JLabel();
|
treeLabel = new JLabel();
|
||||||
tableLabel = new JLabel();
|
tableLabel = new JLabel();
|
||||||
|
rowHeaderCheckBox = new JCheckBox();
|
||||||
showTableGridCheckBox = new JCheckBox();
|
showTableGridCheckBox = new JCheckBox();
|
||||||
autoResizeModeCheckBox = new JCheckBox();
|
autoResizeModeCheckBox = new JCheckBox();
|
||||||
listScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
listScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
@@ -215,6 +334,7 @@ public class FlatSmoothScrollingTest
|
|||||||
tree = new JTree();
|
tree = new JTree();
|
||||||
tableScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
tableScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
table = new JTable();
|
table = new JTable();
|
||||||
|
scrollToSlider = new JSlider();
|
||||||
panel2 = new JPanel();
|
panel2 = new JPanel();
|
||||||
textAreaLabel = new JLabel();
|
textAreaLabel = new JLabel();
|
||||||
textPaneLabel = new JLabel();
|
textPaneLabel = new JLabel();
|
||||||
@@ -227,7 +347,7 @@ public class FlatSmoothScrollingTest
|
|||||||
editorPaneScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
editorPaneScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
editorPane = new JEditorPane();
|
editorPane = new JEditorPane();
|
||||||
customScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
customScrollPane = new FlatSmoothScrollingTest.DebugScrollPane();
|
||||||
button1 = new JButton();
|
customButton = new JButton();
|
||||||
lineChartPanel = new LineChartPanel();
|
lineChartPanel = new LineChartPanel();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
@@ -245,6 +365,41 @@ public class FlatSmoothScrollingTest
|
|||||||
smoothScrollingCheckBox.setMnemonic('S');
|
smoothScrollingCheckBox.setMnemonic('S');
|
||||||
smoothScrollingCheckBox.addActionListener(e -> smoothScrollingChanged());
|
smoothScrollingCheckBox.addActionListener(e -> smoothScrollingChanged());
|
||||||
add(smoothScrollingCheckBox, "cell 0 0,alignx left,growx 0");
|
add(smoothScrollingCheckBox, "cell 0 0,alignx left,growx 0");
|
||||||
|
add(hSpacer1, "cell 0 0,growx");
|
||||||
|
|
||||||
|
//---- durationLabel ----
|
||||||
|
durationLabel.setText("Duration:");
|
||||||
|
add(durationLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//---- durationSlider ----
|
||||||
|
durationSlider.setMaximum(5000);
|
||||||
|
durationSlider.setValue(200);
|
||||||
|
durationSlider.setSnapToTicks(true);
|
||||||
|
durationSlider.setMinimum(100);
|
||||||
|
durationSlider.setMinorTickSpacing(50);
|
||||||
|
durationSlider.addChangeListener(e -> durationOrResolutionChanged());
|
||||||
|
add(durationSlider, "cell 0 0");
|
||||||
|
|
||||||
|
//---- durationValueLabel ----
|
||||||
|
durationValueLabel.setText("0000 ms");
|
||||||
|
add(durationValueLabel, "cell 0 0,width 50");
|
||||||
|
|
||||||
|
//---- resolutionLabel ----
|
||||||
|
resolutionLabel.setText("Resolution:");
|
||||||
|
add(resolutionLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//---- resolutionSlider ----
|
||||||
|
resolutionSlider.setMaximum(1000);
|
||||||
|
resolutionSlider.setMinimum(10);
|
||||||
|
resolutionSlider.setValue(10);
|
||||||
|
resolutionSlider.setMinorTickSpacing(10);
|
||||||
|
resolutionSlider.setSnapToTicks(true);
|
||||||
|
resolutionSlider.addChangeListener(e -> durationOrResolutionChanged());
|
||||||
|
add(resolutionSlider, "cell 0 0");
|
||||||
|
|
||||||
|
//---- resolutionValueLabel ----
|
||||||
|
resolutionValueLabel.setText("0000 ms");
|
||||||
|
add(resolutionValueLabel, "cell 0 0,width 50");
|
||||||
|
|
||||||
//======== splitPane1 ========
|
//======== splitPane1 ========
|
||||||
{
|
{
|
||||||
@@ -264,7 +419,8 @@ public class FlatSmoothScrollingTest
|
|||||||
"[200,grow,fill]" +
|
"[200,grow,fill]" +
|
||||||
"[200,grow,fill]" +
|
"[200,grow,fill]" +
|
||||||
"[200,grow,fill]" +
|
"[200,grow,fill]" +
|
||||||
"[200,grow,fill]",
|
"[200,grow,fill]" +
|
||||||
|
"[fill]",
|
||||||
// rows
|
// rows
|
||||||
"[]0" +
|
"[]0" +
|
||||||
"[200,grow,fill]"));
|
"[200,grow,fill]"));
|
||||||
@@ -284,6 +440,11 @@ public class FlatSmoothScrollingTest
|
|||||||
tableLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
tableLabel.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||||
panel1.add(tableLabel, "cell 2 0 2 1");
|
panel1.add(tableLabel, "cell 2 0 2 1");
|
||||||
|
|
||||||
|
//---- rowHeaderCheckBox ----
|
||||||
|
rowHeaderCheckBox.setText("Row header");
|
||||||
|
rowHeaderCheckBox.addActionListener(e -> rowHeaderChanged());
|
||||||
|
panel1.add(rowHeaderCheckBox, "cell 2 0 2 1,alignx right,growx 0");
|
||||||
|
|
||||||
//---- showTableGridCheckBox ----
|
//---- showTableGridCheckBox ----
|
||||||
showTableGridCheckBox.setText("Show table grid");
|
showTableGridCheckBox.setText("Show table grid");
|
||||||
showTableGridCheckBox.setMnemonic('G');
|
showTableGridCheckBox.setMnemonic('G');
|
||||||
@@ -313,6 +474,13 @@ public class FlatSmoothScrollingTest
|
|||||||
tableScrollPane.setViewportView(table);
|
tableScrollPane.setViewportView(table);
|
||||||
}
|
}
|
||||||
panel1.add(tableScrollPane, "cell 2 1 2 1,width 100,height 100");
|
panel1.add(tableScrollPane, "cell 2 1 2 1,width 100,height 100");
|
||||||
|
|
||||||
|
//---- scrollToSlider ----
|
||||||
|
scrollToSlider.setOrientation(SwingConstants.VERTICAL);
|
||||||
|
scrollToSlider.setValue(0);
|
||||||
|
scrollToSlider.setInverted(true);
|
||||||
|
scrollToSlider.addChangeListener(e -> scrollToChanged());
|
||||||
|
panel1.add(scrollToSlider, "cell 4 1");
|
||||||
}
|
}
|
||||||
splitPane2.setTopComponent(panel1);
|
splitPane2.setTopComponent(panel1);
|
||||||
|
|
||||||
@@ -369,12 +537,11 @@ public class FlatSmoothScrollingTest
|
|||||||
//======== customScrollPane ========
|
//======== customScrollPane ========
|
||||||
{
|
{
|
||||||
|
|
||||||
//---- button1 ----
|
//---- customButton ----
|
||||||
button1.setText("I'm a large button, but do not implement Scrollable interface");
|
customButton.setText("I'm a large button, but do not implement Scrollable interface");
|
||||||
button1.setPreferredSize(new Dimension(800, 800));
|
customButton.setHorizontalAlignment(SwingConstants.LEADING);
|
||||||
button1.setHorizontalAlignment(SwingConstants.LEADING);
|
customButton.setVerticalAlignment(SwingConstants.TOP);
|
||||||
button1.setVerticalAlignment(SwingConstants.TOP);
|
customScrollPane.setViewportView(customButton);
|
||||||
customScrollPane.setViewportView(button1);
|
|
||||||
}
|
}
|
||||||
panel2.add(customScrollPane, "cell 3 1");
|
panel2.add(customScrollPane, "cell 3 1");
|
||||||
}
|
}
|
||||||
@@ -394,12 +561,17 @@ public class FlatSmoothScrollingTest
|
|||||||
|
|
||||||
// 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 JSlider durationSlider;
|
||||||
|
private JLabel durationValueLabel;
|
||||||
|
private JSlider resolutionSlider;
|
||||||
|
private JLabel resolutionValueLabel;
|
||||||
private JSplitPane splitPane1;
|
private JSplitPane splitPane1;
|
||||||
private JSplitPane splitPane2;
|
private JSplitPane splitPane2;
|
||||||
private JPanel panel1;
|
private JPanel panel1;
|
||||||
private JLabel listLabel;
|
private JLabel listLabel;
|
||||||
private JLabel treeLabel;
|
private JLabel treeLabel;
|
||||||
private JLabel tableLabel;
|
private JLabel tableLabel;
|
||||||
|
private JCheckBox rowHeaderCheckBox;
|
||||||
private JCheckBox showTableGridCheckBox;
|
private JCheckBox showTableGridCheckBox;
|
||||||
private JCheckBox autoResizeModeCheckBox;
|
private JCheckBox autoResizeModeCheckBox;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane listScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane listScrollPane;
|
||||||
@@ -408,6 +580,7 @@ public class FlatSmoothScrollingTest
|
|||||||
private JTree tree;
|
private JTree tree;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane tableScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane tableScrollPane;
|
||||||
private JTable table;
|
private JTable table;
|
||||||
|
private JSlider scrollToSlider;
|
||||||
private JPanel panel2;
|
private JPanel panel2;
|
||||||
private JLabel textAreaLabel;
|
private JLabel textAreaLabel;
|
||||||
private JLabel textPaneLabel;
|
private JLabel textPaneLabel;
|
||||||
@@ -420,7 +593,7 @@ public class FlatSmoothScrollingTest
|
|||||||
private FlatSmoothScrollingTest.DebugScrollPane editorPaneScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane editorPaneScrollPane;
|
||||||
private JEditorPane editorPane;
|
private JEditorPane editorPane;
|
||||||
private FlatSmoothScrollingTest.DebugScrollPane customScrollPane;
|
private FlatSmoothScrollingTest.DebugScrollPane customScrollPane;
|
||||||
private JButton button1;
|
private JButton customButton;
|
||||||
private LineChartPanel lineChartPanel;
|
private LineChartPanel lineChartPanel;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
@@ -433,6 +606,7 @@ public class FlatSmoothScrollingTest
|
|||||||
private final Color chartColor; // for smooth scrolling
|
private final Color chartColor; // for smooth scrolling
|
||||||
private final Color chartColor2; // for non-smooth scrolling
|
private final Color chartColor2; // for non-smooth scrolling
|
||||||
private int count;
|
private int count;
|
||||||
|
private int lastValue;
|
||||||
private long lastTime;
|
private long lastTime;
|
||||||
|
|
||||||
ScrollBarChangeHandler( DebugScrollPane scrollPane, boolean vertical, String name, Color chartColor ) {
|
ScrollBarChangeHandler( DebugScrollPane scrollPane, boolean vertical, String name, Color chartColor ) {
|
||||||
@@ -442,20 +616,27 @@ public class FlatSmoothScrollingTest
|
|||||||
|
|
||||||
// add change listener to viewport that is invoked from JViewport.setViewPosition()
|
// add change listener to viewport that is invoked from JViewport.setViewPosition()
|
||||||
scrollPane.getViewport().addChangeListener( e -> {
|
scrollPane.getViewport().addChangeListener( e -> {
|
||||||
// add dot to chart if blit scroll mode is disabled
|
JViewport viewport = scrollPane.getViewport();
|
||||||
if( vertical == scrollPane.lastScrollingWasVertical &&
|
Point viewPosition = viewport.getViewPosition();
|
||||||
scrollPane.getViewport().getScrollMode() != JViewport.BLIT_SCROLL_MODE )
|
|
||||||
|
if( (vertical && viewPosition.y != scrollPane.previousViewPosition.y) ||
|
||||||
|
(!vertical && viewPosition.x != scrollPane.previousViewPosition.x) )
|
||||||
{
|
{
|
||||||
// calculate value from view position because scrollbar value is not yet up-to-date
|
// calculate value from view position because scrollbar value is not yet up-to-date
|
||||||
JViewport viewport = scrollPane.getViewport();
|
|
||||||
Point viewPosition = viewport.getViewPosition();
|
|
||||||
Dimension viewSize = viewport.getViewSize();
|
Dimension viewSize = viewport.getViewSize();
|
||||||
double value = vertical
|
double value = vertical
|
||||||
? ((double) viewPosition.y) / (viewSize.height - viewport.getHeight())
|
? ((double) viewPosition.y) / (viewSize.height - viewport.getHeight())
|
||||||
: ((double) viewPosition.x) / (viewSize.width - viewport.getWidth());
|
: ((double) viewPosition.x) / (viewSize.width - viewport.getWidth());
|
||||||
int ivalue = vertical ? viewPosition.y : viewPosition.x;
|
int ivalue = vertical ? viewPosition.y : viewPosition.x;
|
||||||
|
|
||||||
lineChartPanel.addValue( value, ivalue, true, chartColor, name );
|
// add dot to chart if blit scroll mode is disabled
|
||||||
|
boolean dot = (scrollPane.getViewport().getScrollMode() != JViewport.BLIT_SCROLL_MODE);
|
||||||
|
|
||||||
|
Color color = smoothScrollingCheckBox.isSelected() ? this.chartColor : chartColor2;
|
||||||
|
if( dot )
|
||||||
|
lineChartPanel.addValueWithDot( color, value, ivalue, null, name );
|
||||||
|
else
|
||||||
|
lineChartPanel.addValue( color, value, ivalue, name );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@@ -463,26 +644,25 @@ public class FlatSmoothScrollingTest
|
|||||||
@Override
|
@Override
|
||||||
public void stateChanged( ChangeEvent e ) {
|
public void stateChanged( ChangeEvent e ) {
|
||||||
DefaultBoundedRangeModel m = (DefaultBoundedRangeModel) e.getSource();
|
DefaultBoundedRangeModel m = (DefaultBoundedRangeModel) e.getSource();
|
||||||
boolean smoothScrolling = smoothScrollingCheckBox.isSelected();
|
int value = m.getValue();
|
||||||
|
/*
|
||||||
lineChartPanel.addValue( getChartValue( m ), m.getValue(), false,
|
double chartValue = (double) (value - m.getMinimum()) / (double) (m.getMaximum() - m.getExtent());
|
||||||
smoothScrolling ? chartColor : chartColor2, name );
|
lineChartPanel.addValue( chartValue, value, false, false,
|
||||||
|
smoothScrollingCheckBox.isSelected() ? chartColor : chartColor2, name );
|
||||||
|
*/
|
||||||
long t = System.nanoTime() / 1000000;
|
long t = System.nanoTime() / 1000000;
|
||||||
|
|
||||||
System.out.printf( "%s (%d): %4d %3d ms %b%n",
|
System.out.printf( "%s (%d): %4d --> %4d %3d ms %-5b %s%n",
|
||||||
name, ++count,
|
name, ++count,
|
||||||
m.getValue(),
|
lastValue,
|
||||||
|
value,
|
||||||
t - lastTime,
|
t - lastTime,
|
||||||
m.getValueIsAdjusting() );
|
m.getValueIsAdjusting(),
|
||||||
|
value > lastValue ? "down" : value < lastValue ? "up" : "" );
|
||||||
|
|
||||||
|
lastValue = value;
|
||||||
lastTime = t;
|
lastTime = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getChartValue( BoundedRangeModel m ) {
|
|
||||||
int value = m.getValue();
|
|
||||||
return (double) (value - m.getMinimum()) / (double) (m.getMaximum() - m.getExtent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class DebugViewport ------------------------------------------------
|
//---- class DebugViewport ------------------------------------------------
|
||||||
@@ -490,7 +670,7 @@ public class FlatSmoothScrollingTest
|
|||||||
private static class DebugScrollPane
|
private static class DebugScrollPane
|
||||||
extends JScrollPane
|
extends JScrollPane
|
||||||
{
|
{
|
||||||
boolean lastScrollingWasVertical;
|
Point previousViewPosition = new Point();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JViewport createViewport() {
|
protected JViewport createViewport() {
|
||||||
@@ -504,34 +684,11 @@ public class FlatSmoothScrollingTest
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setViewPosition( Point p ) {
|
public void setViewPosition( Point p ) {
|
||||||
// remember whether scrolling vertically or horizontally
|
// remember previous view position
|
||||||
Component view = getView();
|
previousViewPosition = getViewPosition();
|
||||||
if( view != null ) {
|
|
||||||
int oldY = (view instanceof JComponent)
|
|
||||||
? ((JComponent) view).getY()
|
|
||||||
: view.getBounds().y;
|
|
||||||
|
|
||||||
int newY = -p.y;
|
|
||||||
lastScrollingWasVertical = (oldY != newY);
|
|
||||||
} else
|
|
||||||
lastScrollingWasVertical = true;
|
|
||||||
|
|
||||||
super.setViewPosition( p );
|
super.setViewPosition( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paint( Graphics g ) {
|
|
||||||
super.paint( g );
|
|
||||||
|
|
||||||
if( backingStoreImage != null ) {
|
|
||||||
System.out.println( "---------------------------------------------" );
|
|
||||||
System.out.println( "WARNING: backingStoreImage was used for painting" );
|
|
||||||
System.out.println( "View: " + getView() );
|
|
||||||
System.out.println( "Clip: " + g.getClipBounds() );
|
|
||||||
new Exception().printStackTrace( System.out );
|
|
||||||
System.out.println( "---------------------------------------------" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,66 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 0,alignx left,growx 0"
|
"value": "cell 0 0,alignx left,growx 0"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
|
||||||
|
name: "hSpacer1"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": true
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "durationLabel"
|
||||||
|
"text": "Duration:"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": true
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "durationSlider"
|
||||||
|
"maximum": 5000
|
||||||
|
"value": 200
|
||||||
|
"snapToTicks": true
|
||||||
|
"minimum": 100
|
||||||
|
"minorTickSpacing": 50
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "durationOrResolutionChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "durationValueLabel"
|
||||||
|
"text": "0000 ms"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0,width 50"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "resolutionLabel"
|
||||||
|
"text": "Resolution:"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": true
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "resolutionSlider"
|
||||||
|
"maximum": 1000
|
||||||
|
"minimum": 10
|
||||||
|
"value": 10
|
||||||
|
"minorTickSpacing": 10
|
||||||
|
"snapToTicks": true
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "durationOrResolutionChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "resolutionValueLabel"
|
||||||
|
"text": "0000 ms"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0,width 50"
|
||||||
|
} )
|
||||||
add( new FormContainer( "javax.swing.JSplitPane", new FormLayoutManager( class javax.swing.JSplitPane ) ) {
|
add( new FormContainer( "javax.swing.JSplitPane", new FormLayoutManager( class javax.swing.JSplitPane ) ) {
|
||||||
name: "splitPane1"
|
name: "splitPane1"
|
||||||
"orientation": 0
|
"orientation": 0
|
||||||
@@ -27,7 +87,7 @@ new FormModel {
|
|||||||
"orientation": 0
|
"orientation": 0
|
||||||
"resizeWeight": 0.5
|
"resizeWeight": 0.5
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$columnConstraints": "[200,grow,fill][200,grow,fill][200,grow,fill][200,grow,fill]"
|
"$columnConstraints": "[200,grow,fill][200,grow,fill][200,grow,fill][200,grow,fill][fill]"
|
||||||
"$rowConstraints": "[]0[200,grow,fill]"
|
"$rowConstraints": "[]0[200,grow,fill]"
|
||||||
"$layoutConstraints": "ltr,insets 3,hidemode 3"
|
"$layoutConstraints": "ltr,insets 3,hidemode 3"
|
||||||
} ) {
|
} ) {
|
||||||
@@ -53,6 +113,13 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 0 2 1"
|
"value": "cell 2 0 2 1"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "rowHeaderCheckBox"
|
||||||
|
"text": "Row header"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "rowHeaderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 0 2 1,alignx right,growx 0"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "showTableGridCheckBox"
|
name: "showTableGridCheckBox"
|
||||||
"text": "Show table grid"
|
"text": "Show table grid"
|
||||||
@@ -97,6 +164,15 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 1 2 1,width 100,height 100"
|
"value": "cell 2 1 2 1,width 100,height 100"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "scrollToSlider"
|
||||||
|
"orientation": 1
|
||||||
|
"value": 0
|
||||||
|
"inverted": true
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "scrollToChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 1"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
"value": "left"
|
"value": "left"
|
||||||
} )
|
} )
|
||||||
@@ -160,9 +236,8 @@ new FormModel {
|
|||||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatSmoothScrollingTest$DebugScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatSmoothScrollingTest$DebugScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||||
name: "customScrollPane"
|
name: "customScrollPane"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
name: "button1"
|
name: "customButton"
|
||||||
"text": "I'm a large button, but do not implement Scrollable interface"
|
"text": "I'm a large button, but do not implement Scrollable interface"
|
||||||
"preferredSize": new java.awt.Dimension( 800, 800 )
|
|
||||||
"horizontalAlignment": 10
|
"horizontalAlignment": 10
|
||||||
"verticalAlignment": 1
|
"verticalAlignment": 1
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ class LineChartPanel
|
|||||||
if( (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && isShowing() )
|
if( (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && isShowing() )
|
||||||
EventQueue.invokeLater( this::clearChart );
|
EventQueue.invokeLater( this::clearChart );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
// show chart tooltips immediately and forever
|
||||||
|
ToolTipManager.sharedInstance().setInitialDelay( 0 );
|
||||||
|
ToolTipManager.sharedInstance().setDismissDelay( Integer.MAX_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -106,8 +110,24 @@ class LineChartPanel
|
|||||||
updateChartDelayedCheckBox.setSelected( updateChartDelayed );
|
updateChartDelayedCheckBox.setSelected( updateChartDelayed );
|
||||||
}
|
}
|
||||||
|
|
||||||
void addValue( double value, int ivalue, boolean dot, Color chartColor, String name ) {
|
void addValue( Color chartColor, double value, int ivalue, String name ) {
|
||||||
lineChart.addValue( value, ivalue, dot, chartColor, name );
|
lineChart.addValue( chartColor, value, ivalue, null, false, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addValueWithDot( Color chartColor, double value, int ivalue, Color dotColor, String name ) {
|
||||||
|
if( dotColor == null )
|
||||||
|
dotColor = chartColor;
|
||||||
|
lineChart.addValue( chartColor, value, ivalue, dotColor, false, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDot( Color chartColor, double value, int ivalue, Color dotColor, String name ) {
|
||||||
|
if( dotColor == null )
|
||||||
|
dotColor = chartColor;
|
||||||
|
lineChart.addValue( chartColor, value, ivalue, dotColor, true, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMethodHighlight( String classAndMethod, String highlightColor ) {
|
||||||
|
lineChart.methodHighlightMap.put( classAndMethod, highlightColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void oneSecondWidthChanged() {
|
private void oneSecondWidthChanged() {
|
||||||
@@ -255,19 +275,22 @@ class LineChartPanel
|
|||||||
|
|
||||||
private int oneSecondWidth = 1000;
|
private int oneSecondWidth = 1000;
|
||||||
private int msPerLineX = 200;
|
private int msPerLineX = 200;
|
||||||
|
private final HashMap<String, String> methodHighlightMap = new HashMap<>();
|
||||||
|
|
||||||
private static class Data {
|
private static class Data {
|
||||||
final double value;
|
final double value;
|
||||||
final int ivalue;
|
final int ivalue;
|
||||||
final boolean dot;
|
final Color dotColor;
|
||||||
|
final boolean dotOnly;
|
||||||
final long time; // in milliseconds
|
final long time; // in milliseconds
|
||||||
final String name;
|
final String name;
|
||||||
final Exception stack;
|
final Exception stack;
|
||||||
|
|
||||||
Data( double value, int ivalue, boolean dot, long time, String name, Exception stack ) {
|
Data( double value, int ivalue, Color dotColor, boolean dotOnly, long time, String name, Exception stack ) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.ivalue = ivalue;
|
this.ivalue = ivalue;
|
||||||
this.dot = dot;
|
this.dotColor = dotColor;
|
||||||
|
this.dotOnly = dotOnly;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
@@ -276,7 +299,8 @@ class LineChartPanel
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
// for debugging
|
// for debugging
|
||||||
return "value=" + value + ", ivalue=" + ivalue + ", dot=" + dot + ", time=" + time + ", name=" + name;
|
return "value=" + value + ", ivalue=" + ivalue + ", dotColor=" + dotColor
|
||||||
|
+ ", dotOnly=" + dotOnly + ", time=" + time + ", name=" + name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,9 +321,9 @@ class LineChartPanel
|
|||||||
ToolTipManager.sharedInstance().registerComponent( this );
|
ToolTipManager.sharedInstance().registerComponent( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void addValue( double value, int ivalue, boolean dot, Color chartColor, String name ) {
|
void addValue( Color chartColor, double value, int ivalue, Color dotColor, boolean dotOnly, String name ) {
|
||||||
List<Data> chartData = color2dataMap.computeIfAbsent( chartColor, k -> new ArrayList<>() );
|
List<Data> chartData = color2dataMap.computeIfAbsent( chartColor, k -> new ArrayList<>() );
|
||||||
chartData.add( new Data( value, ivalue, dot, System.nanoTime() / 1000000, name, new Exception() ) );
|
chartData.add( new Data( value, ivalue, dotColor, dotOnly, System.nanoTime() / 1000000, name, new Exception() ) );
|
||||||
|
|
||||||
lastUsedChartColor = chartColor;
|
lastUsedChartColor = chartColor;
|
||||||
|
|
||||||
@@ -452,12 +476,13 @@ class LineChartPanel
|
|||||||
lastPoints.add( new Point( dx, dy ) );
|
lastPoints.add( new Point( dx, dy ) );
|
||||||
lastDatas.add( data );
|
lastDatas.add( data );
|
||||||
|
|
||||||
if( data.dot ) {
|
if( data.dotColor != null ) {
|
||||||
int s1 = (int) Math.round( UIScale.scale( 1 ) * scaleFactor );
|
int s1 = (int) Math.round( UIScale.scale( 1 ) * scaleFactor );
|
||||||
int s3 = (int) Math.round( UIScale.scale( 3 ) * scaleFactor );
|
int s3 = (int) Math.round( UIScale.scale( 3 ) * scaleFactor );
|
||||||
g.setColor( chartColor );
|
g.setColor( data.dotColor );
|
||||||
g.fillRect( dx - s1, dy - s1, s3, s3 );
|
g.fillRect( dx - s1, dy - s1, s3, s3 );
|
||||||
continue;
|
if( data.dotOnly )
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !newSeq ) {
|
if( !newSeq ) {
|
||||||
@@ -479,7 +504,7 @@ class LineChartPanel
|
|||||||
int stage = 0;
|
int stage = 0;
|
||||||
for( int j = i + 1; j < size && stage <= 2 && !isTemporaryValue; j++ ) {
|
for( int j = i + 1; j < size && stage <= 2 && !isTemporaryValue; j++ ) {
|
||||||
Data nextData = chartData.get( j );
|
Data nextData = chartData.get( j );
|
||||||
if( nextData.dot )
|
if( nextData.dotOnly )
|
||||||
continue; // ignore dots
|
continue; // ignore dots
|
||||||
|
|
||||||
// check whether next data point is within 10 milliseconds
|
// check whether next data point is within 10 milliseconds
|
||||||
@@ -592,7 +617,7 @@ class LineChartPanel
|
|||||||
|
|
||||||
Data data = lastDatas.get( i );
|
Data data = lastDatas.get( i );
|
||||||
buf.append( "<h2>" );
|
buf.append( "<h2>" );
|
||||||
if( data.dot )
|
if( data.dotOnly )
|
||||||
buf.append( "DOT: " );
|
buf.append( "DOT: " );
|
||||||
buf.append( data.name ).append( ' ' ).append( data.ivalue ).append( "</h2>" );
|
buf.append( data.name ).append( ' ' ).append( data.ivalue ).append( "</h2>" );
|
||||||
|
|
||||||
@@ -601,6 +626,7 @@ class LineChartPanel
|
|||||||
StackTraceElement stackElement = stackTrace[j];
|
StackTraceElement stackElement = stackTrace[j];
|
||||||
String className = stackElement.getClassName();
|
String className = stackElement.getClassName();
|
||||||
String methodName = stackElement.getMethodName();
|
String methodName = stackElement.getMethodName();
|
||||||
|
String classAndMethod = className + '.' + methodName;
|
||||||
|
|
||||||
// ignore methods from this class
|
// ignore methods from this class
|
||||||
if( className.startsWith( LineChartPanel.class.getName() ) )
|
if( className.startsWith( LineChartPanel.class.getName() ) )
|
||||||
@@ -614,11 +640,24 @@ class LineChartPanel
|
|||||||
}
|
}
|
||||||
j += repeatCount;
|
j += repeatCount;
|
||||||
|
|
||||||
|
String highlight = methodHighlightMap.get( classAndMethod );
|
||||||
|
if( highlight == null )
|
||||||
|
highlight = methodHighlightMap.get( className );
|
||||||
|
if( highlight == null )
|
||||||
|
highlight = methodHighlightMap.get( methodName );
|
||||||
|
if( highlight != null )
|
||||||
|
buf.append( "<span color=\"" ).append( highlight ).append( "\">" );
|
||||||
|
|
||||||
// append method
|
// append method
|
||||||
buf.append( className )
|
buf.append( className )
|
||||||
.append( ".<b>" )
|
.append( ".<b>" )
|
||||||
.append( methodName )
|
.append( methodName )
|
||||||
.append( "</b> <span color=\"#888888\">" );
|
.append( "</b>" );
|
||||||
|
if( highlight != null )
|
||||||
|
buf.append( "</span>" );
|
||||||
|
|
||||||
|
// append source
|
||||||
|
buf.append( " <span color=\"#888888\">" );
|
||||||
if( stackElement.getFileName() != null ) {
|
if( stackElement.getFileName() != null ) {
|
||||||
buf.append( '(' );
|
buf.append( '(' );
|
||||||
buf.append( stackElement.getFileName() );
|
buf.append( stackElement.getFileName() );
|
||||||
@@ -628,14 +667,19 @@ class LineChartPanel
|
|||||||
} else
|
} else
|
||||||
buf.append( "(Unknown Source)" );
|
buf.append( "(Unknown Source)" );
|
||||||
buf.append( "</span>" );
|
buf.append( "</span>" );
|
||||||
|
|
||||||
|
// append repeat count
|
||||||
if( repeatCount > 0 )
|
if( repeatCount > 0 )
|
||||||
buf.append( " <b>" ).append( repeatCount + 1 ).append( "x</b>" );
|
buf.append( " <b>" ).append( repeatCount + 1 ).append( "x</b>" );
|
||||||
buf.append( "<br>" );
|
buf.append( "<br>" );
|
||||||
|
|
||||||
// break at some methods to make stack smaller
|
// break at some methods to make stack smaller
|
||||||
if( (className.startsWith( "java.awt.event.InvocationEvent" ) && methodName.equals( "dispatch" )) ||
|
if( classAndMethod.equals( "java.awt.event.InvocationEvent.dispatch" ) ||
|
||||||
(className.startsWith( "java.awt.Component" ) && methodName.equals( "processMouseWheelEvent" )) ||
|
classAndMethod.equals( "java.awt.Component.processMouseEvent" ) ||
|
||||||
(className.startsWith( "javax.swing.JComponent" ) && methodName.equals( "processKeyBinding" )) )
|
classAndMethod.equals( "java.awt.Component.processMouseWheelEvent" ) ||
|
||||||
|
classAndMethod.equals( "java.awt.Component.processMouseMotionEvent" ) ||
|
||||||
|
classAndMethod.equals( "javax.swing.JComponent.processKeyBinding" ) ||
|
||||||
|
classAndMethod.equals( "com.formdev.flatlaf.util.Animator.timingEvent" ) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf.append( "..." );
|
buf.append( "..." );
|
||||||
|
|||||||
Reference in New Issue
Block a user