tags:

views:

226

answers:

3
+2  Q: 

Java Swing design

Hello, I have a question regarding coding a Swing UI. If I want to make a software with some option e.g. on the first Frame I have three buttons (New, Option, Exit).

Now if a user clicks the new button, I want to change the entire content in the Frame to something else. I know I have to use addActionListener to that button. But my question is how to change the contents in the frame. Creating new Frames and then use setVisible() isn't an option for me.

And to use frame.remove() all the objects seems awkward if it is several things that needs to be removed. Or is it the right way?

+7  A: 

Look into the Card Layout. I would also probably use menu items instead of buttons.

camickr
frame.remove() is not ideal.CardLayout is the correct answer.
Milan Ramaiya
Hey camickr, I'm surprised you're not harassing this person for the SSCCE.... WOW!!
Dan
+1  A: 

You may use frame.remove()

The difference is that you may remove a whole panel instead of removing "several" things, and you just replace it with a new panel

frame.add( mainPanel );
...
// in the action listener 
frame.remove( mainPanel );
frame.add( theNewPage );

The point is, you don't have to be afraid of removing awkwardly things in the main frame, for you have to place all those things into a single panel and then just change panels.

UPDATE

I've made the code needed to test what I'm talking about.

Here's a running sample:

alt text

later

alt text

Here's the running sample:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class ChangePage {
    JComponent mainPage;
    JComponent newPage;
    JFrame     frame;

    public static void main( String [] args ) {
        ChangePage changePageDemo = new ChangePage();
        changePageDemo.show();
    }
    private void show(){
        frame = new JFrame("Demo");
        frame.add( getMainPage() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }
    private JComponent getMainPage() {
        if( this.mainPage != null ) {
            return this.mainPage;
        }
        this.mainPage = new JPanel(new BorderLayout());
        mainPage.add( new JLabel("Choose an option") );
        mainPage.add( new JPanel(){{
            add( new JButton("New"){{
                addActionListener( new ActionListener(){
                    public void actionPerformed( ActionEvent e ){
                        SwingUtilities.invokeLater( new Runnable(){
                            public void run(){
                                frame.remove( getMainPage() );
                                frame.add( getNewPage() );
                                //frame.setContentPane( getNewPage() );
                                frame.pack();

                            }
                        });
                    }
                });
            }});
            add( new JButton("Options"));
            add( new JButton("Exit"));
        }}, BorderLayout.SOUTH );
        return this.mainPage;

    }
    private JComponent getNewPage() {
        if( newPage != null ) {
            return newPage;
        }
        this.newPage = new JPanel();
        this.newPage.add( new JLabel("<html>This is the \"new\" page.<br> Do you like it?<br></html>"));
        this.newPage.add( new JButton("Return"){{
            addActionListener( new ActionListener(){
                public void actionPerformed( ActionEvent e ){
                    SwingUtilities.invokeLater( new Runnable(){
                        public void run(){
                            frame.remove( getNewPage() );
                            frame.add( getMainPage() );
                            //frame.setContentPane( getMainPage() );
                            frame.pack();

                        }
                    });
                }
            });
        }});
        return this.newPage;
    }

}

Alternatively you may use setContentPane :)

OscarRyz
What's with the downvote?
OscarRyz
@Oscar - You probably received a down vote due to the fact that frame.remove is not the correct way to solve this. See camickr's answer for the correct way (CardLayout). Note: I did not down vote you.
JasCav
@Jason: Probably. That's fine, I mean I think it would be better if the downvoter explains what's wrong with my answer. Just to understand. Actually your comment make sense.
OscarRyz
+4  A: 

CardLayout is indeed the better choice in this case; but, when the occasion demands, a Component may be removed from a Container using either the remove() or removeAll() method. Afterward, the essential step is to invoke the validate() method to lay out the container's subcomponents again. Oscar Reyes' example uses the Frame's pack() method, inherited from Window, to achieve this effect. In this example, the resetGame() method reconstructs the display panel in a similar way.

trashgod
+1 for referencing my answer :)
OscarRyz
Good illustrations!
trashgod