Finding commands to replace a panel with another

advertisements

I am making a graphic program with swing that involves placing various panels with components on the frame. One of them is a panel with buttons that, when an option in an options menu is chosen, is entirely replaced with a different one that has different buttons. We've been thinking and it seems that the best way to do this would be to, each time the option is selected, to rebuild the frame from scratch.

This is the snippet of code in which I'm building the main panels:

import java.awt.Color;
import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

import com.jtattoo.plaf.graphite.GraphiteLookAndFeel;
import com.nacher.calc.Main;
import com.nacher.calc.controller.Controller;

import net.miginfocom.swing.MigLayout;

/**
 *
 * @author chema && Sergio
 * This Panel contains buttons and textbox to perform the calculator actions
 */
public class PanelCalculator extends JPanel implements PropertyChangeListener {
    private static final long serialVersionUID = -8377215712645516042L;

    private PanelNumbers panelNumbers;
    private PanelScreen panelScreen;
    private PanelOptions panelOptions;
    private PanelScientific panelScientific;

    public Controller controller;

    public PanelCalculator(Controller controller) {
        this.controller = controller;

        //Initialize JTattoo Library
        try{
            UIManager.setLookAndFeel(new GraphiteLookAndFeel());
        }catch(UnsupportedLookAndFeelException ulafe){
            System.out.println("JTattoo Graphite failed to set");
        }
        this.setLayout(new MigLayout("wrap"));
        buildComponents();
        situateComponents();

        //controller = new Controller();
        controller.addPropertyChangeListener(panelScreen);//panelScreen escucha al controller
        panelOptions.addPropertyChangeListener(controller);//controller escucha al panelOptions
        panelNumbers.addPropertyChangeListener(controller);//controller escucha al panelNumbers
        panelScreen.addPropertyChangeListener(controller);//controller escucha al panelScreen
    }

    private void buildComponents(){
        this.setPreferredSize(new Dimension(210, 280));
        this.setBorder(new EmptyBorder(0, 0, 0, 0));
        panelOptions = new PanelOptions();
        panelOptions.setBorder(new EmptyBorder(0, 0, 0, 0));
        panelOptions.setPreferredSize(new Dimension(200, 50));

        panelScreen = new PanelScreen();
        panelScreen.setBorder(BorderFactory.createEtchedBorder());
        panelScreen.setPreferredSize(new Dimension(200, 40));
        panelScreen.setBackground(new Color(255, 255, 255));

        panelNumbers = new PanelNumbers();
        panelNumbers.setBorder(new EmptyBorder(0, 0, 0, 0));
        panelNumbers.setPreferredSize(new Dimension(200, 185));

        panelOptions.addPropertyChangeListener(panelScreen);//panelScreen escucha al panelOptions
        panelNumbers.addPropertyChangeListener(panelScreen);//panelScreen escucha al panelNumbers
    }

    private void situateComponents(){
        this.add(panelOptions, "span");
        this.add(panelScreen, "span");
        this.add(panelNumbers, "span" );
    }

    /**
     * To build the Scientific Calculator
     */
    private void buildScientific() {
        //Instantiate the panelScientific
        panelScientific = new PanelScientific();
        panelScientific.setBorder(new EmptyBorder(0, 0, 0, 0));
        panelScientific.setPreferredSize(new Dimension(200, 185));
        //Reordering the Panel Calculator
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        String c = evt.getPropertyName();
        if (c.equals(Constants.SET_CALC_SCIENTIFIC)) {
            System.out.println("Set the Scientific Calculator");
            buildScientific();
        }
    }

}

And this is the main class where we build the frame:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import com.jtattoo.plaf.bernstein.BernsteinLookAndFeel;
import com.jtattoo.plaf.fast.FastLookAndFeel;
import com.jtattoo.plaf.graphite.GraphiteLookAndFeel;
import com.jtattoo.plaf.hifi.HiFiLookAndFeel;
import com.jtattoo.plaf.luna.LunaLookAndFeel;
import com.nacher.calc.controller.Controller;
import com.nacher.calc.ui.Constants;
import com.nacher.calc.ui.ImageConstants;
import com.nacher.calc.ui.PanelCalculator;

public class Main extends JFrame implements PropertyChangeListener {

    private static final long serialVersionUID = -4136829057174783241L;

    private static Main mySelf;
    private static PanelCalculator panelCalc;

    public static Controller controller;

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {

        controller = new Controller();
        panelCalc = new PanelCalculator(controller);
        controller.addPropertyChangeListener(panelCalc);
        mySelf = new Main();
        try {
            mySelf.setTitle("Calculator");
            mySelf.setLocationRelativeTo(null);
            mySelf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mySelf.setIconImage(new ImageIcon(mySelf.getClass().getResource(ImageConstants.CALC_IMAGE_THREE)).getImage());
            mySelf.getContentPane().add(panelCalc);
            mySelf.setResizable(false);
            mySelf.addWindowListener(new WindowAdapter(){
                public void windowClosing(WindowEvent e) {
                    System.out.println("Quitting the application.");
                }
            });
            mySelf.pack();
            mySelf.setVisible(true);
            controller.addPropertyChangeListener(mySelf);
        }catch(Exception ex) {
            System.out.println("The application could not run.");
            System.out.println(ex.getMessage());
            System.exit(-1);
        }
    }

What commands should I use to 'unbuild' the frame, then rebuild it from scratch? Is there a more efficient way to replace one panel with another?


The Card Layout was designed for this type of functionality. It allows you to define multiple panels to share the same space of the frame. You then just specify which panel is currently displayed.

Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.