JFreeChart MouseListener doesn’t resolve chart elements

Your exemplary renderer has the correct geometry when run from Swing, as shown below. I’m unsure why things are awry with SWT, but this result may narrow the search.

enter image description here

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Paint;
import java.util.Random;
import javax.swing.JFrame;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.event.RendererChangeEvent;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StackedXYBarRenderer;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeTableXYDataset;
import org.jfree.data.xy.TableXYDataset;

public class StackedChartSwing {

    private ChartPanel panel;
    private StackedRenderer renderer;
    private Color[] colors = new Color[]{
        new Color(230, 240, 255),
        new Color(240, 255, 240),
        new Color(255, 255, 255),
        new Color(255, 255, 240),
        new Color(255, 240, 240),
        new Color(240, 240, 240)
    };

    public StackedChartSwing() {
        JFreeChart chart = createStackedChart(createStackedDataset());
        panel = new ChartPanel(chart);
        panel.addChartMouseListener(new ThisMouseListener());
    }

    private JFreeChart createStackedChart(TableXYDataset tablexydataset) {
        DateAxis dateaxis = new DateAxis();
        dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
        NumberAxis numberaxis = new NumberAxis("Event counts");
        renderer = new StackedRenderer();
        XYPlot plot = new XYPlot(tablexydataset, dateaxis, numberaxis, renderer);
        plot.setBackgroundPaint(Color.white);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.lightGray);

        JFreeChart chart = new JFreeChart(null, plot);
        chart.setBackgroundPaint(Color.white);
        chart.setBorderVisible(false);
        chart.setBorderPaint(null);

        return chart;
    }

    class StackedRenderer extends StackedXYBarRenderer {

        int selectedRow = -1, selectedCol = -1;

        public StackedRenderer() {
            setDrawBarOutline(true);
            setBarPainter(new StandardXYBarPainter());
            setShadowVisible(false);
            setSeriesPaint(0, Color.blue);
            setMargin(0.2);
        }

        public void select(int row, int col) {
            selectedRow = row;
            selectedCol = col;
            notifyListeners(new RendererChangeEvent(this));
        }

        @Override
        public Paint getItemPaint(final int row, final int col) {
            if (row == selectedRow && col == selectedCol) {
                return Color.pink;
            }
            return colors[row];
        }
    }

    class ThisMouseListener implements ChartMouseListener {

        @Override
        public void chartMouseMoved(ChartMouseEvent event) {
        }

        @Override
        public void chartMouseClicked(ChartMouseEvent event) {
            ChartEntity entity = event.getEntity();
            if (entity != null && (entity instanceof XYItemEntity)) {
                XYItemEntity item = (XYItemEntity) entity;
                renderer.select(item.getSeriesIndex(), item.getItem());
                return;
            }
            // deselect
            renderer.select(-1, -1);
        }
    }

    private TableXYDataset createStackedDataset() {
        Random random = new Random(0);
        TimeTableXYDataset ds = new TimeTableXYDataset();
        Day day = new Day();
        for (int i = 0; i < 24; i++) {
            Hour hour = new Hour(i, day);
            ds.add(hour, random.nextInt(20), "A");
            ds.add(hour, random.nextInt(20), "B");
            ds.add(hour, random.nextInt(20), "C");
            ds.add(hour, random.nextInt(20), "D");
            ds.add(hour, random.nextInt(20), "E");
            ds.add(hour, random.nextInt(20), "F");
        }

        return ds;
    }

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new StackedChartSwing().display();
            }
        });
    }
}

Leave a Comment