JFreeChart MouseListener不parsing图表元素

我已经堆积了条形图,我希望能够在堆栈中select单个条形图。 但ChartMouseListener不会将ChartMouseEventparsing为相应的ChartEntity。 这里是监听器片段:

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); } 

问题是,当我明显地点击一些酒吧时,event.getEntity()返回null。 请注意,并非所有的酒吧失败。 进一步我走到图表的右端,坐标的移位就越明显。 在下面的快照显示,选中的栏实际上出现时单击其外部。 我在SWT组合内使用JFreeChart。 任何人都可以确认这是一个马车行为或有一个解决方法吗?

在这里输入图像描述

下面是完整的sscce ,你运行后,点击酒吧 – 它会显示小指。 然后重新调整窗口的大小,并尝试select酒吧 – 它会错过。 而我认为这个小姐是新尺码的function。

 import java.awt.Color; import java.awt.Paint; import java.util.Random; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.jfree.chart.ChartMouseEvent; import org.jfree.chart.ChartMouseListener; 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; import org.jfree.experimental.chart.swt.ChartComposite; public class StackedChartSwt { 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 StackedChartSwt(){ Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new FillLayout()); JFreeChart chart = createStackedChart(createStackedDataset()); ChartComposite chartComposite = new ChartComposite(shell, SWT.NONE, chart, false, false, false, false, false); chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); chartComposite.setRangeZoomable(false); chartComposite.setMenu(null); chartComposite.addChartMouseListener(new ThisMouseListener()); shell.setSize(800, 600); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } 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{ public void chartMouseMoved(ChartMouseEvent event){ } 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; } public static void main(String[] args){ new StackedChartSwt(); } } 

示例渲染器在从Swing运行时具有正确的几何graphics,如下所示。 我不确定为什么SWT会出错,但是这个结果可能会缩小search范围。

在这里输入图像描述

 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(); } }); } } 

好的,我发现了这个问题。 在SWT中有几个构造函数来创buildChartComposite,大多数使用默认值指定最小/最大宽度和高度。 在我的情况下,每当我放大了上方的图表DEFAULT_MAXIMUM_DRAW_WIDTH(800px) – 坐标开始变得杂乱。 所以,解决scheme是使用完整的构造函数并为您的显示指定相关的边界。 主要是由于缺乏适当的文件,这是一个难以解决的问题。