unrelaxboy
unrelaxboy

Reputation: 3

Is this JPanel code good? Not showing the other JPanel when clicked on the button

How to get that second JPanel to show when someone clicked on the button? The code is giving an error - unknown source. What am I missing?

package Com.global;

import java.awt.BorderLayout;

public class Govinda extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private JPanel panel;
    private JPanel panel_1;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Govinda frame = new Govinda();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Govinda() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new CardLayout(0, 0));

        final JPanel panel = new JPanel();
        contentPane.add(panel, "name_273212774632866");
        panel.setLayout(null);

        JButton btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                panel_1.setVisible(true);
                panel.setVisible(true);

            }
        });
        btnNewButton.setBounds(126, 105, 89, 23);
        panel.add(btnNewButton);

        JPanel panel_1 = new JPanel();
        contentPane.add(panel_1, "name_273214471684839");
        panel_1.setLayout(null);

        JLabel lblHaiiiiiiiii = new JLabel("HAIIIIIIIII");
        lblHaiiiiiiiii.setBounds(159, 129, 46, 14);
        panel_1.add(lblHaiiiiiiiii);
    }
}

Upvotes: 0

Views: 101

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347204

Is this JPanel code good?

Not really (sorry), you should be using a CardLayout to get this to work, see How to Use CardLayout

You're also shadowing your variables by redeclaring your variables (panel and panel_1) inside your constructor.

You should also avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

You also never add panel_1 to the contentPane so calling setVisible on it (assuming the variable shadowing is fixed) won't do anything

It's also generally discouraged to extend directly from JFrame or other top level containers, you're not adding any new functionality to the class and are locking yourself into a single use case

So you might, instead, do something more like...

import java.awt.CardLayout;
import java.awt.EventQueue;
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;
import javax.swing.border.EmptyBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        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 Govinda());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Govinda extends JPanel {

        /**
         *
         */
        private static final long serialVersionUID = 1L;
        private JPanel panel;
        private JPanel panel_1;

        /**
         * Create the frame.
         */
        public Govinda() {
            setBorder(new EmptyBorder(5, 5, 5, 5));
            setLayout(new CardLayout(0, 0));

            JPanel panel = new JPanel();
            add(panel, "name_273212774632866");

            JButton btnNewButton = new JButton("New button");
            btnNewButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    ((CardLayout) getLayout()).show(Govinda.this, "name_273214471684839");
                }
            });
            panel.add(btnNewButton);

            JPanel panel_1 = new JPanel();
            add(panel_1, "name_273214471684839");

            JLabel lblHaiiiiiiiii = new JLabel("HAIIIIIIIII");
            panel_1.add(lblHaiiiiiiiii);
        }
    }
}

You might also consider using more a Model-View-Controller approach to the navigation, so the logic that is used to determine which view is next would be made by a controller, based on the requirements of a model, for example, have a look at Listener Placement Adhering to the Traditional (non-mediator) MVC Pattern

Upvotes: 1

pczeus
pczeus

Reputation: 7867

In your actionPerformed() method, you call panel_1.setVisible(true).

However, You declare and instantiate panel_1 within the constructor. As soon as you complete execution of the constructor, you go out of scope and the panel_1 reference is lost (panel_1 is available for garbage collection).

So, by the time you invoke the actionPerformed() method, panel_1 doesn't exists.

Move the declaration of JPanel panel_1; to the top of your class, along with the other declarations and only then instantiate panel_1 within the constructor: panel_1 = new JPanel();

Upvotes: 0

Related Questions