Search code examples
javaswingjframejscrollpane

Where is my second JPanel going?


I'm trying to write a basic GUI application: it's just a scrollable window with text boxes and a few buttons. I've set up the JFrame and JScrollPane as follows:

public class MainFrame extends JFrame {
    public MainFrame() {
        this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
        JScrollPane scrollPane = new JScrollPane();
        JPanel contentPanel = new JPanel(); contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));

        contentPanel.setPreferredSize(new Dimension(600,1600));
        scrollPane.setViewportView(contentPanel);
        this.setContentPane(scrollPane);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        scrollPane.getViewport().add(new PCData());
        scrollPane.getViewport().add(Box.createRigidArea(new Dimension(0,100)));
        scrollPane.getViewport().add(new PCData());

        this.validate();
        this.setSize(625,800);
        this.setVisible(true);
    }

    public static void main(String[] args) {new MainFrame();}
}

Where the class PCData is the following:

public class PCData extends JPanel {
    public PCData() {
        this.setSize(new Dimension(600,300));
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        this.add(new JTextField());

        JPanel nameData = new JPanel();
        nameData.setLayout(new BoxLayout(nameData, BoxLayout.LINE_AXIS));
        nameData.add(new JTextField());
        nameData.add(Box.createRigidArea(new Dimension(5, 0)));
        nameData.add(new JTextField());
        this.add(nameData);
    }
}

I end up, however, with only one of the two PCData areas displayed, despite the preferred size. The content pane is not scrollable. However, if I remove the three lines:

//scrollPane.getViewport().add(new PCData());
//scrollPane.getViewport().add(Box.createRigidArea(new Dimension(0,100)));
//scrollPane.getViewport().add(new PCData());

the JScrollPane becomes scrollable again. Why does this happen, and how can I get both the PCData panels to be displayed? (Please note: I am looking for both why and how, not just how.)


Solution

  • scrollPane.getViewport().add(new PCData());
    scrollPane.getViewport().add(Box.createRigidArea(new Dimension(0,100)));
    scrollPane.getViewport().add(new PCData());
    

    Only a single component can be added to the viewport.

    So you need to create a panel. Add the 3 components to the panel. Then add the panel to the viewport.