Package jsynoptic.plugins.jfreechart

Source Code of jsynoptic.plugins.jfreechart.CyclicPlotShape$PlotPanel

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Nicolas Brodu
*
* $Id: CyclicPlotShape.java,v 1.10 2008/09/29 10:27:46 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
*
*/

package jsynoptic.plugins.jfreechart;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.undo.CompoundEdit;

import jsynoptic.ui.LongAction;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CyclicNumberAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.ui.ChartPropertyEditPanel;

import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.data.DataSourceCollection;
import simtools.ui.ActionCheckBox;
import simtools.ui.DynamicColorChooser;
import simtools.ui.NumberField;
import simtools.ui.ResourceFinder;

/**
* A shape specially designed for Cyclic axis.
* Contains all the parameter configuration options for such axis.
*
*/
public class CyclicPlotShape extends StandardPlotShape {

  static final long serialVersionUID = -7549636147827861795L;

  public static ResourceBundle resources = ResourceFinder.get(CyclicPlotShape.class, StandardPlotShape.resources);

  public CyclicPlotShape(JFreeChart chart) {
    this(chart,0,0,400,300);
  }

  public CyclicPlotShape(JFreeChart chart, int ox, int oy, int width, int height) {
    super(chart, ox, oy, width, height);
    XYPlot plot = (XYPlot)chart.getXYPlot();
    plot.setDomainAxis(new CyclicNumberAxis(10,0));
    plot.setRenderer(new JSynopticCyclicXYItemRenderer());
  }

  /* (non-Javadoc)
   * @see jsynoptic.base.ContextualActionProvider#getActions(double, double, java.lang.Object, int)
   */
  public String[] getActions(double x, double y, Object o, int context) {
    if (context==MOUSE_OVER_CONTEXT) {
      return super.getActions(x,y,o,context);
    }

    if (context==MOUSE_OUT_CONTEXT) {
      return super.getActions(x,y,o,context);
    }

    if (context==MOUSE_PRESSED_CONTEXT) {
      return null;
    }

    if (context==EDITOR_CONTEXT) {
    }

    Vector v = new Vector();
    v.add(resources.getString("Properties..."));

    XYPlot plot = (XYPlot)chart.getXYPlot();
    SourceXYDataset dst = (SourceXYDataset)plot.getDataset();

    if (o instanceof DataSource) {
      v.add(resources.getString("setX"));
      if (dst.getSources().size() != 0) {
        v.add(resources.getString("addY"));
        // No secondary Y here
      }
    }
   
    else if (o instanceof DataSourceCollection) {
      v.add(resources.getString("setXY1Yn"));
      if (dst.getSources().size() != 0) {
        v.add(resources.getString("addY1Yn"));
      }
    }

    return (String[])v.toArray(new String[v.size()]);
  }

  /* (non-Javadoc)
   * @see jsynoptic.base.ContextualActionProvider#doAction(double, double, java.lang.Object, java.lang.String)
   */
  public boolean doAction(double x, double y, Object o, String action, CompoundEdit undoableEdit) {

    if (action.equals(resources.getString("Properties..."))) {
      new LongAction(LongAction.LONG_ACTION_SHAPE, null, this) {
        protected void doAction() {
          ChartPropertyEditPanel panel = new ChartPropertyEditPanel(chart);
          JTabbedPane tab = findTab(panel);
          PlotPanel plotPanel = null;
          if (tab!=null) tab.add(plotPanel = new PlotPanel(),0);
          int result = JOptionPane.showConfirmDialog(null, panel,
            resources.getString("ChartProperties"), JOptionPane.OK_CANCEL_OPTION,
            JOptionPane.PLAIN_MESSAGE);
          if (result == JOptionPane.OK_OPTION) {
            panel.updateChartProperties(chart);
            if (plotPanel!=null) plotPanel.updateChartProperties();
          }
          notifyChange();
        }
      }.start();
      return true;
    }

    return super.doAction(x,y,o,action, undoableEdit);
  }

  public class PlotPanel extends JPanel {

    ActionCheckBox cbautox,cbfixedautox,cbcyclex,cbinvertx;
    NumberField nffixedautox,tfpxmin,tfpxmax,nfperiodx,nfoffsetx;
    JLabel lpxmin, lpxmax;
   
    ActionCheckBox cbautoy,cbfixedautoy,cbcycley,cbinverty;
    NumberField nffixedautoy,tfpymin,tfpymax,nfperiody,nfoffsety;
    JLabel lpymin, lpymax;

   
    JTextField tfTitle;
    JPanel xcards,ycards;
   
