There are 2 JPanels in my code. The first one is Furutsu7 which is the main JPanel which includes my game. The second JPanel is the start Jbutton. What I'm trying to accomplish is after the user clicks the Jbutton, the Furutsu7 JPanel will appear.
This is my setup class where I created the buttons.
public void setup(){
JFrame f = new JFrame("Start ");
JPanel card1 = new JPanel();
JPanel card2 = new JPanel();
cards = new JPanel(new CardLayout());
JButton Card1Button = new JButton("Start");
card1.add(Card1Button);
JButton Card2Button = new JButton("Exit");
card2.add(Card2Button);
cards.add(card1, "C1");
cards.add(card2, "C2");
f.add(cards, BorderLayout.CENTER);
f.setTitle("Furutsu");
f.setSize(500, 300);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
What I need help on is what should I put in my action performed in order to switch to the Furutsu JPanel.
public void actionPerformed(ActionEvent e) {
}
Make your CardLayout a field of the class so that you can more easily get to it in your actionPerformed method. Otherwise you would need to call (CardLayout) cards.getLayout(), a riskier thing to do. For example:
public class MyClass implements ActionListener {
private CardLayout cardLayout = new CardLayout();
private JPanel cards = new JPanel(cardLayout);
public void setup(){
JFrame f = new JFrame("Start ");
JPanel card1 = new JPanel();
JPanel card2 = new JPanel();
// cards = new JPanel(new CardLayout());
JButton Card1Button = new JButton("Start");
card1.add(Card1Button);
JButton Card2Button = new JButton("Exit");
card2.add(Card2Button);
cards.add(card1, "C1");
cards.add(card2, "C2");
f.add(cards, BorderLayout.CENTER);
f.setTitle("Furutsu");
f.setSize(500, 300);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
Then you can directly refer to it:
#Override
public void actionPerformed(ActionEvent e) {
// now you can call methods on your cardLayout variable:
cardLayout.show(...); // I'll leave it to you to figure out what to put in here
}
For more on CardLayout, please check out its tutorial
Note that if you just want to swap components in forward or backwards order, look at the other methods of CardLayout, such as next(cards) and previous(cards)
Related
I am using a card layout as a refreshing element on a JFrame and want to switch to a specific card after the user selects a button. Is there a way to call a specific card in the CardLayout on an action event?
public class ComboBoxTest() extends JFrame implements ActionListener {
JPanel comboBoxPane = new JPanel(); //use FlowLayout
JButton cb = new JButton("next");
cb.setActionCommand(next);
cb.addActionListener(this);
cb.setText("Forward");
this.add(cb);
comboBoxPane.add(cb);
JButton cb2 = new JButton("next");
cb2.setActionCommand(previous);
cb2.addActionListener(this);
cb2.setText("Back");
this.add(cb2);
comboBoxPane.add(cb2);
//Create the "cards".
card1 = new JPanel();
card1.add(HomeGui.getBody());
card2 = new JPanel();
card2.add(HomeGui.getSecondCard());
card3 = new JPanel();
card3.add(Start.getbody());
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, next);
cards.add(card2, previous);
Container base = getContentPane();
pane.add(header, BorderLayout.BEFORE_FIRST_LINE);
pane.add(comboBoxPane, BorderLayout.AFTER_LAST_LINE);
pane.add(cards);
}
public void actionPerformed(ActionEvent e) {
CardLayout c1 = (CardLayout)(cards.getLayout());
String button = e.getActionCommand();
if(button.equals(next)) {
c1.last(cards);
}
if(button.equals(previous)) {
c1.first(cards);
}
if(button.equals(card3)) {
//calls the third, specified card
}
}
}
You have to use show method of the CardLayout object
I am learning Java and I have to develop an application using a GUI. I have the application working in command line already, but the GUI is driving me insane and costing me in lost hours of head banging and research which is leading nowhere. Can you please help me get the basics working so that i can develop further from there. I want to have a single frame application that can switch between frames on a button click. I created a frame and added three panels P1-P3. These are set as Card Layout (from what i read from forums). Then I added additional panels to these to which i have set colour and buttons.
'''
public class MyMainForm extends JFrame{
private JPanel P1;
private JPanel P2;
private JPanel P3;
private JButton btnFrame1;
private JButton btnFrame2;
private JButton button1;
private JTextField thisIsPanel3TextField;
private JButton btn2Frame1;
private final JFrame frame = new JFrame("MyMain Frame");
public MyMainForm() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(P1);
pack();
setSize(1000,800);
//setLocation(null);
btnFrame1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
P1.setVisible(false);
setContentPane(new MyMainForm().P2);
}
});
btnFrame2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
P2.setVisible(false);
setContentPane(new MyMainForm().P3);
}
});
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
P3.setVisible(false);
setContentPane(new MyMainForm().P2);
}
});
btn2Frame1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
P1.setVisible(false);
setContentPane(new MyMainForm().P3);
}
});
}
public static void main(String[] args) {
MyMainForm MyMainForm = new MyMainForm();
MyMainForm.setVisible(true);
}
}
'''
I can display P2 or P3 with this new code example above. When i try to go from P2 or P3 back to P1 the content pane doesn't show? Do i need to revalidate the content pane for this to work? I really need to be able to go from P1 to P2
The easiest way to do this is to use a CardLayout. Just follow this example:
JFrame frame = new JFrame();
JPanel p1 = new JPanel();
p1.setBackground(Color.RED);
JPanel p2 = new JPanel();
p2.setBackground(Color.WHITE);
JPanel p3 = new JPanel();
p3.setBackground(Color.BLUE);
//Create the panel that contains the "cards".
JPanel cards = new JPanel(new CardLayout());
cards.add(p1, "Panel 1");
cards.add(p2, "Panel 2");
cards.add(p3, "Panel 3");
// Add your card container to the frame
Container pane = frame.getContentPane();
pane.add(cards, BorderLayout.CENTER);
JButton btn = new JButton("Click me!");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent e) {
CardLayout cl = (CardLayout)(cards.getLayout());
cl.next(cards);
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(btn);
pane.add(btnPanel, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
Alternatively, you can switch to a specific panel by calling cl.show(cards, "Panel X") where X is the number of the panel. This is because the swing argument is the name I assigned to each "card" and the show method recalls panels added to CardLayout by name. For your example, each button should have a listener that uses this method to "show" its assigned panel.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
The NullPointerException only comes about when I click the 'next' button.
I'm trying to get the frame to transition to another panel using cardlayout, but I have failed to do so.
Second question: How do I get my current panel to transition to the next panel (LoginPanel) in another class? I've already created an instance of it
public class InsuranceMain extends JFrame {
private CardLayout cardPanel;
private JPanel buttonPanel;
private JButton next;
private JLabel label;
public InsuranceMain() {
buttonPanel = new JPanel();
JPanel card1 = new JPanel();
JPanel cards = new JPanel(cardPanel);
LoginPanel loginPanelA = new LoginPanel(this);
CardLayout cardLayout = new CardLayout();
cards.setLayout(cardLayout);
next = new JButton("Next"); // Button
label = new JLabel("Test");
// Main frame settings
setTitle("Travel Insurance Application");
setSize(300, 300);
setLayout(new FlowLayout());
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel.add(next);
add(buttonPanel);
card1.add(label);
cards.add(card1, "card1");
cards.add(loginPanelA, "loginPanelA");
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == next) {
cardLayout.show(cards, "loginPanelA");
}}
});
}
public static void main(String[] args) {
InsuranceMain test = new InsuranceMain();
}
}
Here's my LoginPanel code. I apologize if it's very disorganized
public class LoginPanel extends JPanel {
private JButton loginB, registerB, clearB;
private JTextField nricTextField, passwordTextField;
private JLabel nric, password, loginTitle;
private JPanel centerPanel, southPanel;
private InsuranceMain main;
public LoginPanel(InsuranceMain main){
this.main = main;
// JLabels
loginTitle = new JLabel("Insurance Login", JLabel.CENTER);
nric = new JLabel("NRIC: ");
password = new JLabel("Password: ");
// JTextField
nricTextField = new JTextField("");
passwordTextField = new JTextField("");
// JButton
loginB = new JButton("Login");
loginB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == loginB) {
//cardLayout.show(cards, "card1");
}}
});
registerB = new JButton("Register");
clearB = new JButton("Clear");
// North Panel
setLayout(new BorderLayout()); // main panel's layout
add(loginTitle, BorderLayout.NORTH);
// Center Panel
centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(2,2));
centerPanel.add(nric);
centerPanel.add(nricTextField);
centerPanel.add(password);
centerPanel.add(passwordTextField);
add(centerPanel, BorderLayout.CENTER);
// South Panel
southPanel = new JPanel();
southPanel.setLayout(new FlowLayout());
southPanel.add(loginB);
southPanel.add(registerB);
southPanel.add(clearB);
add(southPanel, BorderLayout.SOUTH);
}
}
A NPE in the actionPerformed method can only be caused by cardLayout being null. So instead of
CardLayout cardLayout = (CardLayout) cards.getLayout(); // yields null
You should create the layout you need.
CardLayout cardLayout = new CardLayout();
See also
Cannot refer to a non-final variable inside an inner class defined in a different method
See also Erwin's comment.
//change to
final CardLayout cardLayout = new CardLayout();
final JPanel cards = new JPanel(cardPanel);
cards.setLayout(cardLayout);
You have to declare the variables final so you can refer to them from an anonymus inner class
new ActionListener() {}
Also use the naming convention of java for naming classes => start with capital letter i.e InsuranceMain, LoginPanel
I just started to learn swing by myself, I'm little bit confused why my event does not work here:
1.I'm trying to delete everything from my panel if the user click menu bar -> load but it force me to change the panel to final because i'm using it inside the event!
2.I have defined new panel in my event and defined two more container to add to that panel and then add it to the main frame but it seems nothing happening!
Please help me if you can find out what is wrong.
Sorry in advance for messy code.
I appreciate any hints.
public class SimpleBorder {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
public void run()
{
myFrame frame = new myFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class MyFrame extends JFrame {
public MyFrame()
{
setSize(500,500);
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel label = new JLabel("my name is bernard...");
Color myColor = new Color(10, 150, 80);
panel.setBackground(myColor);
label.setFont(new Font("Serif", Font.PLAIN, 25));
Dimension size = label.getPreferredSize();
Insets insets = label.getInsets();
label.setBounds(85+insets.left, 120+insets.top , size.width, size.height);
panel.add(label);
JMenuBar menu = new JMenuBar();
setJMenuBar(menu);
JMenu col = new JMenu("Collection");
menu.add(col);
JMenu help = new JMenu("Help");
menu.add(help);
Action loadAction = new AbstractAction("Load")//menu item exit goes here
{
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event)
{
JTextArea text = new JTextArea(10, 40);
JScrollPane scrol1 = new JScrollPane(text);
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
JScrollPane scrol2 = new JScrollPane(list);
JPanel panel2 = new JPanel(new BorderLayout());
panel2 = new JPanel(new GridLayout(1, 2 ));
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
}
};
JMenuItem load = new JMenuItem(loadAction);
col.add(load);
add(panel);
}
}
Call revalidate()/repaint() on your JFrame instance after adding the new panel:
JPanel panel2 = new JPanel(new BorderLayout());
// panel2 = new JPanel(new GridLayout(1, 2 ));//why this it will overwrite the above layout
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
revalidate();
repaint();
Also call pack() on you JFrame instance so all components are spaced by the layoutmanager. As said in a comment dont extend the JFrame class, create a variable of the frame and initiate all that you need on the frames instance, and dont set a layout to null, unless you love hard work :P
Alternatively as mentioned by mKorbel, a CardLayout may be more what you want, it will allow you to use a single JPanel and switch between others/new ones:
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";
final static String TEXTPANEL = "Card with JTextField";
//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
...
JPanel card2 = new JPanel();
...
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);
//add card panel to frame
frame.add(cards);
//swap cards
CardLayout cl = (CardLayout)(cards.getLayout());//get layout of cards from card panel
cl.show(cards, TEXTPANEL);//show another card
I have a panel on my frame .and by clicking on a button I want to delete the old panel and make the other panel and add that panel to my frame.(also I use netbeans)
would you please help me that how can i do that?thanks
JFrame frame = new JFrame();
final JPanel origPanel = new JPanel();
frame.add(origPanel, BorderLayout.CENTER);
MouseListener ml = new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
// Mouse clicked on panel so remove existing panel and add a new one.
frame.remove(origPanel);
frame.add(createNewPanel(), BorderLayout.CENTER);
// Revalidate frame to cause it to layout the new panel correctly.
frame.revalidate();
// Stop listening to origPanel (prevent dangling reference).
origPanel.removeMouseListener(this);
}
}
origPanel.addMouseListener(ml);
This way:
final JFrame frame = new JFrame();
frame.setSize(200, 200);
final JPanel panelA = new JPanel();
final JPanel panelB = new JPanel();
JButton button = new JButton("Switch");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.remove(panelA);
frame.add(panelB);
frame.show();
}
});
JLabel label = new JLabel("This is panel B. Panel A is gone!");
panelB.add(label);
panelA.add(button);
frame.add(panelB);
frame.add(panelA);
frame.show();