cdc.perfs.ui.swing.ControlledChartPanel Maven / Gradle / Ivy
package cdc.perfs.ui.swing;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.Timer;
import cdc.perfs.core.Environment;
import cdc.perfs.core.EnvironmentKind;
import cdc.perfs.ui.PerfsChartHelper;
import cdc.perfs.ui.RefreshRate;
import cdc.perfs.ui.Rendering;
import cdc.ui.swing.GridBagConstraintsBuilder;
import cdc.util.lang.Checks;
/**
* Panel dedicated to graphical display of measures and its controls.
*
* @author Damien Carbonne
*
*/
public final class ControlledChartPanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final double ZOOM_FACTOR = 1.1;
final JButton wMoveToBegin = new JButton("|<");
final JButton wLess = new JButton("<");
final JButton wMore = new JButton(">");
final JButton wMoveToEnd = new JButton(">|");
private final JCheckBox wFocusLocked;
final JSlider wScale = new JSlider();
private final JScrollPane wScrollPane = new JScrollPane();
final ChartPanel wChart;
private enum TimeChangeMode {
DEC,
INC,
NONE
}
TimeChangeMode timeChangeMode = TimeChangeMode.NONE;
long timeChangeInit;
private final transient ActionListener timeChangeHandler;
final Timer timer;
private final transient PerfsChartHelper.ChangeListener changeHandler = source -> refresh();
public ControlledChartPanel(ContextsTableModel contextsModel,
SourcesTableModel sourcesModel) {
super();
final GridBagLayout gbl = new GridBagLayout();
gbl.columnWeights = new double[] { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 };
gbl.rowWeights = new double[] { 1.0, 0.0 };
setLayout(gbl);
// ScrollPane
add(wScrollPane,
GridBagConstraintsBuilder.builder()
.fill(GridBagConstraints.BOTH)
.gridwidth(6)
.insets(0, 0, 5, 0)
.gridx(0)
.gridy(0)
.build());
// Chart
wChart = new ChartPanel(this, contextsModel, sourcesModel);
wScrollPane.setViewportView(wChart);
wChart.addChangeListener(this.changeHandler);
timeChangeHandler = e -> {
final long nanos = System.nanoTime() - timeChangeInit;
switch (timeChangeMode) {
case DEC:
wChart.decrementFocus(nanos);
break;
case INC:
wChart.incrementFocus(nanos);
break;
default:
break;
}
};
this.timer = new Timer(10, this.timeChangeHandler);
this.timer.setInitialDelay(0);
// Move to begin
wMoveToBegin.setEnabled(wChart.isFocusLocked());
wMoveToBegin.addActionListener(event -> wChart.setFocusNanos(0.0));
add(wMoveToBegin,
GridBagConstraintsBuilder.builder()
.insets(0, 5, 0, 5)
.gridx(0)
.gridy(1)
.build());
// Less
wLess.setEnabled(wChart.isFocusLocked());
wLess.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
less();
}
@Override
public void mouseReleased(MouseEvent e) {
stop();
}
});
add(wLess,
GridBagConstraintsBuilder.builder()
.insets(0, 0, 0, 5)
.gridx(1)
.gridy(1)
.build());
// Time lock
wFocusLocked = new JCheckBox("lock");
if (getEnvironment().getKind() == EnvironmentKind.SNAPSHOT) {
wFocusLocked.setEnabled(false);
wFocusLocked.setSelected(true);
wChart.setFocusLocked(true);
wMoveToBegin.setEnabled(wChart.isFocusLocked());
wLess.setEnabled(wChart.isFocusLocked());
wMore.setEnabled(wChart.isFocusLocked());
wMoveToEnd.setEnabled(wChart.isFocusLocked());
} else {
wFocusLocked.addActionListener(event -> setFocusLocked(wFocusLocked.isSelected()));
}
add(wFocusLocked,
GridBagConstraintsBuilder.builder()
.anchor(GridBagConstraints.LINE_END)
.insets(0, 0, 0, 5)
.gridx(2)
.gridy(1)
.build());
// Scale
wScale.setMajorTickSpacing(PerfsChartHelper.SCALE_MAX / 5);
wScale.setMinorTickSpacing(PerfsChartHelper.SCALE_MAX / 10);
wScale.setPaintTicks(true);
wScale.setMinimum(0);
wScale.setMaximum(PerfsChartHelper.SCALE_MAX);
wScale.setValue(PerfsChartHelper.SCALE_MAX / 2);
final Dimension d = wScale.getPreferredSize();
wScale.setPreferredSize(new Dimension(100, d.height));
wScale.setMinimumSize(wScale.getPreferredSize());
wScale.addChangeListener(event -> {
final JSlider w = (JSlider) event.getSource();
final double scale = PerfsChartHelper.sliderToScale(w.getValue());
wChart.setScale(scale);
});
add(wScale,
GridBagConstraintsBuilder.builder()
.insets(0, 0, 0, 5)
.gridx(3)
.gridy(1)
.build());
// More
wMore.setEnabled(wChart.isFocusLocked());
wMore.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
more();
}
@Override
public void mouseReleased(MouseEvent e) {
stop();
}
});
add(wMore,
GridBagConstraintsBuilder.builder()
.gridx(4)
.gridy(1)
.build());
// Move to end
wMoveToEnd.setEnabled(wChart.isFocusLocked());
wMoveToEnd.addActionListener(event -> wChart.setFocusNanos(wChart.getEnvironment().getElapsedNanos()));
add(wMoveToEnd,
GridBagConstraintsBuilder.builder()
.insets(0, 0, 0, 5)
.gridx(5)
.gridy(1)
.build());
setScale(PerfsChartHelper.sliderToScale(wScale.getValue()));
refresh();
}
public Environment getEnvironment() {
return wChart.getEnvironment();
}
public void setRefreshRate(RefreshRate rate) {
Checks.isNotNull(rate, "rate");
wChart.setRefreshRate(rate);
}
public RefreshRate getRefreshRate() {
return wChart.getRefreshRate();
}
public void setRendering(Rendering rendering) {
Checks.isNotNull(rendering, "rendering");
wChart.setRendering(rendering);
}
public Rendering getRendering() {
return wChart.getRendering();
}
public void setDisplayStatsEnabled(boolean enabled) {
wChart.setDisplayStatsEnabled(enabled);
}
public boolean getDisplayStatsEnabled() {
return wChart.getDisplayStatsEnabled();
}
public void setDrawBordersEnabled(boolean enabled) {
wChart.setDrawBordersEnabled(enabled);
}
public boolean getDrawBordersEnabled() {
return wChart.getDrawBordersEnabled();
}
public void setScale(double scale) {
wChart.setScale(scale);
}
public double getScale() {
return wChart.getScale();
}
public void zoomIn() {
setScale(getScale() / ZOOM_FACTOR);
}
public void zoomOut() {
setScale(getScale() * ZOOM_FACTOR);
}
public void setFocusNanos(double time) {
wChart.setFocusNanos(time);
}
public void setFocusLocked(boolean locked) {
if (wFocusLocked.isSelected() != locked) {
wFocusLocked.setSelected(locked);
}
wChart.setFocusLocked(locked);
wMoveToBegin.setEnabled(locked);
wLess.setEnabled(locked);
wMore.setEnabled(locked);
wMoveToEnd.setEnabled(locked);
}
public double getFocusNanos() {
return wChart.getFocusNanos();
}
void refresh() {
wScale.setValue((int) PerfsChartHelper.scaleToSlider(wChart.getScale()));
}
void more() {
if (timeChangeMode != TimeChangeMode.INC) {
timeChangeMode = TimeChangeMode.INC;
timeChangeInit = System.nanoTime();
if (!timer.isRunning()) {
timer.start();
}
}
}
void less() {
if (timeChangeMode != TimeChangeMode.DEC) {
timeChangeMode = TimeChangeMode.DEC;
timeChangeInit = System.nanoTime();
if (!timer.isRunning()) {
timer.start();
}
}
}
void stop() {
if (timeChangeMode != TimeChangeMode.NONE) {
timeChangeMode = TimeChangeMode.NONE;
timer.stop();
}
}
TimeChangeMode getTimeChangeMode() {
return timeChangeMode;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy