JFreeChart MouseListener无法解析图表元素

我有堆叠的条形图,我希望能够在其中选择单个条形。但是ChartMouseListener不会将ChartMouseEvent解析为相应的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的。任何人都可以确认这是错误的行为还是有解决方法?


PIPIONE
浏览 774回答 3
3回答

jeck猫

好的,我发现了问题。在SWT中,有多个构造函数可以创建ChartComposite,大多数使用默认值来指定最小/最大宽度和高度。就我而言,只要将图表放大到DEFAULT_MAXIMUM_DRAW_WIDTH(800px)以上,坐标就会变得混乱。因此,解决方案是使用完整的构造函数并为您的显示指定相关边界。这很难破解...主要是由于缺乏适当的文档。

隔江千里

从Swing运行时,示例性渲染器具有正确的几何形状,如下所示。我不确定SWT为何会出现问题,但是此结果可能会缩小搜索范围。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 {&nbsp; &nbsp; private ChartPanel panel;&nbsp; &nbsp; private StackedRenderer renderer;&nbsp; &nbsp; private Color[] colors = new Color[]{&nbsp; &nbsp; &nbsp; &nbsp; new Color(230, 240, 255),&nbsp; &nbsp; &nbsp; &nbsp; new Color(240, 255, 240),&nbsp; &nbsp; &nbsp; &nbsp; new Color(255, 255, 255),&nbsp; &nbsp; &nbsp; &nbsp; new Color(255, 255, 240),&nbsp; &nbsp; &nbsp; &nbsp; new Color(255, 240, 240),&nbsp; &nbsp; &nbsp; &nbsp; new Color(240, 240, 240)&nbsp; &nbsp; };&nbsp; &nbsp; public StackedChartSwing() {&nbsp; &nbsp; &nbsp; &nbsp; JFreeChart chart = createStackedChart(createStackedDataset());&nbsp; &nbsp; &nbsp; &nbsp; panel = new ChartPanel(chart);&nbsp; &nbsp; &nbsp; &nbsp; panel.addChartMouseListener(new ThisMouseListener());&nbsp; &nbsp; }&nbsp; &nbsp; private JFreeChart createStackedChart(TableXYDataset tablexydataset) {&nbsp; &nbsp; &nbsp; &nbsp; DateAxis dateaxis = new DateAxis();&nbsp; &nbsp; &nbsp; &nbsp; dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);&nbsp; &nbsp; &nbsp; &nbsp; NumberAxis numberaxis = new NumberAxis("Event counts");&nbsp; &nbsp; &nbsp; &nbsp; renderer = new StackedRenderer();&nbsp; &nbsp; &nbsp; &nbsp; XYPlot plot = new XYPlot(tablexydataset, dateaxis, numberaxis, renderer);&nbsp; &nbsp; &nbsp; &nbsp; plot.setBackgroundPaint(Color.white);&nbsp; &nbsp; &nbsp; &nbsp; plot.setDomainGridlinePaint(Color.lightGray);&nbsp; &nbsp; &nbsp; &nbsp; plot.setDomainGridlinesVisible(true);&nbsp; &nbsp; &nbsp; &nbsp; plot.setRangeGridlinesVisible(true);&nbsp; &nbsp; &nbsp; &nbsp; plot.setRangeGridlinePaint(Color.lightGray);&nbsp; &nbsp; &nbsp; &nbsp; JFreeChart chart = new JFreeChart(null, plot);&nbsp; &nbsp; &nbsp; &nbsp; chart.setBackgroundPaint(Color.white);&nbsp; &nbsp; &nbsp; &nbsp; chart.setBorderVisible(false);&nbsp; &nbsp; &nbsp; &nbsp; chart.setBorderPaint(null);&nbsp; &nbsp; &nbsp; &nbsp; return chart;&nbsp; &nbsp; }&nbsp; &nbsp; class StackedRenderer extends StackedXYBarRenderer {&nbsp; &nbsp; &nbsp; &nbsp; int selectedRow = -1, selectedCol = -1;&nbsp; &nbsp; &nbsp; &nbsp; public StackedRenderer() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDrawBarOutline(true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setBarPainter(new StandardXYBarPainter());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setShadowVisible(false);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setSeriesPaint(0, Color.blue);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setMargin(0.2);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void select(int row, int col) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selectedRow = row;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selectedCol = col;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyListeners(new RendererChangeEvent(this));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public Paint getItemPaint(final int row, final int col) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (row == selectedRow && col == selectedCol) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Color.pink;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return colors[row];&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; class ThisMouseListener implements ChartMouseListener {&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void chartMouseMoved(ChartMouseEvent event) {&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void chartMouseClicked(ChartMouseEvent event) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ChartEntity entity = event.getEntity();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (entity != null && (entity instanceof XYItemEntity)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XYItemEntity item = (XYItemEntity) entity;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderer.select(item.getSeriesIndex(), item.getItem());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // deselect&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderer.select(-1, -1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private TableXYDataset createStackedDataset() {&nbsp; &nbsp; &nbsp; &nbsp; Random random = new Random(0);&nbsp; &nbsp; &nbsp; &nbsp; TimeTableXYDataset ds = new TimeTableXYDataset();&nbsp; &nbsp; &nbsp; &nbsp; Day day = new Day();&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 24; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Hour hour = new Hour(i, day);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ds.add(hour, random.nextInt(20), "A");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ds.add(hour, random.nextInt(20), "B");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ds.add(hour, random.nextInt(20), "C");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ds.add(hour, random.nextInt(20), "D");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ds.add(hour, random.nextInt(20), "E");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ds.add(hour, random.nextInt(20), "F");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return ds;&nbsp; &nbsp; }&nbsp; &nbsp; private void display() {&nbsp; &nbsp; &nbsp; &nbsp; JFrame f = new JFrame("Test");&nbsp; &nbsp; &nbsp; &nbsp; f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&nbsp; &nbsp; &nbsp; &nbsp; f.add(panel);&nbsp; &nbsp; &nbsp; &nbsp; f.pack();&nbsp; &nbsp; &nbsp; &nbsp; f.setLocationRelativeTo(null);&nbsp; &nbsp; &nbsp; &nbsp; f.setVisible(true);&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; EventQueue.invokeLater(new Runnable() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new StackedChartSwing().display();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }}

慕森卡

摆动不是这里的问题。问题在JFreeChart的SWT版本中。实际上,最初打开时,一切正常。但是,一旦您调整了主机框架的大小,事情就会变得疯狂。它必须非常简单,就好像图表不知道已调整大小一样。但是它确实可以正确绘制,只是渲染器变得无用。我需要这些东西才能在Eclipse RCP应用程序中工作,如果无法解决,所有库都将变为无效是多么可惜的事情。
打开App,查看更多内容
随时随地看视频慕课网APP