JFreeChart的放大和缩小function的exception行为?

我观察到“放大”和“缩小”的function实现与预期完全不同。例如,当我执行“缩小”一步时,然后在“缩放”后退一步后再次在”。 我再也看不到原始图表了。

我没有看到JFreechart的“放大”和“缩小”function处于同步状态。

public class ChartPanelDemo { private static final String title = "Historical Data Graph"; private ChartPanel chartPanel = createChart(); private JButton ZoomX; private JButton ZoomY; private JButton Zoom; private JButton ZoomXOut; private JButton ZoomYOut; private JButton ZoomOut; private JButton originalGraph; private JButton xscaleInc; private JButton xscaleDec; private NumberAxis domainAxis; private NumberAxis rangeAxis; private int UNITS = 1; private static final int COUNT = 100; private JPanel panel; private double[][] sizeFr = { { TableLayout.FILL }, { TableLayout.FILL } }; public ChartPanelDemo() { JFrame f = new JFrame(title); panel = new JPanel(); f.setTitle(title); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setLayout(new BorderLayout(0, 5)); f.add(chartPanel, BorderLayout.CENTER); chartPanel.setMouseWheelEnabled(true); // chartPanel.setHorizontalAxisTrace(true); // chartPanel.setVerticalAxisTrace(true); chartPanel.setZoomInFactor(0.9); chartPanel.setZoomOutFactor(0.9); JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); panel.add(createTrace()); panel.add(createDate()); panel.add(createZoom()); panel.add(createZoomOutX()); panel.add(createZoomOutY()); panel.add(createZoomOut()); panel.add(toOriginalGraph()); panel.add(AutoScaleDecXaxis()); //panel.add(AutoScaleDecXaxis()); f.add(panel, BorderLayout.SOUTH); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private JSpinner AutoScaleDecXaxis() { final JSpinner spinner = new JSpinner( new SpinnerNumberModel(UNITS, 1, COUNT, 1)); spinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { JSpinner s = (JSpinner) e.getSource(); Number n = (Number) s.getValue(); domainAxis.setTickUnit(new NumberTickUnit(n.intValue())); } }); return spinner; } private JButton toOriginalGraph() { originalGraph = new JButton(new AbstractAction("RestoreGraph") { @Override public void actionPerformed(ActionEvent e) { chartPanel.restoreAutoBounds(); } }); return originalGraph; } private JButton createZoomOut() { ZoomOut = new JButton(new AbstractAction("ZoomOut") { @Override public void actionPerformed(ActionEvent e) { ZoomOut.setActionCommand(chartPanel.ZOOM_OUT_BOTH_COMMAND); ZoomOut.addActionListener(chartPanel); } }); return ZoomOut; } private JButton createZoomOutY() { ZoomYOut = new JButton(new AbstractAction("ZoomOutY") { @Override public void actionPerformed(ActionEvent e) { ZoomYOut.setActionCommand(chartPanel.ZOOM_OUT_RANGE_COMMAND); ZoomYOut.addActionListener(chartPanel); } }); return ZoomYOut; } private JButton createZoomOutX() { ZoomXOut = new JButton(new AbstractAction("ZoomOutX") { @Override public void actionPerformed(ActionEvent e) { ZoomXOut.setActionCommand(chartPanel.ZOOM_OUT_DOMAIN_COMMAND); ZoomXOut.addActionListener(chartPanel); } }); return ZoomXOut; } private JButton createTrace() { ZoomX = new JButton(new AbstractAction("ZoomInX") { @Override public void actionPerformed(ActionEvent e) { ZoomX.setActionCommand(chartPanel.ZOOM_IN_DOMAIN_COMMAND); ZoomX.addActionListener(chartPanel); // chartPanel.restoreAutoBounds(); } }); return ZoomX; } private JButton createDate() { ZoomY = new JButton(new AbstractAction("ZoomInY") { @Override public void actionPerformed(ActionEvent e) { ZoomY.setActionCommand(chartPanel.ZOOM_IN_RANGE_COMMAND); ZoomY.addActionListener(chartPanel); } }); return ZoomY; } private JButton createZoom() { Zoom = new JButton(new AbstractAction("Zoom") { @Override public void actionPerformed(ActionEvent e) { Zoom.setActionCommand(chartPanel.ZOOM_IN_BOTH_COMMAND); Zoom.addActionListener(chartPanel); } }); return Zoom; } private ChartPanel createChart() { XYDataset roiData = createDataset(); JFreeChart chart = createChart(roiData); chart.setBackgroundPaint(new Color(0xBBBBDD)); XYPlot plot = chart.getXYPlot(); XYSplineRenderer r = new XYSplineRenderer(20); plot.setRenderer(r); r.setBaseShapesVisible(true); rangeAxis = (NumberAxis) plot.getRangeAxis(); domainAxis = (NumberAxis) plot.getDomainAxis(); rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); return new ChartPanel(chart); } private JFreeChart createChart(XYDataset dataset) { JFreeChart chart = ChartFactory.createXYLineChart("Historical Data", // chart // title "X", // x axis label "Y", // y axis label dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); return chart; } private XYDataset createDataset() { XYSeries series1 = new XYSeries("First"); series1.add(1.0, 1.0); series1.add(2.0, 4.0); series1.add(3.0, 3.0); series1.add(4.0, 5.0); series1.add(5.0, 5.0); series1.add(6.0, 7.0); series1.add(7.0, 7.0); series1.add(8.0, 8.0); XYSeries series2 = new XYSeries("Second"); series2.add(1.0, 5.0); series2.add(2.0, 7.0); series2.add(3.0, 6.0); series2.add(4.0, 8.0); series2.add(5.0, 4.0); series2.add(6.0, 4.0); series2.add(7.0, 2.0); series2.add(8.0, 1.0); XYSeriesCollection dataset = new XYSeriesCollection(); dataset.addSeries(series1); dataset.addSeries(series2); return dataset; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { ChartPanelDemo cpd = new ChartPanelDemo(); } }); } } 

问题2:两次点击ZoomInX后 在此处输入图像描述

再次点击两次ZoomOutX(这是原始图表) 在此处输入图像描述

但是再次点击两次ZoomInX后,我看到图形不同,而不是这个问题中应该是的第一个图像。 在此处输入图像描述

您的示例似乎是混合了此处建议的两种方法,从您自己的actionPerformed()实现中调用图表面板的处理程序。 虽然图表面板处理程序是可重用的,但它们不是可重入的。 而是直接使用图表面板的实现。 下面的示例重点介绍两个用于放大和缩小域的按钮:

 toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND)); toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND)); … private JButton createButton(String name, String command) { final JButton b = new JButton(name); b.setActionCommand(command); b.addActionListener(chartPanel); return b; } 

单击放大X后

放大x后

单击缩小X后

缩小x后

这个完整的示例重新计算createButton()方法以运用可用的缩放处理程序,并使用JToolBar说明。

 import java.awt.BorderLayout; import java.awt.EventQueue; import java.text.NumberFormat; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToolBar; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.time.Year; import org.jfree.data.xy.XYDataset; import static org.jfree.chart.ChartPanel.*; /** @see https://stackoverflow.com/a/41337259/230513 */ public class ZoomDemo { private static final String TITLE = "Return On Investment"; private final ChartPanel chartPanel = createChart(); public ZoomDemo() { JFrame f = new JFrame(TITLE); f.setTitle(TITLE); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setLayout(new BorderLayout(0, 5)); f.add(chartPanel, BorderLayout.CENTER); chartPanel.setMouseWheelEnabled(true); JPanel panel = new JPanel(); JToolBar toolBar = new JToolBar(); toolBar.add(createButton("Zoom In", ZOOM_IN_BOTH_COMMAND)); toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND)); toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND)); toolBar.add(createButton("Zoom Out", ZOOM_OUT_BOTH_COMMAND)); toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND)); toolBar.add(createButton("Zoom Out Y", ZOOM_OUT_RANGE_COMMAND)); toolBar.add(createButton("Reset", ZOOM_RESET_BOTH_COMMAND)); toolBar.add(createButton("Reset X", ZOOM_RESET_DOMAIN_COMMAND)); toolBar.add(createButton("Reset Y", ZOOM_RESET_RANGE_COMMAND)); panel.add(toolBar); f.add(panel, BorderLayout.SOUTH); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private JButton createButton(String name, String command) { final JButton b = new JButton(name); b.setActionCommand(command); b.addActionListener(chartPanel); return b; } private ChartPanel createChart() { XYDataset roiData = createDataset(); JFreeChart chart = ChartFactory.createTimeSeriesChart( TITLE, "Date", "Value", roiData, true, true, false); XYPlot plot = chart.getXYPlot(); XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer(); renderer.setBaseShapesVisible(true); NumberFormat currency = NumberFormat.getCurrencyInstance(); currency.setMaximumFractionDigits(0); NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); rangeAxis.setNumberFormatOverride(currency); return new ChartPanel(chart); } private XYDataset createDataset() { TimeSeriesCollection tsc = new TimeSeriesCollection(); tsc.addSeries(createSeries("Projected", 200)); tsc.addSeries(createSeries("Actual", 100)); return tsc; } private TimeSeries createSeries(String name, double scale) { TimeSeries series = new TimeSeries(name); for (int i = 0; i < 6; i++) { series.add(new Year(2016 + i), Math.pow(2, i) * scale); } return series; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { ZoomDemo cpd = new ZoomDemo(); } }); } }