Search code examples
javaswinguser-interfacejpaneljlabel

Can objects from a certain class output identically formatted JPanels with unique JLabels?


I have a PanelCreator class that has a constructor which inputs two strings and turns them into JLabels. It also has a method that returns a panel with these labels.

private JLabel string1, string2;
private JPanel panel;

PanelCreator(String input1, String input2)
{
    panel = new JPanel();
    string1 = new JLabel();
    string1.setText(input1);

    string2 = new JLabel();
    string2.setText(input2);

    panel.add(string1);
    panel.add(string2);
}

JPanel createPanel()
{
    return panel;
}

The problem I'm facing is that the main method will only show the most recent panel created from createPanel(). It's as though panel2 overwrites panel1 when I really need them both to appear next to each other in the frame.

    JFrame f = new MultiplePanelTest();

    PanelCreator panelCreator1 = new PanelCreator("Test1-1", "Test1-2");
    JPanel pane1 = panelCreator1.createPanel();
    f.add(pane1);

    PanelCreator panelCreator2 = new PanelCreator("Test2-1", "Test2-2");
    JPanel pane2 = panelCreator2.createPanel();
    f.add(pane2);

I know that components in a swing GUI can only be used once, so I'm assuming the problem is with the PanelCreator objects referencing the same JLabels. I thought that making this a class and then pulling objects from it would make each object have its own unique JLabels, but I seem to be wrong on that.

Is there a way to fix this problem so that there are 2 identical panels each with their own JLabels? The stretch goal is to manipulate the text of the labels through the PanelCreator object itself without changing any of the formatting (since the two panels will hold their own data but look identical formatting wise in the GUI frame).


Solution

  • Each panel is created correctly, but they are both added directly to the JFrame frame, which has a BorderLayout by default. So they are both added to the center of the frame, overlaying each other.

    This is basically equivalent to:

    f.add(pane1, BorderLayout.CENTER);
    f.add(pane2, BorderLayout.CENTER);
    

    ... which is obviously wrong!

    So if you want the panels side by side, try:

    f.add(pane1, BorderLayout.WEST);
    f.add(pane2, BorderLayout.EAST);
    

    Or one above the other:

    f.add(pane1, BorderLayout.NORTH);
    f.add(pane2, BorderLayout.SOUTH);
    

    As mentioned in the comments, you could also modify the frame's layout manager, if you are not happy with BorderLayout. For example:

    f.setLayout(new FlowLayout());
    f.add(pane1);
    f.add(pane2);