[Swift-commit] r6668 - in trunk/src/org/griphyn/vdl/karajan/monitor: items monitors/swing
hategan at ci.uchicago.edu
hategan at ci.uchicago.edu
Thu Jul 25 18:34:55 CDT 2013
Author: hategan
Date: 2013-07-25 18:34:55 -0500 (Thu, 25 Jul 2013)
New Revision: 6668
Modified:
trunk/src/org/griphyn/vdl/karajan/monitor/items/SummaryItem.java
trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphPanel.java
trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphsPanel.java
trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GridView.java
Log:
now with customizable dividers and layout persistence
Modified: trunk/src/org/griphyn/vdl/karajan/monitor/items/SummaryItem.java
===================================================================
--- trunk/src/org/griphyn/vdl/karajan/monitor/items/SummaryItem.java 2013-07-25 20:01:31 UTC (rev 6667)
+++ trunk/src/org/griphyn/vdl/karajan/monitor/items/SummaryItem.java 2013-07-25 23:34:55 UTC (rev 6668)
@@ -63,6 +63,15 @@
public static final State[] STATES = State.values();
+ public static State getStateByKey(String key) {
+ for (State s : STATES) {
+ if (s.getName().equals(key)) {
+ return s;
+ }
+ }
+ return null;
+ }
+
private Map<String, Integer> counts;
private int status;
Modified: trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphPanel.java
===================================================================
--- trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphPanel.java 2013-07-25 20:01:31 UTC (rev 6667)
+++ trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphPanel.java 2013-07-25 23:34:55 UTC (rev 6668)
@@ -11,6 +11,7 @@
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -18,6 +19,7 @@
import java.util.Date;
import java.util.List;
import java.util.TimerTask;
+import java.util.prefs.Preferences;
import javax.swing.JButton;
import javax.swing.JColorChooser;
@@ -43,13 +45,15 @@
public class GraphPanel extends JPanel {
private SystemState state;
- private JFreeChart states;
+ private JFreeChart chart;
private final List<SummaryItem.State> enabled;
private TimeSeriesCollection col;
private JPanel legend;
+ private GraphsPanel gp;
- public GraphPanel(SystemState state) {
+ public GraphPanel(SystemState state, GraphsPanel gp) {
this.state = state;
+ this.gp = gp;
this.setLayout(new BorderLayout());
enabled = new ArrayList<SummaryItem.State>();
createChart();
@@ -67,9 +71,9 @@
TimeSeries ts = new TimeSeries(s.getName());
col.addSeries(ts);
}
- states = ChartFactory.createTimeSeriesChart(null, "Time", "Count", col, false, true, false);
- ChartPanel cp = new ChartPanel(states);
- XYPlot plot = (XYPlot) states.getPlot();
+ chart = ChartFactory.createTimeSeriesChart(null, "Time", "Count", col, false, true, false);
+ ChartPanel cp = new ChartPanel(chart);
+ XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(UIManager.getColor("TextField.background"));
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
@@ -89,7 +93,7 @@
private void rebuildLegend() {
legend.removeAll();
for (int i = 0; i < enabled.size(); i++) {
- makeLegendEntry(legend, states, enabled.get(i).getShortName(), i);
+ makeLegendEntry(legend, chart, enabled.get(i).getShortName(), i);
}
legend.add(new JLabel());
legend.add(new JLabel());
@@ -102,7 +106,7 @@
}
});
- legend.add(newb);
+ legend.add(newb);
}
protected void displayAddPopup(JButton src) {
@@ -143,6 +147,7 @@
col.removeSeries(series);
rebuildLegend();
repaint();
+ gp.saveLayout();
}
protected void displaySeriesPopup(final JFreeChart chart, final String label, final int series, final ColorButton button) {
@@ -173,7 +178,22 @@
Color newColor = JColorChooser.showDialog(this, "Pick a color for " + label, color);
button.setColor(newColor);
((XYPlot) chart.getPlot()).getRenderer().setSeriesPaint(series, newColor);
+ gp.saveLayout();
}
+
+ public void setColor(State s, Color color) {
+ int series = enabled.indexOf(s);
+ ((XYPlot) chart.getPlot()).getRenderer().setSeriesPaint(series, color);
+ int i = 0;
+ for (Component c : legend.getComponents()) {
+ if (c instanceof JButton) {
+ i++;
+ if (i == series + 1) {
+ ((ColorButton) c).setColor(color);
+ }
+ }
+ }
+ }
private void update() {
SummaryItem summary = (SummaryItem) state.getItemByID(SummaryItem.ID, StatefulItemClass.WORKFLOW);
@@ -185,12 +205,50 @@
ts.add(new Second(new Date()), summary.getCount(s));
}
}
+
+ public void enable(State s) {
+ enable(s, true);
+ }
- public void enable(State s) {
+ public void enable(State s, boolean save) {
TimeSeries ts = new TimeSeries(s.getName());
col.addSeries(ts);
enabled.add(s);
rebuildLegend();
repaint();
+ if (save) {
+ gp.saveLayout();
+ }
}
+
+ public void store(Preferences p) {
+ p.putInt("enabledCount", enabled.size());
+ for (int i = 0; i < enabled.size(); i++) {
+ Preferences gp = p.node("series" + i);
+ gp.put("key", enabled.get(i).getName());
+ Color color = (Color) chart.getPlot().getLegendItems().get(i).getLinePaint();
+ gp.putInt("color.r", color.getRed());
+ gp.putInt("color.g", color.getGreen());
+ gp.putInt("color.b", color.getBlue());
+ }
+ }
+
+ public static GraphPanel load(Preferences p, SystemState state, GraphsPanel gps) {
+ GraphPanel g = new GraphPanel(state, gps);
+ int ec = p.getInt("enabledCount", 0);
+ for (int i = 0; i < ec; i++) {
+ Preferences gp = p.node("series" + i);
+ String key = gp.get("key", null);
+ if (key == null) {
+ throw new RuntimeException("Null series key");
+ }
+ int cr = gp.getInt("color.r", 255);
+ int cg = gp.getInt("color.g", 0);
+ int cb = gp.getInt("color.b", 0);
+ SummaryItem.State s = SummaryItem.getStateByKey(key);
+ g.enable(s, false);
+ g.setColor(s, new Color(cr, cg, cb));
+ }
+ return g;
+ }
}
Modified: trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphsPanel.java
===================================================================
--- trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphsPanel.java 2013-07-25 20:01:31 UTC (rev 6667)
+++ trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GraphsPanel.java 2013-07-25 23:34:55 UTC (rev 6668)
@@ -15,8 +15,8 @@
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.net.URL;
-import java.util.Deque;
import java.util.LinkedList;
+import java.util.prefs.Preferences;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
@@ -78,15 +78,14 @@
private SystemState state;
- private int rows, columns;
private JPanel toolBar;
private JPopupMenu layoutPopup;
- private Deque<JComponent> graphs;
+ private LinkedList<GraphPanel> graphs;
private GridView grid;
public GraphsPanel(SystemState state) {
this.state = state;
- this.graphs = new LinkedList<JComponent>();
+ this.graphs = new LinkedList<GraphPanel>();
setLayout(new BorderLayout());
toolBar = new JPanel();
@@ -108,12 +107,7 @@
grid = new GridView();
add(grid, BorderLayout.CENTER);
- GraphPanel gp = new GraphPanel(state);
- gp.enable(SummaryItem.State.ACTIVE);
- gp.enable(SummaryItem.State.STAGE_IN);
- gp.enable(SummaryItem.State.STAGE_OUT);
- graphs.add(gp);
- grid.add(gp);
+ loadLayout();
}
private void makeLayoutPopup() {
@@ -147,7 +141,7 @@
grid.setLayout(t.copy());
int count = grid.getCellCount();
while (count > graphs.size()) {
- GraphPanel gp = new GraphPanel(state);
+ GraphPanel gp = new GraphPanel(state, this);
graphs.add(gp);
grid.add(gp);
}
@@ -155,8 +149,69 @@
JComponent gp = graphs.removeLast();
grid.remove(gp);
}
+
+ saveLayout();
}
+ void saveLayout() {
+ /*
+ * Stored are:
+ * - the layout itself
+ * - the graph count and what's being graphed in each
+ * - the graph colors
+ */
+ try {
+ Preferences prefs = Preferences.userNodeForPackage(GraphsPanel.class);
+ Preferences layout = prefs.node("layout");
+ grid.getTree().store(layout);
+ prefs.putInt("graphCount", graphs.size());
+ for (int i = 0; i < graphs.size(); i++) {
+ Preferences gp = prefs.node("graph" + i);
+ graphs.get(i).store(gp);
+ }
+ }
+ catch (Exception e) {
+ System.err.println("Failed to save layout: " + e);
+ }
+ }
+
+ private void loadLayout() {
+ grid.clear();
+ graphs.clear();
+ try {
+ Preferences prefs = Preferences.userNodeForPackage(GraphsPanel.class);
+ if (prefs.nodeExists("layout")) {
+ grid.setLayout(GridView.Tree.load(prefs.node("layout")));
+ int gc = prefs.getInt("graphCount", 0);
+ for (int i = 0; i < gc; i++) {
+ GraphPanel gp = GraphPanel.load(prefs.node("graph" + i), state, this);
+ graphs.add(gp);
+ grid.add(gp);
+ }
+ }
+ else {
+ setDefaultLayout();
+ }
+ }
+ catch (Exception e) {
+ System.err.println("Failed to load layout: " + e + ". Using default.");
+ setDefaultLayout();
+ }
+ }
+
+ private void setDefaultLayout() {
+ grid.clear();
+ graphs.clear();
+ grid.setLayout(new Tree());
+ GraphPanel gp = new GraphPanel(state, this);
+ gp.enable(SummaryItem.State.ACTIVE);
+ gp.enable(SummaryItem.State.STAGE_IN);
+ gp.enable(SummaryItem.State.STAGE_OUT);
+ graphs.add(gp);
+ grid.add(gp);
+ saveLayout();
+ }
+
protected void displayLayoutPopup(JButton src) {
layoutPopup.show(src, 6, 6);
}
Modified: trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GridView.java
===================================================================
--- trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GridView.java 2013-07-25 20:01:31 UTC (rev 6667)
+++ trunk/src/org/griphyn/vdl/karajan/monitor/monitors/swing/GridView.java 2013-07-25 23:34:55 UTC (rev 6668)
@@ -11,41 +11,84 @@
import java.awt.BasicStroke;
import java.awt.Component;
+import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
import javax.swing.ImageIcon;
+import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class GridView extends JPanel {
public static final int DIVIDER_SIZE = 10;
+ public static final Cursor H_RESIZE_CURSOR = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
+ public static final Cursor V_RESIZE_CURSOR = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
- private GridView.Tree tree;
+ public static final Stroke DIVIDER_STROKE = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 0,
+ new float[] {5.0f}, 0f);
+ private Tree tree;
+ private List<Divider> dividers;
+ private int cellCount, dividerIndex;
+
public GridView() {
- tree = new Tree();
+ dividers = new ArrayList<Divider>();
+ setLayout(new Tree());
}
public void setLayout(Tree t) {
this.tree = t;
- revalidate();
+ cellCount = this.tree.cellCount();
+ validate();
+ repaint();
}
+ public void clear() {
+ tree = null;
+ removeAll();
+ }
+
+ public Tree getTree() {
+ return tree;
+ }
+
public int getCellCount() {
- return tree.cellCount();
+ return cellCount;
}
@Override
- public void doLayout() {
+ public synchronized void doLayout() {
+ dividerIndex = 0;
layout(tree, 0, 0, getWidth(), getHeight(), 0);
+ while (dividers.size() > dividerIndex + 1) {
+ Divider d = dividers.get(dividers.size() - 1);
+ dividers.remove(dividers.size() - 1);
+ remove(d);
+ }
}
+
+ @Override
+ public synchronized Component add(Component comp) {
+ // add before dividers
+ return super.add(comp, getComponentCount() - dividers.size());
+ }
private int layout(GridView.Tree t, int x, int y, int w, int h, int index) {
+ if (t == null) {
+ return index;
+ }
if (t.splitType == Tree.NONE) {
- if (getComponentCount() > index) {
+ if (cellCount > index) {
Component c = getComponent(index);
c.setSize(w, h);
c.setLocation(x, y);
@@ -53,52 +96,41 @@
return index + 1;
}
else if (t.splitType == Tree.V) {
- int h1 = (int) (t.splitPosition * h) - DIVIDER_SIZE / 2;
- int h2 = h - h1 - DIVIDER_SIZE;
- index = layout(t.first, x, y, w, h1, index);
- return layout(t.second, x, y + h1 + DIVIDER_SIZE, w, h2, index);
+ int h1 = (int) (t.splitPosition * h);
+ int h2 = h - h1;
+ setDivider(Tree.V, x, y + h1 - DIVIDER_SIZE / 2, w, DIVIDER_SIZE, h, t);
+ index = layout(t.first, x, y, w, h1 - DIVIDER_SIZE / 2, index);
+ return layout(t.second, x, y + h1 + DIVIDER_SIZE / 2, w, h2, index);
}
else if (t.splitType == Tree.H) {
- int w1 = (int) (t.splitPosition * w) - DIVIDER_SIZE / 2;
- int w2 = w - w1 - DIVIDER_SIZE;
- index = layout(t.first, x, y, w1, h, index);
- return layout(t.second, x + w1 + DIVIDER_SIZE, y, w2, h, index);
+ int w1 = (int) (t.splitPosition * w);
+ int w2 = w - w1;
+ setDivider(Tree.H, x + w1 - DIVIDER_SIZE / 2, y, DIVIDER_SIZE, h, w, t);
+ index = layout(t.first, x, y, w1 - DIVIDER_SIZE / 2, h, index);
+ return layout(t.second, x + w1 + DIVIDER_SIZE / 2, y, w2, h, index);
}
return index;
}
- private final Stroke DIVIDER_STROKE = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 0,
- new float[] {5.0f}, 0f);
-
-
- @Override
- public void paint(Graphics g) {
- super.paint(g);
- Graphics2D g2 = (Graphics2D) g;
- g2.setColor(UIManager.getColor("Table.gridColor"));
- g2.setStroke(DIVIDER_STROKE);
- paintDivider(g, tree, 0, 0, getWidth(), getHeight());
- }
-
- private void paintDivider(Graphics g, Tree t, int x, int y, int w, int h) {
- if (t == null || t.splitType == Tree.NONE) {
+ private void setDivider(int dir, int x, int y, int w, int h, int range, Tree t) {
+ if (dividers.size() <= dividerIndex) {
+ Divider d = new Divider(dir, x, y, w, h, range, t);
+ dividers.add(d);
+ super.add(d);
}
- else if (t.splitType == Tree.V) {
- int h1 = (int) (t.splitPosition * h);
- g.drawLine(x, y + h1, x + w, y + h1);
- paintDivider(g, t.first, x, y, w, h1 - DIVIDER_SIZE / 2);
- paintDivider(g, t.second, x, y + h1 + DIVIDER_SIZE / 2, w, h1 - DIVIDER_SIZE / 2);
+ else {
+ Divider d = dividers.get(dividerIndex);
+ d.set(dir, x, y, w, h, range, t);
+ d.validate();
}
- else if (t.splitType == Tree.H) {
- int w1 = (int) (t.splitPosition * w);
- g.drawLine(x + w1, y, x + w1, y + h);
- paintDivider(g, t.first, x, y, w1 - DIVIDER_SIZE / 2, h);
- paintDivider(g, t.second, x + w1 + DIVIDER_SIZE / 2, y, w1 - DIVIDER_SIZE / 2, h);
- }
+ dividerIndex++;
}
-
-
+ private void addDivider(Divider divider) {
+ dividers.add(divider);
+ this.add(divider);
+ }
+
public static class Tree {
public static final int NONE = 0;
public static final int H = 1;
@@ -162,6 +194,30 @@
return t.copy();
}
}
+
+ public void store(Preferences p) {
+ p.putInt("splitType", splitType);
+ p.putDouble("splitPosition", splitPosition);
+ if (first != null) {
+ Preferences p1 = p.node("first");
+ first.store(p1);
+ }
+ if (second != null) {
+ Preferences p2 = p.node("second");
+ second.store(p2);
+ }
+ }
+
+ public static Tree load(Preferences p) throws BackingStoreException {
+ Tree tree = new Tree();
+ tree.splitType = p.getInt("splitType", H);
+ tree.splitPosition = p.getDouble("splitPosition", 0.5);
+ if (tree.splitType != NONE) {
+ tree.first = load(p.node("first"));
+ tree.second = load(p.node("second"));
+ }
+ return tree;
+ }
}
private static class TreeIcon extends ImageIcon {
@@ -209,4 +265,123 @@
}
}
}
+
+ private static class Divider extends JComponent implements MouseListener, MouseMotionListener {
+ private int type, range;
+ private Tree tree;
+ private boolean dragging;
+ private int vd;
+
+ public Divider(int type, int x, int y, int w, int h, int range, Tree tree) {
+ this.type = type;
+ this.tree = tree;
+ this.range = range;
+ this.setLocation(x, y);
+ this.setSize(w, h);
+ if (type == Tree.H) {
+ this.setCursor(H_RESIZE_CURSOR);
+ }
+ else {
+ this.setCursor(V_RESIZE_CURSOR);
+ }
+ addMouseListener(this);
+ addMouseMotionListener(this);
+ }
+
+ public void set(int dir, int x, int y, int w, int h, int range, Tree t) {
+ this.type = dir;
+ this.tree = t;
+ this.range = range;
+ setLocation(x, y);
+ setSize(w, h);
+ if (type == Tree.H) {
+ this.setCursor(H_RESIZE_CURSOR);
+ }
+ else {
+ this.setCursor(V_RESIZE_CURSOR);
+ }
+ }
+
+ public void paintComponent(Graphics g) {
+ Graphics2D g2 = (Graphics2D) g;
+
+ if (dragging) {
+ g2.setColor(UIManager.getColor("Separator.highlight"));
+ }
+ else {
+ g2.setColor(UIManager.getColor("Separator.foreground"));
+ }
+ //g2.setColor(Color.BLACK);
+ g2.setStroke(DIVIDER_STROKE);
+ if (type == Tree.H) {
+ int w2 = getWidth() / 2;
+ g.drawLine(w2, 0, w2, getHeight());
+ }
+ else {
+ int h2 = getHeight() / 2;
+ g.drawLine(0, h2, getWidth(), h2);
+ }
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ int v;
+ if (type == Tree.V) {
+ v = e.getYOnScreen() - vd;
+ }
+ else {
+ v = e.getXOnScreen() - vd;
+ }
+
+ if (v < 0) {
+ v = 0;
+ }
+ if (v > range) {
+ v = range;
+ }
+ double pos = (double) v / range;
+ tree.splitPosition = pos;
+ getParent().revalidate();
+ getParent().repaint();
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ if (dragging) {
+ mouseDragged(e);
+ }
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ dragging = true;
+ if (type == Tree.H) {
+ int w2 = getX() + getWidth() / 2;
+ vd = e.getXOnScreen() - w2;
+ }
+ else {
+ int h2 = getY() + getHeight() / 2;
+ vd = e.getYOnScreen() - h2;
+ }
+ repaint();
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ dragging = false;
+ repaint();
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ }
+ }
}
\ No newline at end of file
More information about the Swift-commit
mailing list