Search code examples
javaswingawtjfreechartjfilechooser

JFreeChart/JPanel updating after resizing the JFrame


I'm trying to use JFileChooser to choose an excel file which is then displayed by JFreeChart. I start by choosing the default file with classLoader in constructor and then using JFileChooser to update my graph. The problem is that when I choose a file, the panel in which I display the graph doesn't update unless I resize my frame.


public class MyFrame extends JFrame 
{
    private static final long serialVersionUID = 1L;

    MyFrame() throws BiffException, IOException
    {
        this.setSize(1500,1000);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        graphPanel = new Graph();
        menu = new MenuBar(graphPanel);
        this.add(graphPanel);

        this.add(menu, BorderLayout.PAGE_START);
    }


    public static void main(String[] args) throws BiffException, IOException 
    {
        MyFrame idFrame = new MyFrame();
        idFrame.setVisible(true);
    }


    Graph graphPanel;
    MenuBar menu;

}



public class Graph extends JPanel
{

    Graph() throws BiffException, IOException
    {
        ClassLoader classLoader = getClass().getClassLoader();
        file = new File(classLoader.getResource("zeszyt.xls").getFile());


        FileInputStream f = new FileInputStream(file);
        Workbook w = Workbook.getWorkbook(f);
        Sheet s = w.getSheet("Sheet1");

        XYDataset dataset = createDataset(s);
        JFreeChart chart = ChartFactory.createXYLineChart("title","x", "y",dataset,PlotOrientation.VERTICAL,true, true, false);
        ChartPanel panel = new ChartPanel(chart);

        this.add(panel); 
        this.setLayout(new GridLayout(1,1));
    }

    private XYDataset createDataset(Sheet s) 
      {
        XYSeriesCollection dataset = new XYSeriesCollection();

        XYSeries series = new XYSeries("y = x^2");
        for(int i=1; i<39; i++)
        {
            series.add(Double.parseDouble(s.getCell(0,i).getContents()),Double.parseDouble(s.getCell(1,i).getContents()));
        }
        dataset.addSeries(series);

        return dataset;
      }

    public void setFile(File file) throws BiffException, IOException
    {
        this.file = file;
        FileInputStream f = new FileInputStream(file);
        Workbook w = Workbook.getWorkbook(f);
        Sheet s = w.getSheet("Sheet2");

        XYDataset dataset = createDataset(s);
        JFreeChart chart = ChartFactory.createXYLineChart("title here","x", "y",dataset,PlotOrientation.VERTICAL,true, true, false);
        ChartPanel panel = new ChartPanel(chart);

        this.removeAll();
        this.add(panel); 
        this.setLayout(new GridLayout(1,1));
        this.setBackground(Color.RED);
    }
    File file;
}

public class MenuBar extends JMenuBar 
{
    public MenuBar(Graph graphPanel) 
    {
        menu1 = new JMenu("Plik");

        JMenuItem menu1Item = new JMenuItem("Open file...");
        this.add(menu1);
        menu1.add(menu1Item);

        menu1Item.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent arg0)
            {
                int returnValue = jfc.showOpenDialog(null);
                if (returnValue == JFileChooser.APPROVE_OPTION) 
                {
                    file = jfc.getSelectedFile();
                    try {
                        graphPanel.setFile(file);
                    } catch (BiffException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });


    }
    JMenu menu1;
    JMenuItem menu1Item;

    JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
    File file;

}



Solution

  • the panel in which I display the graph doesn't update unless I resize my frame.

    Components have a default size of (0, 0) when created so there is nothing to paint. You need to invoke the layout manager of the panel )after all components have been added) to give each component a size/location.

    So, when adding components to a visible GUI the basic code is:

    panel.add(...);
    panel.revalidate(); // invoke the layout manager
    panel.repaint(); // make sure panel is repainted.