/** * Constructs a DefaultIntervalCategoryDataset, populates it with data from the arrays, and uses * the supplied names for the series and the supplied objects for the categories. * * @param seriesKeys the series keys (if <code>null</code>, series keys will be generated * automatically). * @param categoryKeys the category keys (if <code>null</code>, category keys will be generated * automatically). * @param starts the start values data, indexed as data[series][category]. * @param ends the end values data, indexed as data[series][category]. */ public DefaultIntervalCategoryDataset( Comparable[] seriesKeys, Comparable[] categoryKeys, Number[][] starts, Number[][] ends) { this.startData = starts; this.endData = ends; if (starts != null && ends != null) { String baseName = "org.jfree.data.resources.DataPackageResources"; ResourceBundle resources = ResourceBundleWrapper.getBundle(baseName); int seriesCount = starts.length; if (seriesCount != ends.length) { String errMsg = "DefaultIntervalCategoryDataset: the number " + "of series in the start value dataset does " + "not match the number of series in the end " + "value dataset."; throw new IllegalArgumentException(errMsg); } if (seriesCount > 0) { // set up the series names... if (seriesKeys != null) { if (seriesKeys.length != seriesCount) { throw new IllegalArgumentException( "The number of series keys does not " + "match the number of series in the data."); } this.seriesKeys = seriesKeys; } else { String prefix = resources.getString("series.default-prefix") + " "; this.seriesKeys = generateKeys(seriesCount, prefix); } // set up the category names... int categoryCount = starts[0].length; if (categoryCount != ends[0].length) { String errMsg = "DefaultIntervalCategoryDataset: the " + "number of categories in the start value " + "dataset does not match the number of " + "categories in the end value dataset."; throw new IllegalArgumentException(errMsg); } if (categoryKeys != null) { if (categoryKeys.length != categoryCount) { throw new IllegalArgumentException( "The number of category keys does not match " + "the number of categories in the data."); } this.categoryKeys = categoryKeys; } else { String prefix = resources.getString("categories.default-prefix") + " "; this.categoryKeys = generateKeys(categoryCount, prefix); } } else { this.seriesKeys = new Comparable[0]; this.categoryKeys = new Comparable[0]; } } }
/** A wafer map plot. */ public class WaferMapPlot extends Plot implements RendererChangeListener, Cloneable, Serializable { /** For serialization. */ private static final long serialVersionUID = 4668320403707308155L; /** The default grid line stroke. */ public static final Stroke DEFAULT_GRIDLINE_STROKE = new BasicStroke( 0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0.0f, new float[] {2.0f, 2.0f}, 0.0f); /** The default grid line paint. */ public static final Paint DEFAULT_GRIDLINE_PAINT = Color.lightGray; /** The default crosshair visibility. */ public static final boolean DEFAULT_CROSSHAIR_VISIBLE = false; /** The default crosshair stroke. */ public static final Stroke DEFAULT_CROSSHAIR_STROKE = DEFAULT_GRIDLINE_STROKE; /** The default crosshair paint. */ public static final Paint DEFAULT_CROSSHAIR_PAINT = Color.blue; /** The resourceBundle for the localization. */ protected static ResourceBundle localizationResources = ResourceBundleWrapper.getBundle("org.jfree.chart.plot.LocalizationBundle"); /** The plot orientation. vertical = notch down horizontal = notch right */ private PlotOrientation orientation; /** The dataset. */ private WaferMapDataset dataset; /** Object responsible for drawing the visual representation of each point on the plot. */ private WaferMapRenderer renderer; /** Creates a new plot with no dataset. */ public WaferMapPlot() { this(null); } /** * Creates a new plot. * * @param dataset the dataset (<code>null</code> permitted). */ public WaferMapPlot(WaferMapDataset dataset) { this(dataset, null); } /** * Creates a new plot. * * @param dataset the dataset (<code>null</code> permitted). * @param renderer the renderer (<code>null</code> permitted). */ public WaferMapPlot(WaferMapDataset dataset, WaferMapRenderer renderer) { super(); this.orientation = PlotOrientation.VERTICAL; this.dataset = dataset; if (dataset != null) { dataset.addChangeListener(this); } this.renderer = renderer; if (renderer != null) { renderer.setPlot(this); renderer.addChangeListener(this); } } /** * Returns the plot type as a string. * * @return A short string describing the type of plot. */ @Override public String getPlotType() { return ("WMAP_Plot"); } /** * Returns the dataset * * @return The dataset (possibly <code>null</code>). */ public WaferMapDataset getDataset() { return this.dataset; } /** * Sets the dataset used by the plot and sends a {@link PlotChangeEvent} to all registered * listeners. * * @param dataset the dataset (<code>null</code> permitted). */ public void setDataset(WaferMapDataset dataset) { // if there is an existing dataset, remove the plot from the list of // change listeners... if (this.dataset != null) { this.dataset.removeChangeListener(this); } // set the new dataset, and register the chart as a change listener... this.dataset = dataset; if (dataset != null) { setDatasetGroup(dataset.getGroup()); dataset.addChangeListener(this); } // send a dataset change event to self to trigger plot change event datasetChanged(new DatasetChangeEvent(this, dataset)); } /** * Sets the item renderer, and notifies all listeners of a change to the plot. If the renderer is * set to <code>null</code>, no chart will be drawn. * * @param renderer the new renderer (<code>null</code> permitted). */ public void setRenderer(WaferMapRenderer renderer) { if (this.renderer != null) { this.renderer.removeChangeListener(this); } this.renderer = renderer; if (renderer != null) { renderer.setPlot(this); } fireChangeEvent(); } /** * Draws the wafermap view. * * @param g2 the graphics device. * @param area the plot area. * @param anchor the anchor point (<code>null</code> permitted). * @param state the plot state. * @param info the plot rendering info. */ @Override public void draw( Graphics2D g2, Rectangle2D area, Point2D anchor, PlotState state, PlotRenderingInfo info) { // if the plot area is too small, just return... boolean b1 = (area.getWidth() <= MINIMUM_WIDTH_TO_DRAW); boolean b2 = (area.getHeight() <= MINIMUM_HEIGHT_TO_DRAW); if (b1 || b2) { return; } // record the plot area... if (info != null) { info.setPlotArea(area); } // adjust the drawing area for the plot insets (if any)... RectangleInsets insets = getInsets(); insets.trim(area); dataset.drawChipGrid(g2, area, renderer, this); drawWaferEdge(g2, area); } /** * Calculates the location of the waferedge. * * @param plotArea the plot area. * @return The wafer edge. */ public Ellipse2D getWaferEdge(Rectangle2D plotArea) { Ellipse2D edge = new Ellipse2D.Double(); double diameter = plotArea.getWidth(); double upperLeftX = plotArea.getX(); double upperLeftY = plotArea.getY(); // get major dimension if (plotArea.getWidth() != plotArea.getHeight()) { double major, minor; if (plotArea.getWidth() > plotArea.getHeight()) { major = plotArea.getWidth(); minor = plotArea.getHeight(); } else { major = plotArea.getHeight(); minor = plotArea.getWidth(); } // ellipse diameter is the minor dimension diameter = minor; // set upperLeft point if (plotArea.getWidth() == minor) { // x is minor upperLeftY = plotArea.getY() + (major - minor) / 2; } else { // y is minor upperLeftX = plotArea.getX() + (major - minor) / 2; } } edge.setFrame(upperLeftX, upperLeftY, diameter, diameter); return edge; } /** * Draws the waferedge, including the notch. * * @param g2 the graphics device. * @param plotArea the plot area. */ protected void drawWaferEdge(Graphics2D g2, Rectangle2D plotArea) { // draw the wafer Ellipse2D waferEdge = getWaferEdge(plotArea); g2.setColor(Color.black); g2.draw(waferEdge); // calculate and draw the notch // horizontal orientation is considered notch right // vertical orientation is considered notch down Arc2D notch; Rectangle2D waferFrame = waferEdge.getFrame(); double notchDiameter = waferFrame.getWidth() * 0.04; if (this.orientation == PlotOrientation.HORIZONTAL) { Rectangle2D notchFrame = new Rectangle2D.Double( waferFrame.getX() + waferFrame.getWidth() - (notchDiameter / 2), waferFrame.getY() + (waferFrame.getHeight() / 2) - (notchDiameter / 2), notchDiameter, notchDiameter); notch = new Arc2D.Double(notchFrame, 90d, 180d, Arc2D.OPEN); } else { Rectangle2D notchFrame = new Rectangle2D.Double( waferFrame.getX() + (waferFrame.getWidth() / 2) - (notchDiameter / 2), waferFrame.getY() + waferFrame.getHeight() - (notchDiameter / 2), notchDiameter, notchDiameter); notch = new Arc2D.Double(notchFrame, 0d, 180d, Arc2D.OPEN); } g2.setColor(Color.white); g2.fill(notch); g2.setColor(Color.black); g2.draw(notch); } /** * Return the legend items from the renderer. * * @return The legend items. */ @Override public LegendItemCollection getLegendItems() { return this.renderer.getLegendCollection(); } /** * Notifies all registered listeners of a renderer change. * * @param event the event. */ @Override public void rendererChanged(RendererChangeEvent event) { fireChangeEvent(); } public void createPlotPanel(DefaultPlotEditor defaultPlotEditor) {} public void updatePlotProperties(DefaultPlotEditor defaultPlotEditor) {} public void applyToPlot(StandardChartTheme standardChartTheme) {} }
/** A panel for editing the properties of an axis. */ class DefaultAxisEditor extends JPanel implements ActionListener { /** The axis label. */ private JTextField label; /** The label font. */ private Font labelFont; /** The label paint. */ private PaintSample labelPaintSample; /** A field showing a description of the label font. */ private JTextField labelFontField; /** The font for displaying tick labels on the axis. */ private Font tickLabelFont; /** A field containing a description of the font for displaying tick labels on the axis. */ private JTextField tickLabelFontField; /** The paint (color) for the tick labels. */ private PaintSample tickLabelPaintSample; /** An empty sub-panel for extending the user interface to handle more complex axes. */ private JPanel slot1; /** An empty sub-panel for extending the user interface to handle more complex axes. */ private JPanel slot2; /** A flag that indicates whether or not the tick labels are visible. */ private JCheckBox showTickLabelsCheckBox; /** A flag that indicates whether or not the tick marks are visible. */ private JCheckBox showTickMarksCheckBox; // /** Insets text field. */ // private InsetsTextField tickLabelInsetsTextField; // // /** Label insets text field. */ // private InsetsTextField labelInsetsTextField; /** The tick label insets. */ private RectangleInsets tickLabelInsets; /** The label insets. */ private RectangleInsets labelInsets; /** A tabbed pane for... */ private JTabbedPane otherTabs; /** The resourceBundle for the localization. */ protected static ResourceBundle localizationResources = ResourceBundleWrapper.getBundle("org.jfree.chart.editor.LocalizationBundle"); /** * A static method that returns a panel that is appropriate for the axis type. * * @param axis the axis whose properties are to be displayed/edited in the panel. * @return A panel or <code>null</code< if axis is <code>null</code>. */ public static DefaultAxisEditor getInstance(Axis axis) { if (axis != null) { // figure out what type of axis we have and instantiate the // appropriate panel if (axis instanceof NumberAxis) { return new DefaultNumberAxisEditor((NumberAxis) axis); } if (axis instanceof LogAxis) { return new DefaultLogAxisEditor((LogAxis) axis); } else { return new DefaultAxisEditor(axis); } } else { return null; } } /** * Standard constructor: builds a panel for displaying/editing the properties of the specified * axis. * * @param axis the axis whose properties are to be displayed/edited in the panel. */ public DefaultAxisEditor(Axis axis) { this.labelFont = axis.getLabelFont(); this.labelPaintSample = new PaintSample(axis.getLabelPaint()); this.tickLabelFont = axis.getTickLabelFont(); this.tickLabelPaintSample = new PaintSample(axis.getTickLabelPaint()); // Insets values this.tickLabelInsets = axis.getTickLabelInsets(); this.labelInsets = axis.getLabelInsets(); setLayout(new BorderLayout()); JPanel general = new JPanel(new BorderLayout()); general.setBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), localizationResources.getString("General"))); JPanel interior = new JPanel(new LCBLayout(5)); interior.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); interior.add(new JLabel(localizationResources.getString("Label"))); this.label = new JTextField(axis.getLabel()); interior.add(this.label); interior.add(new JPanel()); interior.add(new JLabel(localizationResources.getString("Font"))); this.labelFontField = new FontDisplayField(this.labelFont); interior.add(this.labelFontField); JButton b = new JButton(localizationResources.getString("Select...")); b.setActionCommand("SelectLabelFont"); b.addActionListener(this); interior.add(b); interior.add(new JLabel(localizationResources.getString("Paint"))); interior.add(this.labelPaintSample); b = new JButton(localizationResources.getString("Select...")); b.setActionCommand("SelectLabelPaint"); b.addActionListener(this); interior.add(b); // interior.add( // new JLabel(localizationResources.getString("Label_Insets")) // ); // b = new JButton(localizationResources.getString("Edit...")); // b.setActionCommand("LabelInsets"); // b.addActionListener(this); // this.labelInsetsTextField = new InsetsTextField(this.labelInsets); // interior.add(this.labelInsetsTextField); // interior.add(b); // // interior.add( // new JLabel(localizationResources.getString("Tick_Label_Insets")) // ); // b = new JButton(localizationResources.getString("Edit...")); // b.setActionCommand("TickLabelInsets"); // b.addActionListener(this); // this.tickLabelInsetsTextField // = new InsetsTextField(this.tickLabelInsets); // interior.add(this.tickLabelInsetsTextField); // interior.add(b); general.add(interior); add(general, BorderLayout.NORTH); this.slot1 = new JPanel(new BorderLayout()); JPanel other = new JPanel(new BorderLayout()); other.setBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), localizationResources.getString("Other"))); this.otherTabs = new JTabbedPane(); this.otherTabs.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); JPanel ticks = new JPanel(new LCBLayout(3)); ticks.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); this.showTickLabelsCheckBox = new JCheckBox( localizationResources.getString("Show_tick_labels"), axis.isTickLabelsVisible()); ticks.add(this.showTickLabelsCheckBox); ticks.add(new JPanel()); ticks.add(new JPanel()); ticks.add(new JLabel(localizationResources.getString("Tick_label_font"))); this.tickLabelFontField = new FontDisplayField(this.tickLabelFont); ticks.add(this.tickLabelFontField); b = new JButton(localizationResources.getString("Select...")); b.setActionCommand("SelectTickLabelFont"); b.addActionListener(this); ticks.add(b); this.showTickMarksCheckBox = new JCheckBox( localizationResources.getString("Show_tick_marks"), axis.isTickMarksVisible()); ticks.add(this.showTickMarksCheckBox); ticks.add(new JPanel()); ticks.add(new JPanel()); this.otherTabs.add(localizationResources.getString("Ticks"), ticks); other.add(this.otherTabs); this.slot1.add(other); this.slot2 = new JPanel(new BorderLayout()); this.slot2.add(this.slot1, BorderLayout.NORTH); add(this.slot2); } /** * Returns the current axis label. * * @return The current axis label. */ public String getLabel() { return this.label.getText(); } /** * Returns the current label font. * * @return The current label font. */ public Font getLabelFont() { return this.labelFont; } /** * Returns the current label paint. * * @return The current label paint. */ public Paint getLabelPaint() { return this.labelPaintSample.getPaint(); } /** * Returns a flag that indicates whether or not the tick labels are visible. * * @return <code>true</code> if ick mark labels are visible. */ public boolean isTickLabelsVisible() { return this.showTickLabelsCheckBox.isSelected(); } /** * Returns the font used to draw the tick labels (if they are showing). * * @return The font used to draw the tick labels. */ public Font getTickLabelFont() { return this.tickLabelFont; } /** * Returns the current tick label paint. * * @return The current tick label paint. */ public Paint getTickLabelPaint() { return this.tickLabelPaintSample.getPaint(); } /** * Returns the current value of the flag that determines whether or not tick marks are visible. * * @return <code>true</code> if tick marks are visible. */ public boolean isTickMarksVisible() { return this.showTickMarksCheckBox.isSelected(); } /** * Returns the current tick label insets value * * @return The current tick label insets value. */ public RectangleInsets getTickLabelInsets() { return (this.tickLabelInsets == null) ? new RectangleInsets(0, 0, 0, 0) : this.tickLabelInsets; } /** * Returns the current label insets value * * @return The current label insets value. */ public RectangleInsets getLabelInsets() { return (this.labelInsets == null) ? new RectangleInsets(0, 0, 0, 0) : this.labelInsets; } /** * Returns a reference to the tabbed pane. * * @return A reference to the tabbed pane. */ public JTabbedPane getOtherTabs() { return this.otherTabs; } /** * Handles user interaction with the property panel. * * @param event information about the event that triggered the call to this method. */ public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (command.equals("SelectLabelFont")) { attemptLabelFontSelection(); } else if (command.equals("SelectLabelPaint")) { attemptModifyLabelPaint(); } else if (command.equals("SelectTickLabelFont")) { attemptTickLabelFontSelection(); } // else if (command.equals("LabelInsets")) { // editLabelInsets(); // } // else if (command.equals("TickLabelInsets")) { // editTickLabelInsets(); // } } /** Presents a font selection dialog to the user. */ private void attemptLabelFontSelection() { FontChooserPanel panel = new FontChooserPanel(this.labelFont); int result = JOptionPane.showConfirmDialog( this, panel, localizationResources.getString("Font_Selection"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (result == JOptionPane.OK_OPTION) { this.labelFont = panel.getSelectedFont(); this.labelFontField.setText(this.labelFont.getFontName() + " " + this.labelFont.getSize()); } } /** Allows the user the opportunity to change the outline paint. */ private void attemptModifyLabelPaint() { Color c; c = JColorChooser.showDialog(this, localizationResources.getString("Label_Color"), Color.blue); if (c != null) { this.labelPaintSample.setPaint(c); } } /** Presents a tick label font selection dialog to the user. */ public void attemptTickLabelFontSelection() { FontChooserPanel panel = new FontChooserPanel(this.tickLabelFont); int result = JOptionPane.showConfirmDialog( this, panel, localizationResources.getString("Font_Selection"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (result == JOptionPane.OK_OPTION) { this.tickLabelFont = panel.getSelectedFont(); this.tickLabelFontField.setText( this.tickLabelFont.getFontName() + " " + this.tickLabelFont.getSize()); } } // /** // * Presents insets chooser panel allowing user to modify tick label's // * individual insets values. Updates the current insets text field if // * edit is accepted. // */ // private void editTickLabelInsets() { // InsetsChooserPanel panel = new InsetsChooserPanel( // this.tickLabelInsets); // int result = JOptionPane.showConfirmDialog( // this, panel, localizationResources.getString("Edit_Insets"), // JOptionPane.PLAIN_MESSAGE // ); // // if (result == JOptionPane.OK_OPTION) { // this.tickLabelInsets = panel.getInsets(); // this.tickLabelInsetsTextField.setInsets(this.tickLabelInsets); // } // } // // /** // * Presents insets chooser panel allowing user to modify label's // * individual insets values. Updates the current insets text field if edit // * is accepted. // */ // private void editLabelInsets() { // InsetsChooserPanel panel = new InsetsChooserPanel(this.labelInsets); // int result = JOptionPane.showConfirmDialog( // this, panel, localizationResources.getString("Edit_Insets"), // JOptionPane.PLAIN_MESSAGE // ); // // if (result == JOptionPane.OK_OPTION) { // this.labelInsets = panel.getInsets(); // this.labelInsetsTextField.setInsets(this.labelInsets); // } // } /** * Sets the properties of the specified axis to match the properties defined on this panel. * * @param axis the axis. */ public void setAxisProperties(Axis axis) { axis.setLabel(getLabel()); axis.setLabelFont(getLabelFont()); axis.setLabelPaint(getLabelPaint()); axis.setTickMarksVisible(isTickMarksVisible()); // axis.setTickMarkStroke(getTickMarkStroke()); axis.setTickLabelsVisible(isTickLabelsVisible()); axis.setTickLabelFont(getTickLabelFont()); axis.setTickLabelPaint(getTickLabelPaint()); axis.setTickLabelInsets(getTickLabelInsets()); axis.setLabelInsets(getLabelInsets()); } }
/** A panel for editing properties of a {@link ValueAxis}. */ class DefaultValueAxisEditor extends DefaultAxisEditor implements FocusListener { /** A flag that indicates whether or not the axis range is determined automatically. */ private boolean autoRange; /** Flag if auto-tickunit-selection is enabled. */ private boolean autoTickUnitSelection; /** The lowest value in the axis range. */ private double minimumValue; /** The highest value in the axis range. */ private double maximumValue; /** A checkbox that indicates whether or not the axis range is determined automatically. */ private JCheckBox autoRangeCheckBox; /** A check-box enabling/disabling auto-tickunit-selection. */ private JCheckBox autoTickUnitSelectionCheckBox; /** A text field for entering the minimum value in the axis range. */ private JTextField minimumRangeValue; /** A text field for entering the maximum value in the axis range. */ private JTextField maximumRangeValue; /** The paint selected for drawing the gridlines. */ private PaintSample gridPaintSample; /** The stroke selected for drawing the gridlines. */ private StrokeSample gridStrokeSample; /** * An array of stroke samples to choose from (since I haven't written a decent StrokeChooser * component yet). */ private StrokeSample[] availableStrokeSamples; /** The resourceBundle for the localization. */ protected static ResourceBundle localizationResources = ResourceBundleWrapper.getBundle("org.jfree.chart.editor.LocalizationBundle"); /** * Standard constructor: builds a property panel for the specified axis. * * @param axis the axis, which should be changed. */ public DefaultValueAxisEditor(ValueAxis axis) { super(axis); this.autoRange = axis.isAutoRange(); this.minimumValue = axis.getLowerBound(); this.maximumValue = axis.getUpperBound(); this.autoTickUnitSelection = axis.isAutoTickUnitSelection(); this.gridPaintSample = new PaintSample(Color.blue); this.gridStrokeSample = new StrokeSample(new BasicStroke(1.0f)); this.availableStrokeSamples = new StrokeSample[3]; this.availableStrokeSamples[0] = new StrokeSample(new BasicStroke(1.0f)); this.availableStrokeSamples[1] = new StrokeSample(new BasicStroke(2.0f)); this.availableStrokeSamples[2] = new StrokeSample(new BasicStroke(3.0f)); JTabbedPane other = getOtherTabs(); JPanel range = new JPanel(new LCBLayout(3)); range.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); range.add(new JPanel()); this.autoRangeCheckBox = new JCheckBox(localizationResources.getString("Auto-adjust_range"), this.autoRange); this.autoRangeCheckBox.setActionCommand("AutoRangeOnOff"); this.autoRangeCheckBox.addActionListener(this); range.add(this.autoRangeCheckBox); range.add(new JPanel()); range.add(new JLabel(localizationResources.getString("Minimum_range_value"))); this.minimumRangeValue = new JTextField(Double.toString(this.minimumValue)); this.minimumRangeValue.setEnabled(!this.autoRange); this.minimumRangeValue.setActionCommand("MinimumRange"); this.minimumRangeValue.addActionListener(this); this.minimumRangeValue.addFocusListener(this); range.add(this.minimumRangeValue); range.add(new JPanel()); range.add(new JLabel(localizationResources.getString("Maximum_range_value"))); this.maximumRangeValue = new JTextField(Double.toString(this.maximumValue)); this.maximumRangeValue.setEnabled(!this.autoRange); this.maximumRangeValue.setActionCommand("MaximumRange"); this.maximumRangeValue.addActionListener(this); this.maximumRangeValue.addFocusListener(this); range.add(this.maximumRangeValue); range.add(new JPanel()); other.add(localizationResources.getString("Range"), range); other.add(localizationResources.getString("TickUnit"), createTickUnitPanel()); } protected JPanel createTickUnitPanel() { JPanel tickUnitPanel = new JPanel(new LCBLayout(3)); tickUnitPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); tickUnitPanel.add(new JPanel()); this.autoTickUnitSelectionCheckBox = new JCheckBox( localizationResources.getString("Auto-TickUnit_Selection"), this.autoTickUnitSelection); this.autoTickUnitSelectionCheckBox.setActionCommand("AutoTickOnOff"); this.autoTickUnitSelectionCheckBox.addActionListener(this); tickUnitPanel.add(this.autoTickUnitSelectionCheckBox); tickUnitPanel.add(new JPanel()); return tickUnitPanel; } /** * Getter for the {@link #autoTickUnitSelection} flag. * * @return The value of the flag for enabling auto-tickunit-selection. */ protected boolean isAutoTickUnitSelection() { return autoTickUnitSelection; } /** * Setter for the {@link #autoTickUnitSelection} flag. * * @param autoTickUnitSelection The new value for auto-tickunit-selection. */ protected void setAutoTickUnitSelection(boolean autoTickUnitSelection) { this.autoTickUnitSelection = autoTickUnitSelection; } /** * Get the checkbox that enables/disables auto-tickunit-selection. * * @return The checkbox. */ protected JCheckBox getAutoTickUnitSelectionCheckBox() { return autoTickUnitSelectionCheckBox; } /** * Set the checkbox that enables/disables auto-tickunit-selection. * * @param autoTickUnitSelectionCheckBox The checkbox. */ protected void setAutoTickUnitSelectionCheckBox(JCheckBox autoTickUnitSelectionCheckBox) { this.autoTickUnitSelectionCheckBox = autoTickUnitSelectionCheckBox; } /** * Returns the current setting of the auto-range property. * * @return <code>true</code> if auto range is enabled. */ public boolean isAutoRange() { return this.autoRange; } /** * Returns the current setting of the minimum value in the axis range. * * @return The current setting of the minimum value in the axis range. */ public double getMinimumValue() { return this.minimumValue; } /** * Returns the current setting of the maximum value in the axis range. * * @return The current setting of the maximum value in the axis range. */ public double getMaximumValue() { return this.maximumValue; } /** * Handles actions from within the property panel. * * @param event an event. */ public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (command.equals("GridStroke")) { attemptGridStrokeSelection(); } else if (command.equals("GridPaint")) { attemptGridPaintSelection(); } else if (command.equals("AutoRangeOnOff")) { toggleAutoRange(); } else if (command.equals("MinimumRange")) { validateMinimum(); } else if (command.equals("MaximumRange")) { validateMaximum(); } else if (command.equals("AutoTickOnOff")) { toggleAutoTick(); } else { // pass to the super-class for handling super.actionPerformed(event); } } /** Handle a grid stroke selection. */ protected void attemptGridStrokeSelection() { StrokeChooserPanel panel = new StrokeChooserPanel(this.gridStrokeSample, this.availableStrokeSamples); int result = JOptionPane.showConfirmDialog( this, panel, localizationResources.getString("Stroke_Selection"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (result == JOptionPane.OK_OPTION) { this.gridStrokeSample.setStroke(panel.getSelectedStroke()); } } /** Handle a grid paint selection. */ protected void attemptGridPaintSelection() { Color c; c = JColorChooser.showDialog(this, localizationResources.getString("Grid_Color"), Color.blue); if (c != null) { this.gridPaintSample.setPaint(c); } } /** * Does nothing. * * @param event the event. */ public void focusGained(FocusEvent event) { // don't need to do anything } /** * Revalidates minimum/maximum range. * * @param event the event. */ public void focusLost(FocusEvent event) { if (event.getSource() == this.minimumRangeValue) { validateMinimum(); } else if (event.getSource() == this.maximumRangeValue) { validateMaximum(); } } /** Toggle the auto range setting. */ public void toggleAutoRange() { this.autoRange = this.autoRangeCheckBox.isSelected(); if (this.autoRange) { this.minimumRangeValue.setText(Double.toString(this.minimumValue)); this.minimumRangeValue.setEnabled(false); this.maximumRangeValue.setText(Double.toString(this.maximumValue)); this.maximumRangeValue.setEnabled(false); } else { this.minimumRangeValue.setEnabled(true); this.maximumRangeValue.setEnabled(true); } } public void toggleAutoTick() { this.autoTickUnitSelection = this.autoTickUnitSelectionCheckBox.isSelected(); } /** Revalidate the range minimum. */ public void validateMinimum() { double newMin; try { newMin = Double.parseDouble(this.minimumRangeValue.getText()); if (newMin >= this.maximumValue) { newMin = this.minimumValue; } } catch (NumberFormatException e) { newMin = this.minimumValue; } this.minimumValue = newMin; this.minimumRangeValue.setText(Double.toString(this.minimumValue)); } /** Revalidate the range maximum. */ public void validateMaximum() { double newMax; try { newMax = Double.parseDouble(this.maximumRangeValue.getText()); if (newMax <= this.minimumValue) { newMax = this.maximumValue; } } catch (NumberFormatException e) { newMax = this.maximumValue; } this.maximumValue = newMax; this.maximumRangeValue.setText(Double.toString(this.maximumValue)); } /** * Sets the properties of the specified axis to match the properties defined on this panel. * * @param axis the axis. */ public void setAxisProperties(Axis axis) { super.setAxisProperties(axis); ValueAxis valueAxis = (ValueAxis) axis; valueAxis.setAutoRange(this.autoRange); if (!this.autoRange) { valueAxis.setRange(this.minimumValue, this.maximumValue); } valueAxis.setAutoTickUnitSelection(this.autoTickUnitSelection); } }
/** A panel for editing the properties of a {@link Plot}. */ class DefaultPlotEditor extends JPanel implements ActionListener { /** Orientation constants. */ private static final String[] orientationNames = {"Vertical", "Horizontal"}; private static final int ORIENTATION_VERTICAL = 0; private static final int ORIENTATION_HORIZONTAL = 1; /** The paint (color) used to fill the background of the plot. */ private PaintSample backgroundPaintSample; /** The stroke used to draw the outline of the plot. */ private StrokeSample outlineStrokeSample; /** The paint (color) used to draw the outline of the plot. */ private PaintSample outlinePaintSample; /** A panel used to display/edit the properties of the domain axis (if any). */ private DefaultAxisEditor domainAxisPropertyPanel; /** A panel used to display/edit the properties of the range axis (if any). */ private DefaultAxisEditor rangeAxisPropertyPanel; /** A panel used to display/edit the properties of the colorbar axis (if any). */ private DefaultColorBarEditor colorBarAxisPropertyPanel; /** An array of stroke samples to choose from. */ private StrokeSample[] availableStrokeSamples; /** The insets for the plot. */ private RectangleInsets plotInsets; /** The orientation for the plot (for <tt>CategoryPlot</tt>s and <tt>XYPlot</tt>s). */ private PlotOrientation plotOrientation; /** The orientation combo box (for <tt>CategoryPlot</tt>s and <tt>XYPlot</tt>s). */ private JComboBox orientationCombo; /** * Whether or not to draw lines between each data point (for <tt>LineAndShapeRenderer</tt>s and * <tt>StandardXYItemRenderer</tt>s). */ private Boolean drawLines; /** The checkbox for whether or not to draw lines between each data point. */ private JCheckBox drawLinesCheckBox; /** * Whether or not to draw shapes at each data point (for <tt>LineAndShapeRenderer</tt>s and * <tt>StandardXYItemRenderer</tt>s). */ private Boolean drawShapes; /** The checkbox for whether or not to draw shapes at each data point. */ private JCheckBox drawShapesCheckBox; /** The resourceBundle for the localization. */ protected static ResourceBundle localizationResources = ResourceBundleWrapper.getBundle("org.jfree.chart.editor.LocalizationBundle"); /** * Standard constructor - constructs a panel for editing the properties of the specified plot. * * <p>In designing the panel, we need to be aware that subclasses of Plot will need to implement * subclasses of PlotPropertyEditPanel - so we need to leave one or two 'slots' where the * subclasses can extend the user interface. * * @param plot the plot, which should be changed. */ public DefaultPlotEditor(Plot plot) { JPanel panel = createPlotPanel(plot); add(panel); } protected JPanel createPlotPanel(Plot plot) { this.plotInsets = plot.getInsets(); this.backgroundPaintSample = new PaintSample(plot.getBackgroundPaint()); this.outlineStrokeSample = new StrokeSample(plot.getOutlineStroke()); this.outlinePaintSample = new PaintSample(plot.getOutlinePaint()); if (plot instanceof CategoryPlot) { this.plotOrientation = ((CategoryPlot) plot).getOrientation(); } else if (plot instanceof XYPlot) { this.plotOrientation = ((XYPlot) plot).getOrientation(); } if (plot instanceof CategoryPlot) { CategoryItemRenderer renderer = ((CategoryPlot) plot).getRenderer(); if (renderer instanceof LineAndShapeRenderer) { LineAndShapeRenderer r = (LineAndShapeRenderer) renderer; this.drawLines = BooleanUtilities.valueOf(r.getBaseLinesVisible()); this.drawShapes = BooleanUtilities.valueOf(r.getBaseShapesVisible()); } } else if (plot instanceof XYPlot) { XYItemRenderer renderer = ((XYPlot) plot).getRenderer(); if (renderer instanceof StandardXYItemRenderer) { StandardXYItemRenderer r = (StandardXYItemRenderer) renderer; this.drawLines = BooleanUtilities.valueOf(r.getPlotLines()); this.drawShapes = BooleanUtilities.valueOf(r.getBaseShapesVisible()); } } setLayout(new BorderLayout()); this.availableStrokeSamples = new StrokeSample[4]; this.availableStrokeSamples[0] = new StrokeSample(null); this.availableStrokeSamples[1] = new StrokeSample(new BasicStroke(1.0f)); this.availableStrokeSamples[2] = new StrokeSample(new BasicStroke(2.0f)); this.availableStrokeSamples[3] = new StrokeSample(new BasicStroke(3.0f)); // create a panel for the settings... JPanel panel = new JPanel(new BorderLayout()); panel.setBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), plot.getPlotType() + localizationResources.getString(":"))); JPanel general = new JPanel(new BorderLayout()); general.setBorder(BorderFactory.createTitledBorder(localizationResources.getString("General"))); JPanel interior = new JPanel(new LCBLayout(7)); interior.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); // interior.add(new JLabel(localizationResources.getString("Insets"))); // JButton button = new JButton( // localizationResources.getString("Edit...") // ); // button.setActionCommand("Insets"); // button.addActionListener(this); // // this.insetsTextField = new InsetsTextField(this.plotInsets); // this.insetsTextField.setEnabled(false); // interior.add(this.insetsTextField); // interior.add(button); interior.add(new JLabel(localizationResources.getString("Outline_stroke"))); JButton button = new JButton(localizationResources.getString("Select...")); button.setActionCommand("OutlineStroke"); button.addActionListener(this); interior.add(this.outlineStrokeSample); interior.add(button); interior.add(new JLabel(localizationResources.getString("Outline_Paint"))); button = new JButton(localizationResources.getString("Select...")); button.setActionCommand("OutlinePaint"); button.addActionListener(this); interior.add(this.outlinePaintSample); interior.add(button); interior.add(new JLabel(localizationResources.getString("Background_paint"))); button = new JButton(localizationResources.getString("Select...")); button.setActionCommand("BackgroundPaint"); button.addActionListener(this); interior.add(this.backgroundPaintSample); interior.add(button); if (this.plotOrientation != null) { boolean isVertical = this.plotOrientation.equals(PlotOrientation.VERTICAL); int index = isVertical ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL; interior.add(new JLabel(localizationResources.getString("Orientation"))); this.orientationCombo = new JComboBox(orientationNames); this.orientationCombo.setSelectedIndex(index); this.orientationCombo.setActionCommand("Orientation"); this.orientationCombo.addActionListener(this); interior.add(new JPanel()); interior.add(this.orientationCombo); } if (this.drawLines != null) { interior.add(new JLabel(localizationResources.getString("Draw_lines"))); this.drawLinesCheckBox = new JCheckBox(); this.drawLinesCheckBox.setSelected(this.drawLines.booleanValue()); this.drawLinesCheckBox.setActionCommand("DrawLines"); this.drawLinesCheckBox.addActionListener(this); interior.add(new JPanel()); interior.add(this.drawLinesCheckBox); } if (this.drawShapes != null) { interior.add(new JLabel(localizationResources.getString("Draw_shapes"))); this.drawShapesCheckBox = new JCheckBox(); this.drawShapesCheckBox.setSelected(this.drawShapes.booleanValue()); this.drawShapesCheckBox.setActionCommand("DrawShapes"); this.drawShapesCheckBox.addActionListener(this); interior.add(new JPanel()); interior.add(this.drawShapesCheckBox); } general.add(interior, BorderLayout.NORTH); JPanel appearance = new JPanel(new BorderLayout()); appearance.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); appearance.add(general, BorderLayout.NORTH); JTabbedPane tabs = createPlotTabs(plot); tabs.add(localizationResources.getString("Appearance"), appearance); panel.add(tabs); return panel; } protected JTabbedPane createPlotTabs(Plot plot) { JTabbedPane tabs = new JTabbedPane(); tabs.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); Axis domainAxis = null; if (plot instanceof CategoryPlot) { domainAxis = ((CategoryPlot) plot).getDomainAxis(); } else if (plot instanceof XYPlot) { domainAxis = ((XYPlot) plot).getDomainAxis(); } this.domainAxisPropertyPanel = DefaultAxisEditor.getInstance(domainAxis); if (this.domainAxisPropertyPanel != null) { this.domainAxisPropertyPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); tabs.add(localizationResources.getString("Domain_Axis"), this.domainAxisPropertyPanel); } Axis rangeAxis = null; if (plot instanceof CategoryPlot) { rangeAxis = ((CategoryPlot) plot).getRangeAxis(); } else if (plot instanceof XYPlot) { rangeAxis = ((XYPlot) plot).getRangeAxis(); } else if (plot instanceof PolarPlot) { rangeAxis = ((PolarPlot) plot).getAxis(); } this.rangeAxisPropertyPanel = DefaultAxisEditor.getInstance(rangeAxis); if (this.rangeAxisPropertyPanel != null) { this.rangeAxisPropertyPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); tabs.add(localizationResources.getString("Range_Axis"), this.rangeAxisPropertyPanel); } // dmo: added this panel for colorbar control. (start dmo additions) ColorBar colorBar = null; if (plot instanceof ContourPlot) { colorBar = ((ContourPlot) plot).getColorBar(); } this.colorBarAxisPropertyPanel = DefaultColorBarEditor.getInstance(colorBar); if (this.colorBarAxisPropertyPanel != null) { this.colorBarAxisPropertyPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); tabs.add(localizationResources.getString("Color_Bar"), this.colorBarAxisPropertyPanel); } // dmo: (end dmo additions) return tabs; } /** * Returns the current plot insets. * * @return The current plot insets. */ public RectangleInsets getPlotInsets() { if (this.plotInsets == null) { this.plotInsets = new RectangleInsets(0.0, 0.0, 0.0, 0.0); } return this.plotInsets; } /** * Returns the current background paint. * * @return The current background paint. */ public Paint getBackgroundPaint() { return this.backgroundPaintSample.getPaint(); } /** * Returns the current outline stroke. * * @return The current outline stroke (possibly <code>null</code>). */ public Stroke getOutlineStroke() { return this.outlineStrokeSample.getStroke(); } /** * Returns the current outline paint. * * @return The current outline paint. */ public Paint getOutlinePaint() { return this.outlinePaintSample.getPaint(); } /** * Returns a reference to the panel for editing the properties of the domain axis. * * @return A reference to a panel. */ public DefaultAxisEditor getDomainAxisPropertyEditPanel() { return this.domainAxisPropertyPanel; } /** * Returns a reference to the panel for editing the properties of the range axis. * * @return A reference to a panel. */ public DefaultAxisEditor getRangeAxisPropertyEditPanel() { return this.rangeAxisPropertyPanel; } /** * Handles user actions generated within the panel. * * @param event the event */ @Override public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (command.equals("BackgroundPaint")) { attemptBackgroundPaintSelection(); } else if (command.equals("OutlineStroke")) { attemptOutlineStrokeSelection(); } else if (command.equals("OutlinePaint")) { attemptOutlinePaintSelection(); } // else if (command.equals("Insets")) { // editInsets(); // } else if (command.equals("Orientation")) { attemptOrientationSelection(); } else if (command.equals("DrawLines")) { attemptDrawLinesSelection(); } else if (command.equals("DrawShapes")) { attemptDrawShapesSelection(); } } /** Allow the user to change the background paint. */ private void attemptBackgroundPaintSelection() { Color c; c = JColorChooser.showDialog( this, localizationResources.getString("Background_Color"), Color.blue); if (c != null) { this.backgroundPaintSample.setPaint(c); } } /** Allow the user to change the outline stroke. */ private void attemptOutlineStrokeSelection() { StrokeChooserPanel panel = new StrokeChooserPanel(this.outlineStrokeSample, this.availableStrokeSamples); int result = JOptionPane.showConfirmDialog( this, panel, localizationResources.getString("Stroke_Selection"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (result == JOptionPane.OK_OPTION) { this.outlineStrokeSample.setStroke(panel.getSelectedStroke()); } } /** * Allow the user to change the outline paint. We use JColorChooser, so the user can only choose * colors (a subset of all possible paints). */ private void attemptOutlinePaintSelection() { Color c; c = JColorChooser.showDialog( this, localizationResources.getString("Outline_Color"), Color.blue); if (c != null) { this.outlinePaintSample.setPaint(c); } } // /** // * Allow the user to edit the individual insets' values. // */ // private void editInsets() { // InsetsChooserPanel panel = new InsetsChooserPanel(this.plotInsets); // int result = JOptionPane.showConfirmDialog( // this, panel, localizationResources.getString("Edit_Insets"), // JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE // ); // // if (result == JOptionPane.OK_OPTION) { // this.plotInsets = panel.getInsets(); // this.insetsTextField.setInsets(this.plotInsets); // } // // } // /** * Allow the user to modify the plot orientation if this is an editor for a <tt>CategoryPlot</tt> * or a <tt>XYPlot</tt>. */ private void attemptOrientationSelection() { int index = this.orientationCombo.getSelectedIndex(); if (index == ORIENTATION_VERTICAL) { this.plotOrientation = PlotOrientation.VERTICAL; } else { this.plotOrientation = PlotOrientation.HORIZONTAL; } } /** * Allow the user to modify whether or not lines are drawn between data points by * <tt>LineAndShapeRenderer</tt>s and <tt>StandardXYItemRenderer</tt>s. */ private void attemptDrawLinesSelection() { this.drawLines = BooleanUtilities.valueOf(this.drawLinesCheckBox.isSelected()); } /** * Allow the user to modify whether or not shapes are drawn at data points by * <tt>LineAndShapeRenderer</tt>s and <tt>StandardXYItemRenderer</tt>s. */ private void attemptDrawShapesSelection() { this.drawShapes = BooleanUtilities.valueOf(this.drawShapesCheckBox.isSelected()); } /** * Updates the plot properties to match the properties defined on the panel. * * @param plot The plot. */ public void updatePlotProperties(Plot plot) { // set the plot properties... plot.setOutlinePaint(getOutlinePaint()); plot.setOutlineStroke(getOutlineStroke()); plot.setBackgroundPaint(getBackgroundPaint()); plot.setInsets(getPlotInsets()); // then the axis properties... if (this.domainAxisPropertyPanel != null) { Axis domainAxis = null; if (plot instanceof CategoryPlot) { CategoryPlot p = (CategoryPlot) plot; domainAxis = p.getDomainAxis(); } else if (plot instanceof XYPlot) { XYPlot p = (XYPlot) plot; domainAxis = p.getDomainAxis(); } if (domainAxis != null) { this.domainAxisPropertyPanel.setAxisProperties(domainAxis); } } if (this.rangeAxisPropertyPanel != null) { Axis rangeAxis = null; if (plot instanceof CategoryPlot) { CategoryPlot p = (CategoryPlot) plot; rangeAxis = p.getRangeAxis(); } else if (plot instanceof XYPlot) { XYPlot p = (XYPlot) plot; rangeAxis = p.getRangeAxis(); } else if (plot instanceof PolarPlot) { PolarPlot p = (PolarPlot) plot; rangeAxis = p.getAxis(); } if (rangeAxis != null) { this.rangeAxisPropertyPanel.setAxisProperties(rangeAxis); } } if (this.plotOrientation != null) { if (plot instanceof CategoryPlot) { CategoryPlot p = (CategoryPlot) plot; p.setOrientation(this.plotOrientation); } else if (plot instanceof XYPlot) { XYPlot p = (XYPlot) plot; p.setOrientation(this.plotOrientation); } } if (this.drawLines != null) { if (plot instanceof CategoryPlot) { CategoryPlot p = (CategoryPlot) plot; CategoryItemRenderer r = p.getRenderer(); if (r instanceof LineAndShapeRenderer) { ((LineAndShapeRenderer) r).setLinesVisible(this.drawLines.booleanValue()); } } else if (plot instanceof XYPlot) { XYPlot p = (XYPlot) plot; XYItemRenderer r = p.getRenderer(); if (r instanceof StandardXYItemRenderer) { ((StandardXYItemRenderer) r).setPlotLines(this.drawLines.booleanValue()); } } } if (this.drawShapes != null) { if (plot instanceof CategoryPlot) { CategoryPlot p = (CategoryPlot) plot; CategoryItemRenderer r = p.getRenderer(); if (r instanceof LineAndShapeRenderer) { ((LineAndShapeRenderer) r).setShapesVisible(this.drawShapes.booleanValue()); } } else if (plot instanceof XYPlot) { XYPlot p = (XYPlot) plot; XYItemRenderer r = p.getRenderer(); if (r instanceof StandardXYItemRenderer) { ((StandardXYItemRenderer) r).setBaseShapesVisible(this.drawShapes.booleanValue()); } } } // dmo: added this panel for colorbar control. (start dmo additions) if (this.colorBarAxisPropertyPanel != null) { ColorBar colorBar = null; if (plot instanceof ContourPlot) { ContourPlot p = (ContourPlot) plot; colorBar = p.getColorBar(); } if (colorBar != null) { this.colorBarAxisPropertyPanel.setAxisProperties(colorBar); } } // dmo: (end dmo additions) } }