    Color noCurveColor;

    // primary Y variables
    JComboBox pcbxcurves;
    JButton pcurvecolor, pcurvedelete;
    CbxEntry pactiveEntry;
    JTextField pcbxeditortf;
    boolean peditLocked;

    
    public PlotPanel() {
//      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      setLayout(new BorderLayout());

      JPanel panel;
      Box section;
     
      Box content = Box.createVerticalBox();
     
      setName(resources.getString("PlotProperties"));

      XYPlot plot = chart.getXYPlot();

      // Create the title section
      section=Box.createHorizontalBox();
      section.add(new JLabel(resources.getString("PlotTitle:")));
      section.add(tfTitle = new JTextField());
      tfTitle.setText(chart.getTitle().getText());
      content.add(section);


      // X axis section
      section = new Box(BoxLayout.Y_AXIS);
      section.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),resources.getString("XAxis")));
     
      panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
     
      CyclicNumberAxis cna = null;
      if (plot.getDomainAxis() instanceof CyclicNumberAxis) cna = (CyclicNumberAxis)plot.getDomainAxis();
     
      panel.add(cbcyclex = new ActionCheckBox(resources.getString("CyclicAxis"), cna!=null) {
        public void actionPerformed(ActionEvent e) {
          CardLayout cl = (CardLayout)(xcards.getLayout());
          if (isSelected()) cl.show(xcards, "cyclic");
          else cl.show(xcards, "normal");
        }
      });
      panel.add(cbinvertx = new ActionCheckBox(resources.getString("Inverted"), plot.getDomainAxis().isInverted()) {
        public void actionPerformed(ActionEvent e) {
        }
      });
      section.add(panel);
     
      xcards = new JPanel();
      xcards.setLayout(new CardLayout());
     
      Box hbox = Box.createHorizontalBox();
      hbox.add(new JLabel(resources.getString("Period")));
      hbox.add(nfperiodx = new NumberField(cna==null ? 0 : cna.getPeriod()));
      hbox.add(Box.createHorizontalGlue());
      hbox.add(new JLabel(resources.getString("Offset")));
      hbox.add(nfoffsetx = new NumberField(cna==null ? 0 : cna.getOffset()));
      xcards.add(hbox,"cyclic");
     
      panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
      double autorange = plot.getDomainAxis().getFixedAutoRange();
      panel.add(cbfixedautox = new ActionCheckBox(resources.getString("FixedRange"),autorange!=0) {
        public void actionPerformed(ActionEvent e) {
          nffixedautox.setEnabled(isSelected() && isEnabled());
        }
      });
      panel.add(nffixedautox = new NumberField(autorange,10));
      xcards.add(panel,"normal");

      section.add(xcards);
     
      panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
      panel.add(cbautox = new ActionCheckBox(resources.getString("Auto-update"), plot.getDomainAxis().isAutoRange()) {
        public void actionPerformed(ActionEvent e) {
          cbfixedautox.setEnabled(isSelected());
          cbfixedautox.apply();
          lpxmin.setEnabled(!isSelected());
          lpxmax.setEnabled(!isSelected());
          tfpxmin.setEnabled(!isSelected());
          tfpxmax.setEnabled(!isSelected());
        }
      });
      panel.add(lpxmin = new JLabel(resources.getString("minLabel")));
      panel.add(tfpxmin = new NumberField(10));
      tfpxmin.setValue(plot.getDomainAxis().getLowerBound());
      panel.add(lpxmax = new JLabel(resources.getString("maxLabel")));
      panel.add(tfpxmax = new NumberField(10));
      tfpxmax.setValue(plot.getDomainAxis().getUpperBound());
      cbautox.apply();
      section.add(panel);
     
      content.add(section);

     
      // Now handle Y axis
      section = new Box(BoxLayout.Y_AXIS);
      section.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),resources.getString("YAxis")));

      panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
     
      cna = null;
      if (plot.getRangeAxis() instanceof CyclicNumberAxis) cna = (CyclicNumberAxis)plot.getRangeAxis();
     
      panel.add(cbcycley = new ActionCheckBox(resources.getString("CyclicAxis"), cna!=null) {
        public void actionPerformed(ActionEvent e) {
          CardLayout cl = (CardLayout)(ycards.getLayout());
          if (isSelected()) cl.show(ycards, "cyclic");
          else cl.show(ycards, "normal");
        }
      });
      panel.add(cbinverty = new ActionCheckBox(resources.getString("Inverted"), plot.getRangeAxis().isInverted()) {
        public void actionPerformed(ActionEvent e) {
        }
      });
      section.add(panel);
     
      ycards = new JPanel();
      ycards.setLayout(new CardLayout());
     
      hbox = Box.createHorizontalBox();
      hbox.add(new JLabel(resources.getString("Period")));
      hbox.add(nfperiody = new NumberField(cna==null ? 0 : cna.getPeriod()));
      hbox.add(Box.createHorizontalGlue());
      hbox.add(new JLabel(resources.getString("Offset")));
      hbox.add(nfoffsety = new NumberField(cna==null ? 0 : cna.getOffset()));
      ycards.add(hbox,"cyclic");
     
      panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
      autorange = plot.getRangeAxis().getFixedAutoRange();
      panel.add(cbfixedautoy = new ActionCheckBox(resources.getString("FixedRange"),autorange!=0) {
        public void actionPerformed(ActionEvent e) {
          nffixedautoy.setEnabled(isSelected() && isEnabled());
        }
      });
      panel.add(nffixedautoy = new NumberField(autorange,10));
      ycards.add(panel,"normal");

      section.add(ycards);
     
      panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
      panel.add(cbautoy = new ActionCheckBox(resources.getString("Auto-update"), plot.getRangeAxis().isAutoRange()) {
        public void actionPerformed(ActionEvent e) {
          cbfixedautoy.setEnabled(isSelected());
          cbfixedautoy.apply();
          lpymin.setEnabled(!isSelected());
          lpymax.setEnabled(!isSelected());
          tfpymin.setEnabled(!isSelected());
          tfpymax.setEnabled(!isSelected());
        }
      });
      panel.add(lpymin = new JLabel(resources.getString("minLabel")));
      panel.add(tfpymin = new NumberField(10));
      tfpymin.setValue(plot.getRangeAxis().getLowerBound());
      panel.add(lpymax = new JLabel(resources.getString("maxLabel")));
      panel.add(tfpymax = new NumberField(10));
      tfpymax.setValue(plot.getRangeAxis().getUpperBound());
      cbautoy.apply();
      section.add(panel);

      Box box = Box.createHorizontalBox();

      box.add(new JLabel(resources.getString("Curves:")));
      box.add(pcbxcurves = new JComboBox());
      box.add(pcurvecolor = new JButton("    "));
      box.add(pcurvedelete = new JButton(resources.getString("Delete")));
      section.add(box);
      content.add(section);

      pcbxcurves.setEditable(true);
      noCurveColor = pcurvecolor.getBackground();
      pcurvecolor.setFocusPainted(false);
      SourceXYDataset dst = (SourceXYDataset)plot.getDataset();
      int n = dst.getSeriesCount();
      JSynopticXYItemRenderer renderer = (JSynopticXYItemRenderer)plot.getRenderer();
      for (int i=0; i<n; ++i) {
        DataSource ds = renderer.getDataSource(i);
        if (ds==null) {
          ds = dst.getYSource(i); // take the datasource associated with this curve by default
          DataSource linked = DataInfo.getLinkedSource(ds); // and follow link if necessary
          if (linked!=null) ds = linked;
        }
        pcbxcurves.addItem(new CbxEntry(i,dst.getSeriesName(i),(Color)renderer.getSeriesPaint(i),ds,renderer.getColorMapper(i)));
      }
      pcbxeditortf = (JTextField)pcbxcurves.getEditor().getEditorComponent();
      pupdateForEntry(pcbxcurves.getSelectedItem());
     
      pcbxcurves.addPopupMenuListener(new PopupMenuListener() {
        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
          peditLocked = true;
        }
        public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
          peditLocked = false;
        }
        public void popupMenuCanceled(PopupMenuEvent e) {
          peditLocked = false;
        }
      });

      pcbxcurves.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
          if (e.getStateChange()==ItemEvent.DESELECTED) pactiveEntry = null;
          else pupdateForEntry(e.getItem());
        }
      });

      pcbxeditortf.getDocument().addDocumentListener(new DocumentListener() {
        public void insertUpdate(DocumentEvent e) {
          updateName();
        }
        public void removeUpdate(DocumentEvent e) {
          updateName();
        }
        public void changedUpdate(DocumentEvent e) {
          updateName();
        }
        public void updateName() {
          if ((peditLocked) || (pactiveEntry == null)) return;
          pactiveEntry.name = pcbxeditortf.getText();
        }
      });

      pcurvecolor.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          if (pactiveEntry==null) return;
         
            DynamicColorChooser dialog = new DynamicColorChooser(
                            null, resources.getString("ChooseAColor"),null ,pactiveEntry.color,pactiveEntry.source,pactiveEntry.mapper);


            dialog.pack();
            dialog.setVisible(true);

            if (dialog.isOk()){
                pactiveEntry.color = dialog.getColor();
                pactiveEntry.source = dialog.getSource();
                pactiveEntry.mapper = dialog.getMapper();
                pupdateForEntry(pactiveEntry);
            }
       
         
        }
      });

      pcurvedelete.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          if (pactiveEntry==null) return;
          pcbxcurves.removeItem(pactiveEntry);
        }
      });
     
      cbcyclex.apply();
      cbcycley.apply();
      add(content, BorderLayout.NORTH);

    }

    protected void pupdateForEntry(Object o) {
      if (o instanceof CbxEntry) pactiveEntry = (CbxEntry)o;
      else  pactiveEntry = null;
      if (pactiveEntry == null) return;
      pcurvecolor.setBackground(pactiveEntry.color);
    }

    protected void updateChartProperties() {
      ValueAxis xaxis = null;
      if (cbcyclex.isSelected()) {
        xaxis = new CyclicNumberAxis(nfperiodx.getDoubleValue(),nfoffsetx.getDoubleValue());
      } else {
        xaxis = new NumberAxis();
        if (nffixedautox.isEnabled()) xaxis.setFixedAutoRange(nffixedautox.getDoubleValue());
      }
      xaxis.setAutoRange(cbautox.isSelected());
      xaxis.setInverted(cbinvertx.isSelected());
      if (tfpxmin.isEnabled() && tfpxmax.isEnabled()) xaxis.setRange(tfpxmin.getDoubleValue(), tfpxmax.getDoubleValue());
     
      ValueAxis yaxis = null;
      if (cbcycley.isSelected()) {
        yaxis = new CyclicNumberAxis(nfperiody.getDoubleValue(),nfoffsety.getDoubleValue());
      } else {
        yaxis = new NumberAxis();
        if (nffixedautoy.isEnabled()) yaxis.setFixedAutoRange(nffixedautoy.getDoubleValue());
      }
      yaxis.setAutoRange(cbautoy.isSelected());
      yaxis.setInverted(cbinverty.isSelected());
      if (tfpymin.isEnabled() && tfpymax.isEnabled()) yaxis.setRange(tfpymin.getDoubleValue(), tfpymax.getDoubleValue());
     
      chart.setTitle(tfTitle.getText());
      XYPlot plot = chart.getXYPlot();

      plot.setDomainAxis(xaxis);
      plot.setRangeAxis(yaxis);
     
      // Primary Y update
      SourceXYDataset dst = (SourceXYDataset)plot.getDataset();
      int n = dst.getSeriesCount();

      // If some curves were deleted, remove them
      if (n != pcbxcurves.getItemCount()) {
        boolean[] toKeep = new boolean[n]; // boolean are initialized to false by JVM
        for (int i=0; i<pcbxcurves.getItemCount(); ++i)
          toKeep[((CbxEntry)pcbxcurves.getItemAt(i)).datasetIndex] = true;

        JSynopticXYItemRenderer renderer = (JSynopticXYItemRenderer)plot.getRenderer();

        // Now we can remove the deleted curves, and update the existing ones
        // Start from the end, to remove the entries and keep the index OK
        for (int i=n-1; i>=0; i--) {
          if (!toKeep[i]) {
            if (i>0) dst.removeXSource(i);
            else dst.removeYSource(i);
            renderer.removeColorMapper(i);
            renderer.removeDataSource(i);
          }
        }
      }
     
      // Now we match the data set and the list
      for (int i=0; i<pcbxcurves.getItemCount(); ++i) {
        CbxEntry e = (CbxEntry)pcbxcurves.getItemAt(i);
        dst.setName(i,e.name);
        JSynopticXYItemRenderer renderer = (JSynopticXYItemRenderer)plot.getRenderer();
        renderer.setSeriesPaint(i,e.color);
        renderer.setDataSource(i, e.source);
        renderer.setColorMapper(i, e.mapper);
      }

    }

  }
 
 
}

TOP

Related Classes of jsynoptic.plugins.jfreechart.CyclicPlotShape$PlotPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.