switching between multiple JPanels in CardLayout - java

I'm working on a game and I am using a CardLayout to switch between different JPanels in the same JFrame.
Problem: I have a helpPanel that I can go to pushing a button in the main-menuPanel and pushing a button in the gamePanel.
What I want:
I want to be able to place a JButton in my helpPanel that (when pressed) goes back to the main-menuPanel or the gamePanel (depending if you came from the main-menuPanel or from the gamePanel).
What I've tried: I've tried using the actionlistener in combination with .previous(container parent) but that only takes me back to the JPanel that was added to the CardLayout in the position previous to the helpPanel. I've also tried nesting the actionListeners to try and get different situations but that didn't work.
What I searched: I've searched for solutions in other Questiones but it's always about switching between 2 different JPanels in stead of 3.
Can anyone help me please? I find it to be a very difficult situation.

Read the section from the Swing tutorial on How to Use Card Layout. It shows you how to switch between cards by specifying a String that identifies the card to display.

I have been working on a game menu recently(which you'll see bits and pieces of here), and one way to do it is to have a common ActionListener for all the panel's buttons within. then set their action commands to have specific Strings.
in this example, overallgame is the master CardLayout panel. GAME, CREDITS, and MAIN-MENU are String constants used to title panels inside the overallgame panel
ActionListener listener=new ActionListener()
{public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("start")){
//dummyframe.add(newgame);
//mainmenupanel=null;
CardLayout layout=(CardLayout)(overallgame.getLayout());//retrieves the overall layout
layout.show(overallgame, GAME);//uses it to switch to main game panel
newgame.requestFocus(true);//need to redirect focus to the game rather than original main menu
dummyframe.repaint();
}
else if(e.getActionCommand().equals("show credits")){
CardLayout layout=(CardLayout)(overallgame.getLayout());
layout.show(overallgame, CREDITS);
}
else if(e.getActionCommand().equals("switch to main")){
CardLayout layout=(CardLayout)(overallgame.getLayout());
layout.show(overallgame, MAIN_MENU);
}
else if(e.getActionCommand().equals("show chapter panel")){
CardLayout layout=(CardLayout)(overallgame.getLayout());
layout.show(overallgame, CHAPTERSTART);
}
else{
JOptionPane.showMessageDialog(null, "hey");
}
}
};​
as you can see, the above ActionCommands used are specific Strings. you can set a JButton to have an ActionCommand like "start" with a line like this(with using my pre-defined listener, that will switch to panel with my in-progress game)
, causing the NewGame JButton to have an ActionEvent with the ActionCommand, "start" whenever clicked.
NewGame.setActionCommand("start");​
to make a panel have a title that can be used by the CardLayout, you have to define the name when adding the panel to the CardLayout. this line adds a JPanel called mainmenupanel to my overallgame JPanel, and then allows the overallgame panel to refer to it with the String constant MAIN_MENU.
overallgame.add(mainmenupanel, MAIN_MENU);​
as you can see, conditionally analyzing your pre-set ActionCommands on an overridden ActionListener to then use the CardLayout to show a particular JPanel is a good way to do what you want.
Hope this helps!(I just did this recently too, so I was at a loss for a while, too).
feel free to comment to ask questions if I wasn't completely clear

Related

JPanel deforms my Layout

