我有一个 JFrame,它根据您单击的 MenuItem 显示 JPanels。它可以工作,但是现在我需要在将 JPanel 添加到框架并显示它后调用一个方法(因为我在该面板中使用 JFreeChart,并且我必须chartPanel.repaint()
在 JPanel 可见时调用):
this.getContentPane().add( myjpanel, BorderLayout.CENTER ); //this = JFrame
this.validate();
myjpanel.methodCalledOnceDisplayed();
好像没问题?真的myjpanel
被显摆了吗?似乎不是:
public void methodCalledOnceDisplayed() {
chartPanel.repaint()
}
这不起作用(chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0)
正在抛出 IndexOutOfBoundsException)。这意味着调用 repaint 时 JPanel 不可见,我测试了以下内容:
public void methodCalledOnceDisplayed() {
JOptionPane.showMessageDialog(null,"You should see myjpanel now");
chartPanel.repaint()
}
现在它可以工作了,我myjpanel
在警报后面看到,正如预期的那样,重新绘制了 chartPanel 并且没有发生异常。
编辑:SSCCE(需要 jfreechart 和 jcommon:http ://www.jfree.org/jfreechart/download.html )
导入 java.awt.BorderLayout; 导入 java.awt.EventQueue; 导入java.awt.Font; 导入 javax.swing.JButton; 导入 javax.swing.JFrame; 导入 javax.swing.JLabel; 导入 javax.swing.JOptionPane; 导入 javax.swing.JPanel; 导入 javax.swing.border.EmptyBorder; 导入 org.jfree.chart.ChartMouseEvent; 导入 org.jfree.chart.ChartMouseListener; 导入 org.jfree.chart.JFreeChart; 导入 org.jfree.chart.plot.CombinedDomainXYPlot; 导入 org.jfree.chart.plot.PlotOrientation; 导入 org.jfree.chart.plot.XYPlot; 导入 org.jfree.chart.ChartPanel; 导入 org.jfree.data.time.TimeSeries; 导入 org.jfree.data.time.TimeSeriesCollection; 导入 org.jfree.data.xy.XYDataset; 导入 java.awt.event.ActionListener; 导入 java.awt.event.ActionEvent; 公共类窗口扩展 JFrame { 私有JPanel contentPane; 公共静态无效主要(字符串[]参数){ EventQueue.invokeLater(new Runnable() { 公共无效运行(){ 尝试 { 窗口框架 = 新窗口(); frame.setVisible(true); } 捕捉(异常 e){ e.printStackTrace(); } } }); } 公共窗口(){ 设置默认关闭操作(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 700, 500); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(new BorderLayout(0, 0)); 设置内容窗格(内容窗格); JButton clickme = new JButton("点击我"); clickme.addActionListener(new ActionListener() { 公共无效actionPerformed(ActionEvent arg0){ contentPane.removeAll(); MyJPanel mypanel = new MyJPanel(); contentPane.add(mypanel, BorderLayout.CENTER); 证实(); mypanel.methodCalledOnceDisplayed(); } }); contentPane.add(clickme, BorderLayout.NORTH); JPanel 示例 = 新 JPanel(); example.add(new JLabel("Example JPanel")); contentPane.add(例如,BorderLayout.CENTER); } } 类 MyJPanel 扩展 JPanel 实现 ChartMouseListener { 私人图表面板图表面板; 私人 JFreeChart 图表; 私人 XYPlot 子图顶部; 私人 XYPlot 子图底部; 私人 CombinedDomainXYPlot 图; 公共 MyJPanel() { this.add( new JLabel("这个 JPanel 包含图表") ); createCombinedChart(); 图表面板 = 新图表面板(图表); chartPanel.addChartMouseListener(this); this.add(chartPanel); } 私人无效createCombinedChart(){ plot = new CombinedDomainXYPlot(); plot.setGap(30); 创建子图(); plot.add(subplotTop, 4); plot.add(subplotBottom, 1); plot.setOrientation(PlotOrientation.VERTICAL); chart = new JFreeChart("Title", new Font("Arial", Font.BOLD,20), plot, true); } 私人无效创建子图(){ subplotTop = new XYPlot(); subplotBottom = new XYPlot(); subplotTop.setDataset(emptyDataset("Empty 1")); subplotBottom.setDataset(emptyDataset("Empty 2")); } 私人 XYDataset 空数据集(字符串标题){ TimeSeries ts = new TimeSeries(title); TimeSeriesCollection tsc = new TimeSeriesCollection(); tsc.addSeries(ts); 返回 tsc; } @覆盖 公共无效chartMouseMoved(ChartMouseEvent e){ System.out.println("鼠标移动了!"); } @覆盖 公共无效chartMouseClicked(ChartMouseEvent arg0){} 公共无效方法CalledOnceDisplayed(){ JOptionPane.showMessageDialog(null,"Magic!"); //尝试评论这一行并查看控制台 chartPanel.repaint(); //现在我们可以获取图表区域 this.chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0).getDataArea(); this.chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(1).getDataArea(); } }
看看有没有 JOptionPane 会发生什么。