I have a JFrame that displays JPanels depending on the click of MenuItem. It works, but now I need to call the method when the JPanel is added to the frame and it is displayed (because I use JFreeChart inside this panel, and I need to call chartPanel.repaint() when the JPanel is visible):
this.getContentPane().add( myjpanel, BorderLayout.CENTER ); //this = JFrame this.validate(); myjpanel.methodCalledOnceDisplayed();
Does this seem normal? Is myjpanel really showing myjpanel ? It doesn't seem to be that way:
public void methodCalledOnceDisplayed() { chartPanel.repaint() }
This does not work ( chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0) throws an IndexOutOfBoundsException). This means that JPanel was not visible when calling repaint, I tested the following:
public void methodCalledOnceDisplayed() { JOptionPane.showMessageDialog(null,"You should see myjpanel now"); chartPanel.repaint() }
Now it works, I see myjpanel behind the warning, as expected, chartPanel is repainted and an Exception does not occur.
EDIT : SSCCE (requires jfreechart and jcommon: http://www.jfree.org/jfreechart/download.html )
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.ChartPanel;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Window extends JFrame {
private JPanel contentPane;
public static void main (String [] args) {
EventQueue.invokeLater (new Runnable () {
public void run () {
try {
Window frame = new Window ();
frame.setVisible (true);
} catch (Exception e) {
e.printStackTrace ();
}
}
});
}
public Window () {
setDefaultCloseOperation (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));
setContentPane (contentPane);
JButton clickme = new JButton ("Click me");
clickme.addActionListener (new ActionListener () {
public void actionPerformed (ActionEvent arg0) {
contentPane.removeAll ();
MyJPanel mypanel = new MyJPanel ();
contentPane.add (mypanel, BorderLayout.CENTER);
validate ();
mypanel.methodCalledOnceDisplayed ();
}
});
contentPane.add (clickme, BorderLayout.NORTH);
JPanel example = new JPanel ();
example.add (new JLabel ("Example JPanel"));
contentPane.add (example, BorderLayout.CENTER);
}
}
class MyJPanel extends JPanel implements ChartMouseListener {
private ChartPanel chartPanel;
private JFreeChart chart;
private XYPlot subplotTop;
private XYPlot subplotBottom;
private CombinedDomainXYPlot plot;
public MyJPanel () {
this.add (new JLabel ("This JPanel contains the chart"));
createCombinedChart ();
chartPanel = new ChartPanel (chart);
chartPanel.addChartMouseListener (this);
this.add (chartPanel);
}
private void createCombinedChart () {
plot = new CombinedDomainXYPlot ();
plot.setGap (30);
createSubplots ();
plot.add (subplotTop, 4);
plot.add (subplotBottom, 1);
plot.setOrientation (PlotOrientation.VERTICAL);
chart = new JFreeChart ("Title", new Font ("Arial", Font.BOLD, 20), plot, true);
}
private void createSubplots () {
subplotTop = new XYPlot ();
subplotBottom = new XYPlot ();
subplotTop.setDataset (emptyDataset ("Empty 1"));
subplotBottom.setDataset (emptyDataset ("Empty 2"));
}
private XYDataset emptyDataset (String title) {
TimeSeries ts = new TimeSeries (title);
TimeSeriesCollection tsc = new TimeSeriesCollection ();
tsc.addSeries (ts);
return tsc;
}
@Override
public void chartMouseMoved (ChartMouseEvent e) {
System.out.println ("Mouse moved!");
}
@Override
public void chartMouseClicked (ChartMouseEvent arg0) {}
public void methodCalledOnceDisplayed () {
JOptionPane.showMessageDialog (null, "Magic!"); // try to comment this line and see the console
chartPanel.repaint ();
// now we can get chart areas
this.chartPanel.getChartRenderingInfo (). getPlotInfo (). getSubplotInfo (0) .getDataArea ();
this.chartPanel.getChartRenderingInfo (). getPlotInfo (). getSubplotInfo (1) .getDataArea ();
}
} See what happens with and without JOptionPane.