I need to have one JPanel opened on start. I have a button on that one to open to another JPanel which contains a button to bring me back. How do i write action listeners for those buttons. I have searched extensively. Do I need a JFrame? All examples seem to have it.
Regardless of which approach you might take, the basic idea is the same. You need to know where to go based on where you are...
To this end, this simple example uses a simple navigation interface to provide movement control for the panels and a List to maintain the order of the components.
You could just as simply use a queue of some kind, pushing the next panel onto it and popping the last panel of it as you switched views.
This is a quick and simple example of CardLayout
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SwitchPanel extends JApplet{
private String currentView;
private List<String> viewNames;
#Override
public void init() {
final CardLayout cardLayout = new CardLayout();
setLayout(cardLayout);
Navigator navi = new Navigator() {
#Override
public void next() {
int index = viewNames.indexOf(currentView);
if (index > -1) {
index++;
if (index < viewNames.size()) {
currentView = viewNames.get(index);
cardLayout.show(getContentPane(), currentView);
}
}
}
#Override
public void previous() {
int index = viewNames.indexOf(currentView);
if (index > -1) {
index--;
if (index >= 0) {
currentView = viewNames.get(index);
cardLayout.show(getContentPane(), currentView);
}
}
}
};
MainPane mainPane = new MainPane(navi);
LastPane lastPane = new LastPane(navi);
viewNames = new ArrayList<>(2);
viewNames.add("main");
viewNames.add("last");
add(mainPane, "main");
add(lastPane, "last");
currentView = "main";
cardLayout.show(getContentPane(), "main");
}
public interface Navigator {
public void next();
public void previous();
}
public class MainPane extends JPanel {
private Navigator navigator;
public MainPane(Navigator navi) {
this.navigator = navi;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton btn = new JButton("Next >");
add(new JLabel("Main"), gbc);
add(btn, gbc);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
navigator.next();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class LastPane extends JPanel {
private Navigator navigator;
public LastPane(Navigator navi) {
this.navigator = navi;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton btn = new JButton("< Previous");
add(new JLabel("Last"), gbc);
add(btn, gbc);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
navigator.previous();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Related
I'm learning java swing, I have many buttons, but I need to put some new buttons in the red zone when I select something on my combobox, the problem is that I don't know how to use the buttons if those are not created at the beginning.
Here some buttons loaded when I select in the combobox, I need to make some actions with them:
thanks
Your question leaves a lot open to interpretation.
So, for example, if the values are fixed, I would start by separating them into individual panels, isolating their functionality and workflow, and simple swap them based on what is selected.
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JComboBox<String> comboBox = new JComboBox<>();
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
model.addElement("Option A");
model.addElement("Option B");
comboBox.setModel(model);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(8, 8, 8, 8);
add(comboBox, gbc);
CardLayout cardLayout = new CardLayout();
JPanel buttonOptions = new JPanel(cardLayout);
buttonOptions.add(new OptionAPane(), "optionA");
buttonOptions.add(new OptionBPane(), "optionB");
gbc.gridy = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(buttonOptions, gbc);
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
switch (comboBox.getSelectedIndex()) {
case 0:
cardLayout.show(buttonOptions, "optionA");
break;
case 1:
cardLayout.show(buttonOptions, "optionB");
break;
}
}
});
}
}
public class OptionAPane extends JPanel {
public OptionAPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
gbc.insets = new Insets(8, 8, 8, 8);
JButton btnThis = new JButton("This");
btnThis.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Do this");
}
});
JButton btnThat = new JButton("That");
btnThis.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Do that");
}
});
add(new JLabel("A Options"), gbc);
add(btnThis, gbc);
add(btnThat, gbc);
}
}
public class OptionBPane extends JPanel {
public OptionBPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
gbc.insets = new Insets(8, 8, 8, 8);
JButton btnOther = new JButton("Other");
btnOther.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Do other");
}
});
JButton btnSomethingElse = new JButton("Something else");
btnOther.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Do something else");
}
});
add(new JLabel("B Options"), gbc);
add(btnOther, gbc);
add(btnSomethingElse, gbc);
}
}
}
But how do I know when a button is clicked.
This is where an observer pattern would be used. You'd define one or more listeners, based on the needs of each panel and when a button on a panel is clicked, this listener would trigger an event and you could make use of it
If, on the other hand, you need something a little more dynamic (ie each option can have different actions based on some other configuration), you might be able to make use of the Action API
For example...
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ActionGroup {
private String description;
private List<Action> actions;
public ActionGroup(String description) {
this.description = description;
this.actions = new ArrayList<>(25);
}
public ActionGroup(String description, List<Action> actions) {
this.description = description;
this.actions = actions;
}
public String getDescription() {
return description;
}
public void add(Action action) {
actions.add(action);
}
public void remove(Action action) {
actions.remove(action);
}
public List<Action> getActions() {
return Collections.unmodifiableList(actions);
}
}
public class SimpleAction extends AbstractAction {
// You have a number of choices when using something like Action,
// You can create a custom Action based on your needs and pass
// in the information it needs to do it's job OR, you can use
// a observer pattern to get notified when the ActionListener
// is triggered
public SimpleAction(String name) {
putValue(NAME, name);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(getValue(NAME) + " was triggered");
}
}
public class ActionGroupCellRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value instanceof ActionGroup) {
value = ((ActionGroup)value).getDescription();
}
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
ActionGroup optionA = new ActionGroup("Option A");
optionA.add(new SimpleAction("Cat"));
optionA.add(new SimpleAction("Doggy"));
optionA.add(new SimpleAction("Bunny"));
optionA.add(new SimpleAction("Rat"));
optionA.add(new SimpleAction("Cow"));
ActionGroup optionB = new ActionGroup("Option B");
optionB.add(new SimpleAction("Banana"));
optionB.add(new SimpleAction("Apple"));
optionB.add(new SimpleAction("Pear"));
optionB.add(new SimpleAction("Orange"));
optionB.add(new SimpleAction("Lemon"));
JComboBox<ActionGroup> comboBox = new JComboBox<>();
comboBox.setRenderer(new ActionGroupCellRenderer());
DefaultComboBoxModel<ActionGroup> model = new DefaultComboBoxModel<>();
model.addElement(optionA);
model.addElement(optionB);
comboBox.setModel(model);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(8, 8, 8, 8);
add(comboBox, gbc);
gbc.gridy = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
ActionGroupPane buttonOptions = new ActionGroupPane();
buttonOptions.setActionGroup(optionA);
add(buttonOptions, gbc);
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object item = comboBox.getSelectedItem();
if (item instanceof ActionGroup) {
System.out.println(item);
buttonOptions.setActionGroup((ActionGroup)item);
}
}
});
}
}
public class ActionGroupPane extends JPanel {
public ActionGroupPane() {
setLayout(new GridBagLayout());
}
public void setActionGroup(ActionGroup actionGroup) {
removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
gbc.insets = new Insets(8, 8, 8, 8);
add(new JLabel(actionGroup.getDescription()), gbc);
for (Action action : actionGroup.getActions()) {
add(new JButton(action), gbc);
}
revalidate();
repaint();
}
}
}
Action is very powerful and I would recommend taking some time to have look at How to Use Actions
So I'm using cardLayout in one of my programs and I'm trying to make it so that when you click a button the next panel loads. I have a panelHolder class where the cardlayout is held and every time the button on the panel is pressed, it would call a method in the panelHolder class that depending on the button sets a certain boolean variable to true and calls repaint (where the panels are shown). For some reason my button isn't working and I can't seem to find out why. Can someone help me?
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.Arrays;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
public class SheetReader101 extends JFrame {
public SheetReader101(){
super("SheetReader101");
setSize(2000,1000);
setLocation(0,0);
setResizable(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
PanelHolder pg2 = new PanelHolder();
setContentPane(pg2);
setVisible(true);
}
public static void main(String[]args){
SheetReader101 z1 = new SheetReader101();
}
}
class PanelHolder extends JPanel { // HERE
CardLayout clayout = new CardLayout();
PianoGameContent x;
tutorial y;
boolean [] paneldecide;
PanelHolder() {
super();
y = new tutorial();
x = new PianoGameContent();
setLayout(clayout);
this.add("Tutorial", y);
this.add("FreePlay Mode", x);
paneldecide = new boolean[15];
}
public static void main(String[]args){
PanelHolder z1 = new PanelHolder();
z1.run();
}
public void run(){
layoutShower(0);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
}
public void layoutShower (int decide){
{
PianoGameContent y2 = new PianoGameContent();
PanelHolder.this.add("Piano", y2);
System.out.println("intro slide run");
if(decide == 1){
PanelHolder.this.add("Piano", y2);
System.out.println("testing11");
clayout.show(PanelHolder.this,"Piano");
}
}
}
}
I "suspect" that the core problem has to do with the original code you posted, where you're making a new instance of PanelHolder in your child view's ActionListener and then are attempting to switch views, this new instance has no relationship to the instance that is on the screen.
There are a few ways you can manage CardLayout, my preferred way is to use some kind of "navigation" controller which defines how navigation works, for example, you could have "next" and "previous" or "back", or you could define the actual views that can be displayed, ie showMenuView, showTutorialView etc, depending on how much control you want to give your sub views.
The following is a simple example which demonstrates the basic idea, it uses a enum to define the available views (as it has more meaning than 0, 1... and I don't need to remember the actual names of the views, the IDE can provide auto correct for that ;))
I create and add each view up front when I create the PanelHolder, I also pass each view an instance of the NavigationController, so they can interact with it
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JavaApplication1013 {
public static void main(String[] args) {
new JavaApplication1013();
}
public JavaApplication1013() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PanelHolder());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum View {
MENU,
TUTORIAL,
FREEPLAY;
}
public interface NavigationController {
public void showView(View view);
}
public class PanelHolder extends JPanel implements NavigationController {
private CardLayout cardLayout;
public PanelHolder() {
cardLayout = new CardLayout();
setLayout(cardLayout);
add(new MenuView(this), View.MENU.name());
add(new TutorialView(this), View.TUTORIAL.name());
add(new FreePlayView(this), View.FREEPLAY.name());
}
#Override
public void showView(View view) {
cardLayout.show(this, view.name());
}
}
public abstract class ViewPane extends JPanel {
private NavigationController controller;
public ViewPane(NavigationController controller) {
this.controller = controller;
}
public NavigationController getController() {
return controller;
}
protected void showView(View view) {
controller.showView(view);
}
}
public class MenuView extends ViewPane {
public MenuView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
JButton tut = new JButton("Tutorial");
JButton freePlay = new JButton("Free Play");
add(tut, gbc);
add(freePlay, gbc);
tut.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showView(View.TUTORIAL);
}
});
freePlay.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showView(View.FREEPLAY);
}
});
}
}
public class TutorialView extends ViewPane {
public TutorialView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton menu = new JButton("Menu");
add(new JLabel("Tutorial"), gbc);
add(menu, gbc);
menu.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showView(View.MENU);
}
});
}
}
public class FreePlayView extends ViewPane {
public FreePlayView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton menu = new JButton("Menu");
add(new JLabel("Free Play"), gbc);
add(menu, gbc);
menu.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showView(View.MENU);
}
});
}
}
}
Take a closer look at How to Use CardLayout for more details
Scaled back a sample I found to test working with JPanel and JLabel.
A new TransferHandler object is created for the createTransferable() call for both JPanel and JLabel.
Since there is no setDraggable method so I included the exportAsDrag (which is what I think is required if the object doesn't have the setDraggable method).
Although createTransferable() returns null and won't really do anything I should at least get the println executed, but the code doesn't seem to enter that section which means neither the panel or label is seen as a draggable object.
What is the missing step to get this to be seen as a draggable object.
And if you have a panel with a bunch of labels is it recommended to make the panel draggable and sort out which label or make each individual label draggable?
import java.awt.*;
import java.awt.datatransfer.Transferable;
import javax.swing.*;
import java.awt.event.InputEvent;
public class DnDTransferableTest {
public static void main(String[] args) {
new DnDTransferableTest();
}
public DnDTransferableTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label1;
private JLabel label2;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weighty = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
label1 = new JLabel("Drag Me.");
add(label1, gbc);
label2 = new JLabel("Drag Me too.");
gbc.gridx++;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.NONE;
add(label2, gbc);
setTransferHandler(new TransferHandler()
{
#Override
public Transferable createTransferable(final JComponent c)
{
System.out.println("Inside Panel : createTransferable");
return null;
}
#Override
public int getSourceActions(final JComponent c)
{
System.out.println("Inside Panel : getSourceActions()");
return COPY;
}
#Override
public void exportAsDrag(final JComponent comp, final InputEvent e, final int action)
{
System.out.println("Inside Panel : getSourceActions()");
super.exportAsDrag(comp, e, action);
}
});
label1.setTransferHandler(new TransferHandler()
{
#Override
public Transferable createTransferable(final JComponent c)
{
System.out.println("Inside Label : createTransferable");
return null;
}
#Override
public int getSourceActions(final JComponent c)
{
System.out.println("Inside Label : getSourceActions()");
return COPY;
}
#Override
public void exportAsDrag(final JComponent comp, final InputEvent e, final int action)
{
System.out.println("Inside Label : getSourceActions()");
super.exportAsDrag(comp, e, action);
}
});
}
}
}
I think that you will need a MouseListener to allow the JLabel to accept a drag gesture since it does not have a setDragEnabled(...) method.
To use a MouseListener with your DnD:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.TransferHandler;
public class DnDTransferableTest {
public static void main(String[] args) {
new DnDTransferableTest();
}
public DnDTransferableTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label3;
private JTextField textField = new JTextField(15);
public TestPane() {
label3 = new JLabel("Fubars Rule!");
add(label3);
add(Box.createHorizontalStrut(35));
add(textField);
label3.setTransferHandler(new TransferHandler("text"));
label3.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent mEvt) {
JComponent component = (JComponent) mEvt.getSource();
TransferHandler tHandler = component.getTransferHandler();
tHandler.exportAsDrag(component, mEvt, TransferHandler.COPY);
}
});
}
}
}
Hey Guys my problem is when I place the mouse on a JButton in my JFrame, I want it to show a list of JButtons on its left.
I don't known how to do that really I feel like I'm blocked and I cant make any progress in my project.
I'd would be grateful if you could help me and thanks in advance.
Can you create the list of buttons in a JPanel, add it to your JFrame and then call myPanel.setVisible(false). When you click your button then call myPanel.setVisible(true)?
As for ensuring that myPanel is positioned correctly you will want to use a Layout Manager
Or is there a more complex behaviour you want?
A basic option would be to use a MouseListener and a CardLayout. The MouseListener would be used to determine when the mouse cursor enters/exists a given component and the CardLayout would be used to display the appropriate sub component for each "menu" element.
I have to say, JButton would be me last choice for the "menu" item, in most cases, a JLabel would be preferred or even perhaps using a JMenu, which can can have sub menus, which can be displayed automatically might be a better choice, or even a JComboBox....
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShowStuff {
public static void main(String[] args) {
new ShowStuff();
}
public ShowStuff() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
MenuPane menu = new MenuPane();
menu.addMenu("Fruit", new FruitPane());
menu.addMenu("Meat", new MeatPane());
menu.addMenu("Dairy", new DairyPane());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(menu);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MenuPane extends JPanel {
private JPanel subMenu;
private JPanel menu;
private CardLayout cardLayout;
private MouseListener mouseHandler;
public MenuPane() {
setLayout(new BorderLayout());
cardLayout = new CardLayout();
subMenu = new JPanel(cardLayout);
menu = new JPanel(new GridBagLayout());
add(subMenu);
add(menu, BorderLayout.WEST);
subMenu.add(new JPanel(), "BLANK");
mouseHandler = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
if (e.getSource() instanceof JButton) {
JButton btn = (JButton) e.getSource();
cardLayout.show(subMenu, btn.getText());
}
}
#Override
public void mouseExited(MouseEvent e) {
cardLayout.show(subMenu, "BLANK");
}
};
}
public void addMenu(String name, JPanel subMenuPane) {
JButton button = new JButton(name);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
menu.add(button, gbc);
subMenu.add(subMenuPane, name);
button.addMouseListener(mouseHandler);
}
}
public abstract class ButtonPane extends JPanel {
private int gridy = 0;
public ButtonPane() {
setLayout(new GridBagLayout());
}
protected void addButton(String name) {
JButton btn = new JButton(name);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = gridy++;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(btn, gbc);
}
}
public class FruitPane extends ButtonPane {
public FruitPane() {
addButton("Banana");
addButton("Grapes");
addButton("Apples");
addButton("Tomatoes");
}
}
public class MeatPane extends ButtonPane {
public MeatPane() {
addButton("Lamb");
addButton("Beef");
addButton("Pork");
addButton("Mince");
}
}
public class DairyPane extends ButtonPane {
public DairyPane() {
addButton("Milk");
addButton("Cream");
addButton("Cheese");
addButton("Yoghurt");
}
}
}
From a variety of resources (this website, a book, a friend) I have managed to make a JFrame(JFrame1) that responds to a button. It makes another JFrame (JFrame2), and changes the JFrame.setVisible() to false.
What I'm trying to do is make it so that when a declared Back button is pressed, it closes JFrame2 and sets JFrame1 visibility to true. That's all fine, but when I do JFrame2.setVisiblity(false), JFrame2 is still visible. I've tried dispose(); but that doesn't work either.
I'm also wondering, since I've read on stackoverflow, that creating multiple JFrames is bad programming. So should I use JDialogs instead?
I am trying to display a bunch of information, and allow you to interact with the GUI to navigate around the information. The information would be arranged by alphabetical order.
Also, I'm not sure how to post code on here, so if you need to see what I currently have, just tell me how to post code :D
You are better of using a single frame, using something like JPanels to hold you UI components. This way you can simply switch it the panels as you need, possibly with something like CardLyout
By moving your UI to panels, you are also decoupling your code, giving your more flexibility and reuse potential.
Updated with basic example
This basically uses a simple model to change out different views. You could use a different style of model that listens to changes to the views and then makes choices on there behalf (which would generally be my preferred method), it depends on what you want to do...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CardLayoutDemo {
public static void main(String[] args) {
new CardLayoutDemo();
}
public CardLayoutDemo() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MasterPane());
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GameModel {
private JPanel view;
private JPanel lastView;
private JPanel currentView;
private WelcomePane welcomePane;
private GamePane gamePane;
private SettingsPane settingsPane;
public GameModel(JPanel view) {
this.view = view;
welcomePane = new WelcomePane(this);
gamePane = new GamePane(this);
settingsPane = new SettingsPane(this);
}
public void welcome() {
lastView = currentView;
view.removeAll();
view.add(welcomePane);
view.revalidate();
view.repaint();
currentView = welcomePane;
}
public void newGame() {
lastView = currentView;
view.removeAll();
view.add(gamePane);
view.revalidate();
view.repaint();
currentView = gamePane;
}
public void settings() {
lastView = currentView;
view.removeAll();
view.add(settingsPane);
view.revalidate();
view.repaint();
currentView = settingsPane;
}
public void back() {
if (lastView != null) {
view.removeAll();
view.add(lastView);
view.revalidate();
view.repaint();
currentView = lastView;
lastView = null;
}
}
}
public class MasterPane extends JPanel {
public MasterPane() {
setLayout(new BorderLayout());
GameModel model = new GameModel(this);
model.welcome();
}
}
public class WelcomePane extends JPanel {
private GameModel model;
public WelcomePane(GameModel gameModel) {
this.model = gameModel;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton btnStart = new JButton("New Game");
JButton btnSettings = new JButton("Settings");
add(new JLabel("Welcome"), gbc);
add(btnStart, gbc);
add(btnSettings, gbc);
btnSettings.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
model.settings();
}
});
btnStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
model.newGame();
}
});
}
}
public class SettingsPane extends JPanel {
private GameModel model;
public SettingsPane(GameModel gameModel) {
this.model = gameModel;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Go ahead, make some changes..."), gbc);
JButton back = new JButton("Back");
back.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
model.back();
}
});
add(back, gbc);
}
}
public class GamePane extends JPanel {
private GameModel model;
public GamePane(GameModel model) {
this.model = model;
setLayout(new GridBagLayout());
add(new JLabel("All your base are belong to us"));
}
}
}