2

I'm trying to perform some actions, in example - drawing the rectangle on one of the many charts in separate tabs. Actually, I have functionality to draw rectangles and scrolling the chart, but it work only on last chart created. I know, this is logical, but how to manage these actions on previous charts in other tabs? Could I use list of chartpanels, to get these datasets and add new values to them? How to solve this? Can anyone help me? SSCCE:

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellRenderer;

import net.miginfocom.swing.MigLayout;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYShapeAnnotation;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.Range;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.Layer;

public class TabbedPaneTEST extends JFrame {

    private JFrame frame;
    public JTabbedPane tabbedPane;
    public JButton btnadd;
    public TabbedPaneTEST okno = this;
    ChartPanel chartpanel;
    XYPlot subplot1;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TabbedPaneTEST window = new TabbedPaneTEST();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public TabbedPaneTEST() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);

        btnadd = new JButton("add chart");
        frame.getContentPane().add(btnadd, BorderLayout.NORTH);

        panel = new JPanel();
        frame.getContentPane().add(panel, BorderLayout.SOUTH);
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

        btnpr = new JButton("draw rectangle");
        panel.add(btnpr);

        btnkr = new JButton("cursor");
        panel.add(btnkr);

        btnadd.addActionListener(new OtworzOknoWyboruInstruDoWykres(this));
        // ==================================================================================================================================
        // Action listener rectangle
        btnpr.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                try {
                    chartpanel.removeMouseListener(mouselistenerProstokat);
                    chartpanel
                            .removeMouseMotionListener(mousemotionlistenerProstokat);
                    chartpanel.removeMouseListener(mouselistenercursor);
                    chartpanel
                            .removeMouseMotionListener(mousemotionlistenercursor);
                    chartpanel
                            .removeMouseWheelListener(mousewheellistenercursor);
                    chartpanel.setPopupMenu(null);
                } catch (Exception e) {
                }

                flagrectangle = true;

                chartpanel.addMouseListener(mouselistenerProstokat);
                chartpanel.addMouseMotionListener(mousemotionlistenerProstokat);

                currentx = chartpanel.getLocationOnScreen().x;
                currenty = Math.abs(chartpanel.getLocationOnScreen().y
                        - frame.getLocationOnScreen().y);
            }
        });
        // ==================================================================================================================================
        // ==================================================================================================================================
        // Action listener cursor
        btnkr.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                try {
                    chartpanel.removeMouseListener(mouselistenerProstokat);
                    chartpanel
                            .removeMouseMotionListener(mousemotionlistenerProstokat);
                    chartpanel.removeMouseListener(mouselistenercursor);
                    chartpanel
                            .removeMouseMotionListener(mousemotionlistenercursor);
                    chartpanel
                            .removeMouseWheelListener(mousewheellistenercursor);
                    chartpanel.setPopupMenu(null);
                } catch (Exception e) {
                }

                flagrectangle = false;

                chartpanel.addMouseListener(mouselistenercursor);
                chartpanel.addMouseMotionListener(mousemotionlistenercursor);
                chartpanel.addMouseWheelListener(mousewheellistenercursor);

            }
        });
        // ==================================================================================================================================

    }

    class OtworzOknoWyboruInstruDoWykres implements ActionListener {
        private TabbedPaneTEST okno;

        public OtworzOknoWyboruInstruDoWykres(TabbedPaneTEST okno) {
            super();
            this.okno = okno;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            formchild FrameDoInstruWyk = null;
            FrameDoInstruWyk = new formchild();
            FrameDoInstruWyk.setOkno(okno);
        }
    }

    List<ChartPanel> CPlist = new ArrayList<>();

    public void DodajWykresInstrumentu(String string) {

        double[] value = new double[1];
        Random generator = new Random();
        value[0] = generator.nextDouble();
        XYSeries series = new XYSeries("Random Data");
        series.add(1.0, 400.2);
        series.add(5.0, 294.1);
        series.add(4.0, 100.0);
        series.add(12.5, 734.4);
        series.add(17.3, 453.2);
        series.add(21.2, 500.2);
        series.add(21.9, null);
        series.add(25.6, 734.4);
        series.add(30.0, 453.2);
        XYSeriesCollection dataset = new XYSeriesCollection(series);
        String plotTitle = "sometitle";
        String xaxis = "number";
        String yaxis = "value";
        PlotOrientation orientation = PlotOrientation.VERTICAL;
        boolean show = false;
        boolean toolTips = false;
        boolean urls = false;

        JFreeChart chart = ChartFactory.createHistogram(plotTitle, xaxis,
                yaxis, dataset, orientation, show, toolTips, urls);
        subplot1 = (XYPlot) chart.getPlot();
        chartpanel = new ChartPanel(chart) {
            @Override
            public void restoreAutoBounds() {

            }
        };
        chartpanel.setRangeZoomable(false);
        chartpanel.setDomainZoomable(true);
        chartpanel.setDismissDelay(400);
        chartpanel.setZoomTriggerDistance(-1000);
        chartpanel.setMouseZoomable(false);

        CPlist.add(chartpanel);
        tabbedPane.addTab(string, chartpanel);

    }

    private double pointstartxrange;
    private double pointendxrange;
    private double pointstartx;
    private double pointstarty;
    private double pointendx;
    private double pointendy;
    Point pointstart = null;
    Point pointend = null;

    // ==================================================================================================================================
    // mouse listener cursor
    MouseListener mouselistenercursor = new MouseListener() {

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
            Point pointstart = e.getPoint();
            Point2D point = chartpanel.translateScreenToJava2D(pointstart);
            Rectangle2D plotArea = chartpanel.getScreenDataArea();

            pointstartxrange = subplot1.getDomainAxis().java2DToValue(
                    point.getX(), plotArea, subplot1.getDomainAxisEdge());
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseClicked(MouseEvent e) {
        }
    };

    MouseMotionListener mousemotionlistenercursor = new MouseMotionListener() {

        @Override
        public void mouseMoved(MouseEvent arg0) {
        }

        @Override
        public void mouseDragged(MouseEvent arg0) {
            Point pointstart = arg0.getPoint();
            Point2D point = chartpanel.translateScreenToJava2D(pointstart);
            Rectangle2D plotArea = chartpanel.getScreenDataArea();

            pointendxrange = subplot1.getDomainAxis().java2DToValue(
                    point.getX(), plotArea, subplot1.getDomainAxisEdge());

            double roznica = (pointendxrange - pointstartxrange) * (-1);

            double mini = subplot1.getDomainAxis().getRange().getLowerBound()
                    + roznica / 10;
            double maxi = subplot1.getDomainAxis().getRange().getUpperBound()
                    + roznica / 10;
            double maximumRange = subplot1.getDataRange(
                    subplot1.getDomainAxis()).getUpperBound();
            double minimumRange = subplot1.getDataRange(
                    subplot1.getDomainAxis()).getLowerBound();

            if (mini >= minimumRange - 50D
                    && pointstartxrange <= pointendxrange) {
                Range range = new Range(mini, maxi);
                subplot1.getDomainAxis().setRange(range, true, true);
                pointstartxrange = pointstartxrange + roznica / 10;
                pointendxrange = pointendxrange + roznica / 10;
            } else if (maxi <= maximumRange + 50D
                    && pointstartxrange >= pointendxrange) {
                Range range = new Range(mini, maxi);
                subplot1.getDomainAxis().setRange(range, true, true);
                pointstartxrange = pointstartxrange + roznica / 10;
                pointendxrange = pointendxrange + roznica / 10;
            }

        }
    };
    MouseWheelListener mousewheellistenercursor = new MouseWheelListener() {

        int zoomCounter = 0;

        @Override
        public void mouseWheelMoved(MouseWheelEvent arg0) {

            System.out.println(zoomCounter);

            if (arg0.getWheelRotation() > 0) {
                if (zoomCounter > (-5)) {
                    chartpanel.zoomOutDomain(MouseInfo.getPointerInfo()
                            .getLocation().x, MouseInfo.getPointerInfo()
                            .getLocation().y);
                    zoomCounter = zoomCounter - 1;
                }

            } else if (arg0.getWheelRotation() < 0) {
                if (zoomCounter < 5) {
                    chartpanel.zoomInDomain(MouseInfo.getPointerInfo()
                            .getLocation().x, MouseInfo.getPointerInfo()
                            .getLocation().y);
                    zoomCounter = zoomCounter + 1;
                }

            }
        }
    };
    // ==================================================================================================================================

    // ==================================================================================================================================
    // Drawing rectangle

    private MouseListener mouselistenerProstokat = new MouseListener() {

        @Override
        public void mouseReleased(MouseEvent e) {
            Point2D point = chartpanel.translateScreenToJava2D(e.getPoint());
            Rectangle2D plotArea = chartpanel.getScreenDataArea();

            pointendx = subplot1.getDomainAxis().java2DToValue(point.getX(),
                    plotArea, subplot1.getDomainAxisEdge());
            pointendy = subplot1.getRangeAxis().java2DToValue(point.getY(),
                    plotArea, subplot1.getRangeAxisEdge());

            chartfigura();

            pointstart = null;

        }

        @Override
        public void mousePressed(MouseEvent e) {
            Point2D point = chartpanel.translateScreenToJava2D(e.getPoint());
            Rectangle2D plotArea = chartpanel.getScreenDataArea();

            pointstartx = subplot1.getDomainAxis().java2DToValue(point.getX(),
                    plotArea, subplot1.getDomainAxisEdge());
            pointstarty = subplot1.getRangeAxis().java2DToValue(point.getY(),
                    plotArea, subplot1.getRangeAxisEdge());

            pointstart = e.getPoint();
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseClicked(MouseEvent e) {
        }

    };
    private MouseMotionListener mousemotionlistenerProstokat = new MouseMotionListener() {

        @Override
        public void mouseMoved(MouseEvent e) {
            pointend = e.getPoint();
        }

        @Override
        public void mouseDragged(MouseEvent arg0) {
            chartpanel.setMouseZoomable(false);
            pointend = arg0.getPoint();
            repaint();
        }

    };
    private boolean flagrectangle;
    private int datasetIndex;

    private Shape createRectangle(double startx, double starty, double endx,
            double endy) {
        Rectangle2D e = new Rectangle2D.Double();
        e.setFrameFromDiagonal(startx, starty, endx, endy);
        return e;
    }

    // ==================================================================================================================================
    // ==================================================================================================================================

    private void chartfigura() {

        float alpha = 0.75f;
        int type = AlphaComposite.SRC_OVER;
        AlphaComposite composite = AlphaComposite.getInstance(type, alpha);

        if (flagrectangle == true) {
            datasetIndex++;
            subplot1.setDataset(datasetIndex,
                    Annotacja("rect", pointstartx, pointstarty));
            XYLineAndShapeRenderer rendererShape = new XYLineAndShapeRenderer();
            rendererShape.setBaseShapesVisible(false);
            Rectangle2D rectangle = (Rectangle2D) createRectangle(pointstartx,
                    pointstarty, pointendx, pointendy);
            rendererShape.addAnnotation(new XYShapeAnnotation(rectangle,
                    new BasicStroke(1.0f), Color.BLACK, new Color(255, 90, 100,
                            128)), Layer.BACKGROUND);
            subplot1.setRenderer(datasetIndex, rendererShape);
        }
    }

    // ==================================================================================================================================

    public XYSeriesCollection Annotacja(final String name, double wartosc1,
            double data1) {
        final XYSeries series = new XYSeries(name);
        series.add(wartosc1, data1);

        return new XYSeriesCollection(series);
    }

    // ==================================================================================================================================

    int currentx;
    int currenty;
    public JPanel panel;
    public JButton btnpr;
    public JButton btnkr;

    // ==================================================================================================================================

    public void paint(Graphics g) {
        super.paint(g);
        g.translate(currentx, currenty);

        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        if (pointstart != null) {
            if (flagrectangle == true) {
                g.setClip(chartpanel.getBounds());
                g.setColor(Color.BLACK);
                ((Graphics2D) g).draw(createRectangle(pointstart.x,
                        pointstart.y, pointend.x, pointend.y));
            }

        }
    }

    // ==================================================================================================================================

}