Im using NetBeans to do a work for school. There i have an huge JPanel that contains a huge JFrame. That JFrame as 5 small JFrames, 1 is the menu with buttons, the other ones are boxes with text that will swap when i choose in the buttons.
When one box is showing the other ones are invisible im using the following code (dont know if it is the best):
public ConversorUI() {
initComponents();
PanelVazio.setVisible(true);
PanelTemp.setVisible(false);
PanelComp.setVisible(false);
PanelMoedas.setVisible(false);
this.pack();
}
My problem is, when i run my program i have a big space with nothing and only below it the components appear. I want them to appear in the top of my window. What can I do ?
ANSWER
After some time searching i just realized i could Set Layout from JPanel to Card Layout and create JPanels over each other activating them with the code:
private void DinheiroButtonActionPerformed(java.awt.event.ActionEvent evt) {
//Remove Panels
CAIXA.removeAll();
CAIXA.repaint();
CAIXA.revalidate();
//Add Panels
CAIXA.add(DinheiroBox);
CAIXA.repaint();
CAIXA.revalidate();
}
Looks like you are using Java Swing , right ?
Any way you do something wrong if you have JPanel that contains JFrames. To build correct UI you have to add JPanels inside JFrame.
Also, to reach correct component order and placing you need configure corresponded layout, here is description.
You can load one jframe at e time
Because every jframe you added have own place and visibility doesnt do anything to remove
Try to save every jframe and for changing
Delete old one and add new one
Why are you using multiple JFrames to do this? From what I can see it would be a better idea to use JPanels that can take care of the individual tasks, such as the menu and buttons etc.
I'm relatively new to using javax.swing myself, but from my knowledge you can only have 1 frame at a time per window (like the other person said).
From what i've been able to discern from your project, you possibly don't even need multiple panels. You just need one panel for the menu with buttons, and multiple Labels or JLabels that display text according to the button. You can use the setText method in writing your addActionListener, something like this:
buttonName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
labelName.setText("blah blah blah");
//and whatever else you may need to do
}
});

How to access JFrame components from a JPanel class?

I'm working on a GUI assignment and I encountered a problem that I cannot figure out. I have a JFrame with multiple JPanels, one of those JPanels contains a CardLayout with multiple JPanels. Since we are more people working on the project we decided to make a separate class (that extends JPanel) for each panel that's gonna be inside the CardLayout.
The problem is accessing components of the JFrame from the JPanel classes.
To give you an example, I have a JLabel somewhere in the JFrame that serves as a status bar and I want to change the text of the status bar when a button is pressed on the SaleMain panel (a class SaleMain that extends JPanel, contained in the CardLayout).
Another example, inside another panel EditCustomer (also a JPanel class, included in the CardLayout), I'd like to have a button with an action listener that will change the current panel (the one containing the button) to a different panel from the CardLayout.
Hope I made it as clear as possible, thank you guys in advance for helping me :)
The model / view / controller pattern (MVC) is useful for creating a GUI. By separating your model from your view, you can concentrate on one part of your GUI at a time.
You create a model for your GUI that contains the information you want to present on your GUI.
I have a JLabel somewhere in the JFrame that serves as a status bar and I want to change the text of the status bar when a button is pressed on the SaleMain panel
Put the text in your model, and in the action listener for the button, you have the text put in the status bar.
I'd like to have a button with an action listener that will change the current panel (the one containing the button) to a different panel from the CardLayout.
Then do so. The action listener is a controller that can change the view.
Take a look at my article, Dice Game, to see how a Java Swing application implements the MVC pattern and JPanel switching.

Enumerating all controls on JFrame

