Search code examples
javaswinglayout-managerborder-layoutflowlayout

Automatically Expanding using JTabbedPane


I'm trying to get the JTabbedPane automatically expanding over the parent JPanel.

When I put everything in the Main class, it works:

enter image description here

Main:

public class Main extends JFrame {

    public Main() {
        JTabbedPane tpane = new JTabbedPane();
        JPanel panel = new JPanel();
        panel.add(new JButton("Button 1"));
        tpane.addTab("Tab1", panel);

        JPanel panel2 = new JPanel();
        panel2.add(new JButton("Button 2"));
        tpane.addTab("Tab2", panel2);

        this.setSize(500, 500);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(tpane);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        Main m = new Main();
    }
}

But when I put it into another class, it won't work anymore:

enter image description here

Main:

public class Main extends JFrame {

    View view = new View();

    public Main() {
        this.setSize(500, 500);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(view, BorderLayout.CENTER); // BorderLayout
        this.setVisible(true);
    }

    public static void main(String[] args) {
        Main m = new Main();
    }
}

View:

public class View extends JPanel {

    public View() {
        JTabbedPane tpane = new JTabbedPane();
        JPanel panel = new JPanel();
        panel.add(new JButton("Button 1"));
        tpane.addTab("Tab1", panel);

        JPanel panel2 = new JPanel();
        panel2.add(new JButton("Button 2"));
        tpane.addTab("Tab2", panel2);

        this.add(tpane, BorderLayout.CENTER); // BorderLayout
    }
}

Solution

  • The frame has a border layout, the panel has a flow layout.

    • A component added to a border layout with no constraint ends up in the CENTER & will be stretched to the available height and width.
    • A component added to a flow layout will maintain its natural size.

    More generally, don't set the size of a top level container. It is better to call pack() which will make the TLC the exact size needed to accommodate the components within. To add white space to a GUI, use layout constraints (not especially relevant when the layout only has a single component), or borders. See this answer for a working example.


    Edit

    I set a BorderLayout to both, Main and View. But the result remained the same.

    This is the result of changing the layout of the View as seen here.

    enter image description here

    import java.awt.BorderLayout;
    import javax.swing.*;
    
    public class Main extends JFrame {
    
        View view = new View();
    
        public Main() {
            this.setSize(500, 500);
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.add(view);
            this.setVisible(true);
        }
    
        public static void main(String[] args) {
            Main m = new Main();
        }
    }
    
    class View extends JPanel {
    
        public View() {
            super(new BorderLayout()); // Just 1 line difference!
            JTabbedPane tpane = new JTabbedPane();
            JPanel panel = new JPanel();
            panel.add(new JButton("Button 1"));
            tpane.addTab("Tab1", panel);
    
            JPanel panel2 = new JPanel();
            panel2.add(new JButton("Button 2"));
            tpane.addTab("Tab2", panel2);
    
            this.add(tpane);
        }
    }