class formchild extends JFrame {
    public JFrame frame = this;
    public JPanel panel;
    public JPanel panel_1;
    public JTable table;
    public JPanel panel_2;
    public JButton btnOk;
    public JButton btnOK;
    public JScrollPane scrollPane;
    private TabbedPaneTEST okno;
    public JTextField textField;
    JButton button = new JButton();
    public JLabel lblSzukajFrazy;

    public formchild() {

        frame.setMinimumSize(new Dimension(400, 450));
        frame.setPreferredSize(new Dimension(400, 450));

        panel = new JPanel();
        frame.getContentPane().add(panel, BorderLayout.NORTH);
        panel.setLayout(new MigLayout("", "[544px]", "[23px]"));

        panel_1 = new JPanel();
        frame.getContentPane().add(panel_1, BorderLayout.CENTER);
        panel_1.setLayout(new BorderLayout(0, 0));

        panel_2 = new JPanel();
        FlowLayout flowLayout = (FlowLayout) panel_2.getLayout();
        flowLayout.setAlignment(FlowLayout.RIGHT);
        frame.getContentPane().add(panel_2, BorderLayout.SOUTH);

        btnOK = new JButton("OK");
        btnOK.setPreferredSize(new Dimension(70, 23));
        panel_2.add(btnOK);
        btnOK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                frame.dispose();
                okno = null;
            }
        });

        String[] nazwyKolumn = { "element", "button" };

        String[][] data = new String[10][2];

        for (int i = 0; i < 10; i++) {
            data[i][0] = "a" + i;
            data[i][1] = "add";
        }

        table = new JTable(data, nazwyKolumn);
        table.setAutoCreateRowSorter(true);

        table.getColumn("button").setMaxWidth(70);
        table.getColumn("button").setCellRenderer(new ButtonRenderer());
        table.getColumn("button").setCellEditor(
                new ButtonEditor(new JCheckBox()));
        table.setRowHeight(30);
        scrollPane = new JScrollPane(table);
        panel_1.add(scrollPane, BorderLayout.CENTER);

        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.out.println(table.getValueAt(table.getSelectedRow(), 0));

                okno.DodajWykresInstrumentu((table.getValueAt(
                        table.getSelectedRow(), 0)).toString());

            }
        });

        frame.validate();
        frame.show();
    }

    public void setOkno(TabbedPaneTEST okno) {
        this.okno = okno;
    }

    class ButtonRenderer extends JButton implements TableCellRenderer {
        public ButtonRenderer() {
            setOpaque(true);
        }

        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            setText((value == null) ? "" : value.toString());
            return this;
        }
    }

    class ButtonEditor extends DefaultCellEditor {
        private String label = "add";

        public ButtonEditor(JCheckBox checkBox) {
            super(checkBox);
        }

        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            label = (value == null) ? "" : value.toString();
            button.setText(label);
            return button;
        }

        public Object getCellEditorValue() {
            return new String(label);
        }
    }
}
RNJ
  • 15,272
  • 18
  • 86
  • 131
