From b67213c92dc149f4d8e2693bb8af070383f27247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Dr=C3=A4ger?= Date: Mon, 19 Apr 2010 09:24:34 +0000 Subject: [PATCH] Improved the function area. Setting legends is now easier and really works. The pair class is now based on a sorted set data structure to avoid having identical labels multiple times. This may happen if one plots data points together with simulation results. To this end, the data structure now checks whether an element with the same label and color is already present. --- src/eva2/gui/FunctionArea.java | 95 +++++++++++---- src/eva2/gui/GraphPointSetLegend.java | 167 ++++++++++++++++++-------- src/eva2/tools/Pair.java | 64 ++++++++-- 3 files changed, 238 insertions(+), 88 deletions(-) diff --git a/src/eva2/gui/FunctionArea.java b/src/eva2/gui/FunctionArea.java index 826cde41..0abd7589 100644 --- a/src/eva2/gui/FunctionArea.java +++ b/src/eva2/gui/FunctionArea.java @@ -68,8 +68,14 @@ public class FunctionArea extends DArea implements Serializable { private InterfaceRefPointListener m_RefPointListener; private int m_x; + /** + * + */ private int m_y; + /** + * + */ private boolean notifyNegLog = true; /** @@ -596,15 +602,20 @@ public class FunctionArea extends DArea implements Serializable { } /** - * - */ + * This gives the number of graphs already plotted. + * + * @return + */ public int getContainerSize() { return m_PointSetContainer.size(); } /** - * - */ + * + * @param x + * @param y + * @return + */ public String getGraphInfo(int x, int y) { String ret = ""; if ((m_PointSetContainer == null) || (m_PointSetContainer.size() == 0)) @@ -618,8 +629,10 @@ public class FunctionArea extends DArea implements Serializable { } /** - * - */ + * + * @param GraphLabel + * @return + */ private GraphPointSet getGraphPointSet(int GraphLabel) { // System.out.println("looping through " + m_PointSetContainer.size() + // " point sets..."); @@ -677,8 +690,11 @@ public class FunctionArea extends DArea implements Serializable { } /** - * - */ + * + * @param x + * @param y + * @return + */ private int getNearestGraphIndex(int x, int y) { // get index of nearest Graph double distmin = 10000000; @@ -749,13 +765,14 @@ public class FunctionArea extends DArea implements Serializable { @Override public void paint(Graphics g) { super.paint(g); - if (legendBox != null && (m_legend)) + if (legendBox != null && m_legend) legendBox.paintIn(g, m_Border.getInnerRect(this)); } /** - * - */ + * + * @return + */ public DPointSet[] printPoints() { DPointSet[] ret = new DPointSet[m_PointSetContainer.size()]; for (int i = 0; i < m_PointSetContainer.size(); i++) { @@ -768,6 +785,11 @@ public class FunctionArea extends DArea implements Serializable { } + /** + * + * @param i + * @return + */ public DPointSet printPoints(int i) { // for (int i = 0; i < m_PointSetContainer.size();i++) { System.out.println(""); @@ -820,8 +842,10 @@ public class FunctionArea extends DArea implements Serializable { } /** - * - */ + * + * @param p + * @param graphLabel + */ public void setConnectedPoint(double[] p, int graphLabel) { setConnectedPoint(p[0], p[1], graphLabel); } @@ -910,8 +934,11 @@ public class FunctionArea extends DArea implements Serializable { } /** - * - */ + * + * @param GraphLabel + * @param Info + * @param stroke + */ public void setInfoString(int GraphLabel, String Info, float stroke) { getGraphPointSet(GraphLabel).setInfoString(Info, stroke); } @@ -929,8 +956,11 @@ public class FunctionArea extends DArea implements Serializable { } /** - * - */ + * + * @param x + * @param y + * @param GraphLabel + */ public void setUnconnectedPoint(double x, double y, int GraphLabel) { if (!checkLogValidYValue(x, y, GraphLabel)) { if (m_log) @@ -941,10 +971,18 @@ public class FunctionArea extends DArea implements Serializable { repaint(); } + /** + * + * @param p + * @param GraphLabel + */ public void setUnconnectedPoint(double[] p, int GraphLabel) { setUnconnectedPoint(p[0], p[1], GraphLabel); } + /** + * + */ private void toggleLegend() { m_legend = !m_legend; repaint(); @@ -957,18 +995,16 @@ public class FunctionArea extends DArea implements Serializable { */ public void showLegend(boolean on) { m_legend = on; - if (on) { - if (legendBox == null) - legendBox = new GraphPointSetLegend(m_PointSetContainer); - } else { + if (!on) legendBox = null; - } + else + legendBox = new GraphPointSetLegend(m_PointSetContainer); repaint(); } /** - * - */ + * + */ public void toggleLog() { // System.out.println("ToggleLog log was: "+m_log); if (!m_log && !checkLoggable()) { @@ -1015,4 +1051,15 @@ public class FunctionArea extends DArea implements Serializable { GraphPointSetLegend lb = new GraphPointSetLegend(m_PointSetContainer); setLegend(lb); } + + /** + * Gives the info string for a graph label. + * + * @param j + * The graph label identifier. + * @return The associated info string. + */ + public String getInfoString(int j) { + return getGraphPointSet(j).getInfoString(); + } } diff --git a/src/eva2/gui/GraphPointSetLegend.java b/src/eva2/gui/GraphPointSetLegend.java index 50bcc4aa..f013ed42 100644 --- a/src/eva2/gui/GraphPointSetLegend.java +++ b/src/eva2/gui/GraphPointSetLegend.java @@ -5,7 +5,10 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.geom.Rectangle2D; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; import javax.swing.BoxLayout; import javax.swing.JComponent; @@ -17,101 +20,159 @@ import eva2.tools.Pair; import eva2.tools.chart2d.SlimRect; /** - * A class representing the legend of a plot. It is created from a list of GraphPointSets as - * used in FunctionArea. Painting is done in FunctionArea. As an alternative, an own frame - * could be created. + * A class representing the legend of a plot. It is created from a list of + * GraphPointSets as used in FunctionArea. Painting is done in FunctionArea. As + * an alternative, an own frame could be created. * * @author mkron - * + * */ -public class GraphPointSetLegend { - Pair[] legendEntries; +public class GraphPointSetLegend { + SortedSet> legendEntries; + + /** + * + * @author draeger + * + */ + private static class PairComp implements Comparator> { + + /* + * (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Pair o1, Pair o2) { + return o1.car().compareTo(o2.car()); + } + + } + private static final PairComp comperator = new PairComp(); + + /** + * + * @param pointSetContainer + */ public GraphPointSetLegend(List pointSetContainer) { - legendEntries = new Pair[pointSetContainer.size()]; + legendEntries = new TreeSet>(comperator); for (int i = 0; i < pointSetContainer.size(); i++) { GraphPointSet pointset = pointSetContainer.get(i); - legendEntries[i] = new Pair(pointset.getInfoString(), pointset.getColor()); - } + legendEntries.add(new Pair(pointset.getInfoString(), + pointset.getColor())); + } } /** * Add the legend labels to a container. + * * @param comp */ public void addToContainer(JComponent comp) { - for (int i = 0; i < legendEntries.length; i++) { - JLabel label = new JLabel(legendEntries[i].head); - label.setForeground(legendEntries[i].tail); + for (Pair legendEntry : legendEntries) { + JLabel label = new JLabel(legendEntry.head); + label.setForeground(legendEntry.tail); comp.add(label); } } - - public static JPanel makeLegendPanel(Color bgCol, ArrayList pointSetContainer) { + + /** + * + * @param bgCol + * @param pointSetContainer + * @return + */ + public static JPanel makeLegendPanel(Color bgCol, + ArrayList pointSetContainer) { JPanel pan = new JPanel(); pan.setBackground(bgCol); pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS)); - GraphPointSetLegend lBox=new GraphPointSetLegend(pointSetContainer); + GraphPointSetLegend lBox = new GraphPointSetLegend(pointSetContainer); lBox.addToContainer(pan); return pan; } - public static JFrame makeLegendFrame(Color bgCol, ArrayList pointSetContainer) { + /** + * + * @param bgCol + * @param pointSetContainer + * @return + */ + public static JFrame makeLegendFrame(Color bgCol, + ArrayList pointSetContainer) { JFrame frame = new JFrame("Legend"); -// LegendBox lBox = new LegendBox(bgCol, pointSetContainer); + // LegendBox lBox = new LegendBox(bgCol, pointSetContainer); frame.add(makeLegendPanel(bgCol, pointSetContainer)); frame.pack(); - frame.setVisible(true); + frame.setVisible(true); return frame; } + /** + * + * @param component + */ public void paintIn(JComponent component) { Graphics g = component.getGraphics(); FontMetrics fm = g.getFontMetrics(); - int yOffs=5+fm.getHeight(); - int xOffs=0; + int yOffs = 5 + fm.getHeight(); + int xOffs = 0; Color origCol = g.getColor(); - - for (int i=0; i legendEntry : legendEntries) { + g.setColor(legendEntry.tail); + Rectangle2D rect = fm.getStringBounds(legendEntry.head, g); + xOffs = (int) (component.getWidth() - rect.getWidth() - 5); + g.drawString(legendEntry.head, xOffs, yOffs); + yOffs += (5 + rect.getHeight()); } g.setColor(origCol); } - -// public void paintIn(Graphics g, Dimension dim) { -// paintIn(g, dim.width); -// } -// -// public void paintIn(Graphics g, Rectangle rect) { -// paintIn(g, rect.width); -// } -// -// public void paintIn(Graphics g, DRectangle rect) { -// paintIn(g, (int)rect.width); -// } - + + // public void paintIn(Graphics g, Dimension dim) { + // paintIn(g, dim.width); + // } + // + // public void paintIn(Graphics g, Rectangle rect) { + // paintIn(g, rect.width); + // } + // + // public void paintIn(Graphics g, DRectangle rect) { + // paintIn(g, (int)rect.width); + // } + + /** + * + */ public void paintIn(Graphics g, SlimRect rect) { - paintIn(g, (int)rect.getX(), (int)rect.getY(), (int)rect.getX()+(int)rect.getWidth()); + paintIn(g, (int) rect.getX(), (int) rect.getY(), (int) rect.getX() + + (int) rect.getWidth()); } - + + /** + * + * @param g + * @param x + * @param y + * @param maxX + */ private void paintIn(Graphics g, int x, int y, int maxX) { FontMetrics fm = g.getFontMetrics(); -// System.out.println("In LegendBox.paintIn!"); - int yOffs=5+y+fm.getHeight(); - int xOffs=x; + // System.out.println("In LegendBox.paintIn!"); + int yOffs = 5 + y + fm.getHeight(); + int xOffs = x; Color origCol = g.getColor(); - - for (int i=0; i legendEntry : legendEntries) { + // System.out.println(legendEntries[i].toString() + "\tcontaines: " + // + set.contains(legendEntries[i])); + g.setColor(legendEntry.tail); + Rectangle2D stringBounds = fm.getStringBounds( + legendEntry.head, g); + xOffs = (int) (maxX - stringBounds.getWidth() - 5); + g.drawString(legendEntry.head, xOffs, yOffs); + // g.drawString(legendEntries[i].head, 80, 80); + yOffs += (5 + stringBounds.getHeight()); } g.setColor(origCol); } diff --git a/src/eva2/tools/Pair.java b/src/eva2/tools/Pair.java index 83c42242..38ff435b 100644 --- a/src/eva2/tools/Pair.java +++ b/src/eva2/tools/Pair.java @@ -6,7 +6,7 @@ import java.io.Serializable; * Simple pair structure of two types, Scheme style, but typed. * * @author mkron - * + * */ public class Pair implements Serializable { /** @@ -15,33 +15,75 @@ public class Pair implements Serializable { private static final long serialVersionUID = -3620465393975181451L; public S head; public T tail; - - public Object clone() { - return new Pair(head, tail); - } + /** + * + * @param head + * @param tail + */ public Pair(S head, T tail) { this.head = head; this.tail = tail; } - + + /** + * + * @return + */ public S car() { return head; } - + + /** + * + * @return + */ public T cdr() { return tail; } - + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + public Pair clone() { + return new Pair(head, tail); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return toString().hashCode(); + } + + /** + * + * @return + */ public S head() { return head; } - + + /** + * + * @return + */ public T tail() { return tail; } - + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override public String toString() { - return "(" + head.toString() + "," + tail.toString()+")"; + return "(" + head.toString() + "," + tail.toString() + ")"; } } \ No newline at end of file