I am quite new to Java and am trying to set the visible property to false for all JPanels
on my JFrame (frame.)
When I execute the following, It returns null to console:
public void mouseClicked(MouseEvent e){
for (Component c : frame.getComponents()) {
System.out.println(c.getName());
if (c instanceof JPanel) {
((JPanel)c).setVisible(false);
}
}
panelDispatch.setVisible(true);
panelDispatch.requestFocus();
}
What I want it to do is set all the panels visibility to false then
set the selected panels visibility to true.
3 JPanels are added to frame.
What am I doing wrong here?
Any help would be greatly appreciated.
Components are added to a ContentPane of a JFrame rather than the RootPane. You're seeing null displayed to the console as you probably havent set the name property of the component
for (Component c : getContentPane().getComponents()) {
I can't tell why you're seeing null, and I'm not sure in what way you're seeing it, a NullPointerException perhaps, but I do know that you appear to be removing the JFrame's contentPane, glassPane and rootPane inadvertently, a dangerous thing to do. Instead just use a CardLayout that should allow you to easily and simply swap your GUI views as this is exactly what CardLayout was built for. Please check out the CardLayout Tutorial for more information.
Edit
For examples of CardLayout-using GUI's, please check out:
getting Jcomponent from other class changes frame size
Java CardLayout Main Menu Problem
Change size of JPanel using CardLayout
Java CardLayout JPanel moves up, when second JPanel added
Java swing; How to toggle panel's visibility?
Clear components of JFrame and add new componets on the same JFrame
gui multiple frames switch
JLabel displaying countdown, java
This one is unusual in that it uses a CardLayout and has one panel fading into the other panel:
CardLayout showing two panels, flashing.

Adding content to a JPanel

I'm new to Java and actually designing the GUI for an application.
My main is a JFrame with 5 buttons and 1 panel which will have the "content", for the first button for example, I've designed a Jframe which has a JTabbedPane.
Now I would like to know how can I incorporate the content from that frame to the "content" panel when clicking on the button ?
I tried to use .add but I get:
java.lang.IllegalArgumentException: adding a window to a container
(seems we can't add Jframe to Jpanel).
I also tried the setVisible way but it doesn't meet what I need since it will hide the panel completely and I will get a tiny window with the buttons.
![Jframe content][1]
![Main Jframe with buttons and Jpanel to show the jframe content][2]
The code is generated by netbeans, and I forgot to mention that I did research on adding a Jframe into another Jframe but here isn't my problem at all.
I tried by changing the Jframe by JInternalFrame but clicking on button doesn't do anything.
Button has
contentPanel.add(new GestionUtilisateur());
So basically when you click on the "Gestion Utilisateur" button for example, you get that JTabbedPane that has to appear in the content area (which is blank here)
You should not be putting JFrames inside JPanels. If you have multiple panels you would like to display, depending on something like a button, look in to LAYOUTS.
In particular, it sounds like a CardLayout would work well for your needs. CardLayouts allow you to swap which panel is displayed in a frame by bringing it to the "front" of a list of panels. This would let you display your JTabbedPane on one button click, then click another to change the content pane.
JFrame can not be added in a JPanel.
use JInternalFrame
Make and hold references to JPanels containing your content. A JFrame is really just that, it's a frame (though you can add a single component to it).
You can't add a JFrame to a JPanel. If you want multiple components to be visible use layouts such as BorderLayout, GridBag, etc. Check out some of the Swing layout tutorials here.
Content should be designed as JPanel (you can design it with drag&drop just like JFrame) but if you really have to put a JFrame to JPanel for some reason, you can do it by
myJPanel.add(myJFrame.getContentPane());
however i would suggest modification of your program.

Java multiple GUI windows creation

I have made a simple GUI using a GridLayout(5,3) , it is action performed and it implements action listener as well. The are some calculation and algorithms that working according to what inputs or buttons the user provides. Everything works just fine up to this point.
At some point in my code, the user gets a pop up massage that he is correctly logged in to the system using this common method JOptionPane.showMessageDialog(....) . All i want is, after he press the OK button, is to create an additional form that pop ups, and looks similar to the one above i made with GridLayout(5,3) so that my user can store additional info about him.
I really cant get it to work, and i have no idea how to start this.
Any ideas are very welcomed! Cheers and thanks in advance :)
if add this:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = getContentPane();
GridLayout grid=new GridLayout(10,1);
pane.setLayout(grid);
it only adds more lines to my gridlayout. And all above buttons and labels remains. How can i get rid of the previous labels and buttons?
You state:
if add this:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = getContentPane();
GridLayout grid=new GridLayout(10,1);
pane.setLayout(grid);
it only adds more lines to my gridlayout. And all above buttons and labels remains. How can i get rid of the previous labels and buttons?
You have at least three options if you want to swap "views" on the JFrame.
If you want to use the same GUI with the same JTextComponents but have the components empty of text, then you'll need to go through your text components and call setText("") on all of them. If you want to keep the same JButtons and labels but change their text, then similarly you will need to go through all of them calling setText("something else").
If you want totally new components to replace the old ones, the most straight forward way I believe is to use a CardLayout to hold your JPanel that has all your components. When you want to swap the JPanel for another, make sure that the new JPanel has been added to the CardLayout-using JPanel and then call next() on the CardLayout object.
Another way is to manually swap out JPanels held by the JFrame's contentPane by calling removeAll() on the contentPane, then add(nextJPanel) on it, then revalidate(), then repaint().

Categories