Search code examples
javajfreechart

Multiple chart on the same frame with JFreeChart


I would like to display many charts on the same frame like following :

enter image description here

This example comes from java2s.com but the domain is nowadays out.

Actually i am doing it this way but it is not working, i only get one chart displayed into the frame :

JFrame frame = new JFrame("Many charts same frame");

JFreeChart barChart1 = 
    ChartFactory.createHistogram("Histogram1","", "", dataset,
            PlotOrientation.VERTICAL, true, true, false);

frame.getContentPane().add(new ChartPanel(barChart1));

JFreeChart barChart2 = 
    ChartFactory.createHistogram("Histogram2","", "", dataset,
            PlotOrientation.VERTICAL, true, true, false);

frame.getContentPane().add(new ChartPanel(barChart2));

frame.pack();

frame.setVisible(true);

Any idea ?


Solution

  • Its because JFrame uses, by default, the BorderLayout layout manager. This layout manager divides the container in five regions, i.e., CENTER, NORTH/PAGE_START, SOUTH/PAGE_END, WEST/LINE_START and EAST/LINE_END. Take a look here. If you just want to throw the components in the container and let it organize them for you, you can use, for example, a FlowLayout, that is the default layout manager for JPanel. Try something like this to change the layout manager of your JFrame.

    JFrame frame = new JFrame("Many charts same frame");
    frame.setLayout( new FlowLayout() );
    
    JFreeChart barChart1 = 
        ChartFactory.createHistogram("Histogram1","", "", dataset,
                PlotOrientation.VERTICAL, true, true, false);
    
    frame.getContentPane().add(new ChartPanel(barChart1));
    
    JFreeChart barChart2 = 
        ChartFactory.createHistogram("Histogram2","", "", dataset,
                PlotOrientation.VERTICAL, true, true, false);
    
    frame.getContentPane().add(new ChartPanel(barChart2));
    
    frame.pack();
    
    frame.setVisible(true);
    

    Doing this it probably solve your problem. If you want to keep using BorderLayout, you just need to say where, i.e., in what region, the components must be inserted. For example:

    frame.getContentPane().add(new ChartPanel(barChart1), BorderLayout.NORTH);
    frame.getContentPane().add(new ChartPanel(barChart2), BorderLayout.CENTER);
    

    You don't need to use the getContentPane() method of JFrame too. Since Java 5, if I'm not wrong, you can use the addmethod directly. Something like:

    frame.add(new ChartPanel(barChart1));
    

    Here is an example to show you the differences between these two layout managers, take a look:

    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    
    public class LayoutManagerTest {
    
        public static void main( String[] args ) {
    
            JFrame f1 = new JFrame( "BorderLayout" );
            f1.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
            f1.add( new JButton( "btn1" ) );
            f1.add( new JButton( "btn2" ) );
            f1.add( new JButton( "btn3" ) );
            f1.add( new JButton( "btn4" ) );
            f1.add( new JButton( "btn5" ) );
            f1.setSize( 500, 200 );
            f1.setLocationRelativeTo( null );
    
    
    
            JFrame f2 = new JFrame( "BorderLayout with regions" );
            f2.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
            f2.add( new JButton( "btn1" ), BorderLayout.NORTH );
            f2.add( new JButton( "btn2" ), BorderLayout.SOUTH );
            f2.add( new JButton( "btn3" ), BorderLayout.WEST );
            f2.add( new JButton( "btn4" ), BorderLayout.EAST );
            f2.add( new JButton( "btn5" ), BorderLayout.CENTER );
            f2.setSize( 500, 200 );
            f2.setLocationRelativeTo( null );
    
    
    
            JFrame f3 = new JFrame( "FlowLayout" );
            f3.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            f3.setLayout( new FlowLayout() );
    
            f3.add( new JButton( "btn1" ) );
            f3.add( new JButton( "btn2" ) );
            f3.add( new JButton( "btn3" ) );
            f3.add( new JButton( "btn4" ) );
            f3.add( new JButton( "btn5" ) );
            f3.setSize( 500, 200 );
            f3.setLocationRelativeTo( null );
    
    
    
            f1.setVisible( true );
            f2.setVisible( true );
            f3.setVisible( true );
    
        }
    
    }