Reputation: 8531
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?
Upvotes: 2
Views: 1471
Reputation: 205785
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()
](http://java.sun.com/javase/6/docs/api/java/awt/Container.html#validate()) method to lay out the container's subcomponents again. Oscar Reyes' example uses the Frame's [pack()
](http://java.sun.com/javase/6/docs/api/java/awt/Window.html#pack()) method, inherited from Window, to achieve this effect. In this example, the resetGame()
method reconstructs the display panel in a similar way.
Upvotes: 5
Reputation: 199215
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 http://img190.imageshack.us/img190/5206/capturadepantalla200912p.png
later
alt text http://img301.imageshack.us/img301/1368/capturadepantalla200912n.png
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
:)
Upvotes: 1
Reputation: 324108
Look into the Card Layout. I would also probably use menu items instead of buttons.
Upvotes: 5