Bernard Burn
  • 661
  • 5
  • 20

2 Answers2

3

Your example overrides JFrame and its paint() method to replace the functionality usually provided by ChartPanel. Instead, extend ChartPanel and override paintComponent(), then each panel you create will have a single chart with the new functionality.

  • You can control available listeners more reliably.
  • You can make a control panel available, as shown here.
  • As discussed in Painting in AWT and Swing: The Paint Methods, "Swing programs should override paintComponent() instead of overriding paint()."
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • At this time, I'm using a list of chartpanels, and each chartpanel has an index on list which is equal to index of currently used tab. But I'll analyze your solution too, perhaps it may be easier. Thank you very much :) – Bernard Burn Sep 25 '12 at 11:38
  • It should be no problem; you can use `getComponentAt()` to get the content at a given index. In this [example](http://stackoverflow.com/a/11949899/230513), `createPanel()` could return a `MyChartPanel`. – trashgod Sep 25 '12 at 13:08
1

Sounds like your looking for the Observer pattern to handle events on the other GUI components.

Take a look at http://en.wikipedia.org/wiki/Observer_pattern.

Basic idé is that whenever an event happens(say drawing a triangle in a chart) then all the classes that listens to said event are notified with whatever information you feel is relevant to the event.

Theres ALOT of literature/examples about it on the web.

David
  • 375
  • 4
  • 11