-1

I'm developing Java Swing application. My application has two Java classes. Inside class1.java, I include JFrame, JButton and JPanel (panel1). When I click the button I want to hide panel1 and should be shown panel2 of class2.java. I tried this method in button actionPerformed method of class1.java. But it was not working.

class2 pnl = new class2();     
this.remove(panel1);
this.add(pnl); 
this.validate();
this.repaint();
bytecode77
  • 14,163
  • 30
  • 110
  • 141
Nadee
  • 23
  • 7
  • Call `revalidate` instead of `validate` – MadProgrammer Nov 11 '15 at 08:17
  • 3
    you should take a look at layouts, especially the `CardLayout` might fit your needs here. – SomeJavaGuy Nov 11 '15 at 08:18
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Use a [`CardLayout`](http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) as shown in [this answer](http://stackoverflow.com/a/5786005/418556). – Andrew Thompson Nov 11 '15 at 08:48
  • I used **this.setContentPane(pnl)**.Then display panel2. but I want to display it specific position. How to do it? – Nadee Nov 11 '15 at 09:10

2 Answers2

0

Analysis

You simply want the JComponents to be displayed on the JFrame. We can achieve this by using a single JPanel, but adding and removing the JComponents from it, during the JButton's action listener.

Without looking at your actual code, it is better to make a manageable way to reach code and instantiated Objects. The code listed below, creates a nice and manageable way to do so.

Achieving This

The entire class is listed below with comments for explanations.

package swing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

    public class MultiPaneledFrame {

        JFrame frame = new JFrame();
        JPanel window = new JPanel();

        // As you can see, we create an array containing all your JComponents.
        // We have two of these, to simulate multiple JPanel's.
        List<JComponent> window1Contents = new ArrayList<JComponent>();
        List<JComponent> window2Contents = new ArrayList<JComponent>();
        // NOTE: The above Lists can instead be stuck in their own class like asked for,
        // and instantiated on Class invocation.

        JButton goto2 = new JButton("Goto Panel 2");
        JButton goto1 = new JButton("Goto Panel 1");

        int panelToShow = 0; // 0 - First "panel".
                               // 1 - Second "panel".

        // Main method of class. Change 'Multi_Paneled_Frame' to the name of your Class.
        public MultiPaneledFrame() {
            // Execute anything else you want here, before we start the frame.
            window1Contents.add(goto2);
            window2Contents.add(goto1);

            // Here is where I personally am setting the coordinates of the JButton's on the JPanel.
            goto2.setPreferredSize(new Dimension(200, 100));
            goto1.setPreferredSize(new Dimension(200, 100));
            //goto2.setBounds(5, 5, 150, 30); < Used for 'null' layout.
            //goto1.setBounds(5, 5, 150, 30); < Used for 'null' layout.

            goto2.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    addComponents(panelToShow = 1);
                }
            });
            goto1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    addComponents(panelToShow = 0);
                }
            });

            initialiseFrame();
        }

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new MultiPaneledFrame();
                }
            });
        }

        private void initialiseFrame() {
            frame.setSize(600, 400); // Change it accordingly.
            // Optional
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setResizable(false);
            // Needed
            frame.setVisible(true);
            frame.add(window);
            window.setLayout(new BorderLayout()); // Assuming your using a BorderLayout.
            //window.setLayout(null); < Uses 'null' layout.
            addComponents(panelToShow);

            // I always like to make sure that everything is on the frame nicely.
            frame.repaint();
            frame.validate();
        }

        private void addComponents(int panelNo) {
            if (panelNo == 0) {
                for (JComponent component : window1Contents) {
                    window.removeAll(); // We're removing everything that it contains and replacing it...
                    window.revalidate();
                    window.add(component, BorderLayout.CENTER);
                    //window.add(component); < Uses 'null' layout.
                    // Since we are using the first panel, we are adding
                    // everything from the first list of components to the window...
                }
            } else {
                for (JComponent component : window2Contents) {
                    window.removeAll(); // We're removing everything that it contains and replacing it...
                    window.revalidate();
                    window.add(component, BorderLayout.CENTER);
                    //window.add(component); < Uses 'null' layout.
                    // Since we are using the second panel, we are adding
                    // everything from the second list of components to the window...
                }
            }

            // Refreshes the frame.
            frame.repaint();
            frame.validate();
        }
    }

Conclusion

Although there are countless ways to achieve something like this, the way I have given, is semi-efficient, and very flexible. Feel free to edit the code, or drop a question if you have any concerns, and I will be happy to respond.

PS: This code was tested and works on a Macbook Air running OS X 10.11 and Java Version 8 Update 65.

  • @haywire Both of you, I have updated the answer (Although using a BorderLayout), stuck to the average naming-conventions and removed the "DIY Homework" tab. :) –  Nov 11 '15 at 10:43
  • @MadProgrammer Alright, alright. I understand your perspective now. Check my last comment. ;) –  Nov 11 '15 at 10:43
  • @MadProgrammer Don't mean to be pushy or assertive, but is there anything that I could possibly ***add*** or ***change*** that would win me your upvote? Albeit being a semi-legacy user, I'm still open to corrections. That is if you were the second person to downvote me. –  Nov 11 '15 at 11:06
  • 1
    @frayment [Initial Threads](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html), [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) – MadProgrammer Nov 11 '15 at 21:16
-1

CardLayout should be your solution. In this tutorial they show how to switch from panel to another one by selecting a value in ComboBox.

A little bit of explanation for the CarLayout:

The CardLayout lets you place different panel on top of each other but shows only one at the time. With your code, you select the one you want to display.

Initialisation:

this.setLayout(new CardLayout());

class1 pnl1 = new class1();
class2 pnl2 = new class2();

this.add(pnl1, "PANEL1");
this.add(pnl2, "PANEL2");

On your button actionPerformed:

CardLayout cl = (CardLayout)(this.getLayout());
cl.show(this, "PANEL2");
lvr123
  • 524
  • 6
  • 24