Shane A. Darr
Shane A. Darr

Reputation: 521

When to use JFrame or JPanel

I am new to GUI programming in Java and have a couple questions about when to use which tools.

When my application is run I have a JFrame that comes up and uses the content panel to show the user 3 buttons. I would like each button to display a different screen but not open in a separate window. To accomplish this I am currently disposing the current JFrame and creating a new JFrame with the new content. Here are my questions.

  1. Should I be creating a new JPanel for each of the button clicks instead of creating a new JFrame? If the answer to this question is a matter of opinion, are there generally accepted best practices?

  2. When closing a JFrame or JPanel when is it appropriate to use setVisible(false) vs .dispose()?

Upvotes: 0

Views: 1927

Answers (3)

aw-think
aw-think

Reputation: 4803

Should the buttons stay at the JFrame after switching to an other screen? If yes, use an BorderLayout for the ContentPane and add the 3 Buttons at an own JPanel to the BorderLayout.NORTH. Use 3 JPanels for your custom screens and add them to the BorderLayout.CENTER.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ThreeButtonExample extends JFrame {

  private JPanel current;
  private JPanel screen1 = new JPanel();
  private JPanel screen2 = new JPanel();
  private JPanel screen3 = new JPanel();

  public ThreeButtonExample(String title) {
    super(title);
    setMinimumSize(new Dimension(400, 300));

    getContentPane().setLayout(new BorderLayout());

    JPanel buttonPane = new JPanel();

    JButton btnScreen1 = new JButton("Screen 1");
    JButton btnScreen2 = new JButton("Screen 2");
    JButton btnScreen3 = new JButton("Screen 3");

    btnScreen1.setActionCommand("Screen 1");
    btnScreen2.setActionCommand("Screen 2");
    btnScreen3.setActionCommand("Screen 3");

    buttonPane.add(btnScreen1);
    buttonPane.add(btnScreen2);
    buttonPane.add(btnScreen3);

    screen1.setBackground(Color.red);
    screen2.setBackground(Color.green);
    screen3.setBackground(Color.blue);

    btnScreen1.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        changePanel(e);
      }
    });

    btnScreen2.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        changePanel(e);
      }
    });

    btnScreen3.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        changePanel(e);
      }
    });

    getContentPane().add(buttonPane, BorderLayout.NORTH);
    current = screen1;
    getContentPane().add(screen1, BorderLayout.CENTER);

    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

  public void changePanel(ActionEvent e) {
    getContentPane().remove(current);
    switch (e.getActionCommand()) {
      case "Screen 1":
        getContentPane().add(screen1, BorderLayout.CENTER);
        current = screen1;
        break;
      case "Screen 2":
        getContentPane().add(screen2, BorderLayout.CENTER);
        current = screen2;
        break;
      case "Screen 3":
        getContentPane().add(screen3, BorderLayout.CENTER);
        current = screen3;
        break;
    }
    this.revalidate();
    this.repaint();
  }

  public static void main(String[] args) {
    ThreeButtonExample tbe = new ThreeButtonExample("3 Button Test");
    tbe.pack();
    tbe.setVisible(true);
  }

}

Upvotes: 0

NESPowerGlove
NESPowerGlove

Reputation: 5496

  1. You can use a CardLayout to switch to a completely different view of components, or you could also define different JPanels (keeping or creating anew would be based on the design of what they interact with or are made up of) and add and remove them from the JFrame as required. CardLayout however is designed for this so I would suggest looking into that first.

    Creating a new JFrame should be confusing for the user, especially if you don't keep track of the frame's previous position on their monitor or custom size set by the user. I would also imagine there would be a sort of flicker that would happen as one frame disappears before the next appears.

  2. You should call setVisible(true) on your JFrame when you have set all of it's attributes and have added all the components that you will add. Part of setVisible() as you can see in the method documentation is that it will align all of your components, so if you call it and then after add components, you may only see some of your components visible.

    You should not really ever need to call setVisible(false), or dispose() in usual cases.

Upvotes: 3

Lukas Hieronimus Adler
Lukas Hieronimus Adler

Reputation: 1094

I will also try to explain it.

JFrame - Used to represent the stuff a window should have. This includes borders (resizeable y/n?), titlebar (App name or other message), controls (minimize/maximize allowed?), and event handlers for various system events like 'window close' (permit app to exit yet?).

JPanel - Generic class used to gather other elements together. This is more important with working with the visual layout or one of the provided layout managers e.g. gridbaglayout, etc. For example, you have a textbox that is bigger then the area you have reserved. Put the textbox in a scrolling pane and put that pane into a JPanel. Then when you place the JPanel, it will be more manageable in terms of layout.

Upvotes: 2

Related Questions