From ca903ef4dfce164da79a2a0f719c5472cf0dcee3 Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Wed, 29 Sep 2010 15:18:54 +0000 Subject: [PATCH] Allow switching between standard and exponential numbering format for the plots. --- src/eva2/client/EvAClient.java | 34 ++++++++ src/eva2/gui/FunctionArea.java | 22 ++++- src/eva2/tools/chart2d/ScaledBorder.java | 103 ++++++++++++++++++++--- 3 files changed, 143 insertions(+), 16 deletions(-) diff --git a/src/eva2/client/EvAClient.java b/src/eva2/client/EvAClient.java index 9dc9b68d..81ff44ef 100644 --- a/src/eva2/client/EvAClient.java +++ b/src/eva2/client/EvAClient.java @@ -66,6 +66,7 @@ import eva2.server.modules.GOParameters; import eva2.server.modules.GenericModuleAdapter; import eva2.server.modules.ModuleAdapter; import eva2.server.stat.AbstractStatistics; +import eva2.server.stat.InterfaceStatisticsListener; import eva2.server.stat.InterfaceStatisticsParameter; import eva2.tools.BasicResourceLoader; import eva2.tools.EVAERROR; @@ -489,6 +490,39 @@ public class EvAClient implements RemoteStateListener, Serializable { } } + + /** + * Initialize the client GUI with given parameters and set + * listeners. This will return as soon as the GUI is visible and ready. + * + * @param goParams optimization parameters + * @param statisticsListener statistics listener receiving data during optimization + * @param windowListener additional window listener for client frame + */ + public static EvAClient initClientGUI(GOParameters goParams, + InterfaceStatisticsListener statisticsListener, + WindowListener windowListener, final Window parent) { + EvAClient evaClient; + + evaClient = new EvAClient(null, parent, null, goParams, + false, true, false); // initializes GUI in the background + // important: wait for GUI initialization before accessing any internal + // settings: + evaClient.awaitClientInitialized(); // this returns as soon as the + // GUI is ready + evaClient.addWindowListener(windowListener); + // modify initial settings: + evaClient.getStatistics().getStatisticsParameter().setOutputAllFieldsAsText(true); // activate output of all data + // fields + // add a data listener instance: + evaClient.getStatistics().addDataListener(statisticsListener); + + evaClient.refreshMainPanels(); // GUI update due to the changes made through the API + + + return evaClient; + } + public static String usage() { StringBuffer sbuf = new StringBuffer(); sbuf.append(EvAInfo.productName); diff --git a/src/eva2/gui/FunctionArea.java b/src/eva2/gui/FunctionArea.java index f8265071..41465635 100644 --- a/src/eva2/gui/FunctionArea.java +++ b/src/eva2/gui/FunctionArea.java @@ -213,6 +213,12 @@ public class FunctionArea extends DArea implements Serializable { } }); + addMenuItem(graphPopupMenu, "Toggle scientific format", new ActionListener() { + public void actionPerformed(ActionEvent ee) { + toggleScientificY(true); + } + }); + if (FunctionArea.this.m_PointSetContainer.size() > 0) { addMenuItem(graphPopupMenu, "Recolor all graphs", new ActionListener() { @@ -1188,7 +1194,8 @@ public class FunctionArea extends DArea implements Serializable { exp.setMinValue(getMinimalPositiveYValue()); setYScale(exp); m_Border.setSrcdY(Math.log(10)); - m_Border.applyPattern(false, "0.###E0"); + m_Border.setScientificPattern(false); // scientific on y axis +// m_Border.applyPattern(false, "0.###E0"); // replaced by the former line m_log = true; } else { m_log = false; @@ -1198,11 +1205,22 @@ public class FunctionArea extends DArea implements Serializable { m_Border.x_label = buffer.x_label; // "App. " + Name + // " func. calls"; m_Border.y_label = buffer.y_label; // "fitness"; + m_Border.setStandardPattern(false); // default decimal pattern on y axis setBorder(m_Border); } repaint(); } - + + /** + * Toggle between different decimal patterns on the y-axis. + * + * @param immediateRepaint if true, a repaint event is scheduled immediately + */ + public void toggleScientificY(boolean immediateRepaint) { + m_Border.toggleDecPattern(false); + if (immediateRepaint) repaint(); + } + /** * Allows setting whether or not to paint the y-axis in logarithmic scale. * diff --git a/src/eva2/tools/chart2d/ScaledBorder.java b/src/eva2/tools/chart2d/ScaledBorder.java index 2f02f6ea..5f970420 100644 --- a/src/eva2/tools/chart2d/ScaledBorder.java +++ b/src/eva2/tools/chart2d/ScaledBorder.java @@ -1,17 +1,25 @@ package eva2.tools.chart2d; -import java.awt.* ; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Point; +import java.awt.geom.AffineTransform; +import java.text.DecimalFormat; +import java.text.NumberFormat; + import javax.swing.BorderFactory; -import javax.swing.border.* ; +import javax.swing.border.BevelBorder; +import javax.swing.border.Border; import eva2.tools.math.Mathematics; -import java.awt.geom.AffineTransform ; -import java.text.NumberFormat; -import java.text.DecimalFormat; - /** - * ScaledBorder puts an border around Components + * ScaledBorder puts a border around Components * ( especially around DrawingAreas ) with scaled and labeled axes. */ public class ScaledBorder implements Border @@ -109,6 +117,17 @@ public class ScaledBorder implements Border private NumberFormat format_x = new DecimalFormat(), format_y = new DecimalFormat(); + /** + * Possible patterns for the number formats used by a border. + */ + private String[] decPatterns = {"#,##0.###", "0.###E0"}; // standard decimal or scientific exponential + + /** + * Internal states of which decPatterns to switch to next. + */ + private int nextYPattern = 1; + private int nextXPattern = 1; + private double src_dX = -1, src_dY = -1; private boolean do_refresh, @@ -194,6 +213,9 @@ public class ScaledBorder implements Border public void paintBorder(Component c, Graphics g, int x, int y, int width, int height){ if( under_construction ) System.out.println("ScaledBorder.paintBorder()"); + +// Here one might know how much of the graph is taken by the border only and possibly switch to exponential numbering? + if( foreground == null ) foreground = c.getForeground(); if( background == null ) background = c.getBackground(); Color old_color = g.getColor(); @@ -210,9 +232,10 @@ public class ScaledBorder implements Border do_refresh = true; Insets inner_insets = getBorderInsets(c); - Dimension d = c.getSize(), - cd = new Dimension( d.width - inner_insets.left - inner_insets.right, - d.height - inner_insets.top - inner_insets.bottom ); + Dimension d = c.getSize(), + cd = new Dimension( d.width - inner_insets.left - inner_insets.right, + d.height - inner_insets.top - inner_insets.bottom ); + FontMetrics fm = g.getFontMetrics(); int fontAsc = fm.getAscent(); do_refresh = false; @@ -443,6 +466,57 @@ public class ScaledBorder implements Border return outer_border.isBorderOpaque(); } + /** + * Toggle between different decimal patterns on the axes. Basically shifts + * to the next pattern specified for this border type. + * + * @param xOrY if true toggle for the x axis otherwise for the y axis + */ + public void toggleDecPattern(boolean xOrY) { +// System.out.println("Next pattern: " + nextYPattern); + int current; + if (xOrY) { + current = nextXPattern; + nextXPattern = (nextXPattern+1) % decPatterns.length; + } else { + current = nextYPattern; + nextYPattern = (nextYPattern+1) % decPatterns.length; + } + applyPattern(xOrY, decPatterns[current]); + } + + /** + * Switch between different decimal patterns on the axes. + * The next index gives the index within the pattern list of this border type + * to switch to. + * + * @param xOrY if true toggle for the x axis otherwise for the y axis + * @param next index of the pattern to switch to + */ + protected void setNextPattern(boolean xOrY, int next) { + if (xOrY) nextXPattern=next; + else nextYPattern=next; + toggleDecPattern(xOrY); + } + + /** + * Set the standard decimal number pattern for the x or y axis. + * + * @param xOrY if true, toggle for the x axis otherwise for the y axis + */ + public void setStandardPattern(boolean xOrY) { + setNextPattern(xOrY, 0); + } + + /** + * Set the exponential number pattern for the x or y axis. + * + * @param xOrY if true, toggle for the x axis otherwise for the y axis + */ + public void setScientificPattern(boolean xOrY) { + setNextPattern(xOrY, 1); + } + /** * Apply a decimal format pattern to x (bXorY true) or y (bXorY false) axis. * @@ -456,6 +530,11 @@ public class ScaledBorder implements Border else ((java.text.DecimalFormat)format_y).applyPattern(pattern); } + /** + * This measures the space required for numberings on x and y axis and returns + * it. Depends on the decimal format applied and the FontMetrics of the + * current Graphics instance. + */ public Insets getBorderInsets(Component c){ if( under_construction ) System.out.println("ScaledBorder.getBorderInsets()"); if( !do_refresh && old_insets != null ) return old_insets; @@ -525,7 +604,3 @@ public class ScaledBorder implements Border return insets; } } - -/**************************************************************************** - * END OF FILE - ****************************************************************************/