-2

I will have a menu bar in which I can select multiple choices, in which will display a different JPanel for me onto my JFrame. Whenever I choose another option from my menu bar, a different JPanel will occupy the JFrame's space.

However, with this code, every time I issue the following code frame.getJPanelOne();, it creates a new JFrame, which I don't want. I only want the panel to be displayed on my existing JFrame.

Keep in mind, when my program starts, a JFrame is created from the JFrameTest class and also displays my menu bar at the top so I can select between Panel one and Panel two.

How can I successfully do this with the following code?

public class MenuActionListener implements ActionListener {

    private MyFrame frame;

    public MenuActionListener (MyFrame frame) {

        this.frame = frame;

    }

    public void displayPanelOne() {
        JFrameTest frame = new JFrameTest();
        frame.getJPanelOne();
    }
    public void displayPanelTwo() {
        JFrameTest frame = new JFrameTest();
        frame.getJPanelTwo();
    }
    @Override
    public void actionPerformed(final ActionEvent e) {
        String command = e.getActionCommand();

        switch (command) {

            //Display panel one when I select the option on the menu bar
            case "Panel One":
                displayPanelOne();
                break;

            //Display panel two when I select the option on the menu bar
            case "Panel Two":
                displayPanelTwo();
                break;
            default:
        }
    }
}

Here is my JFrameTest class:

public class JFrameTest extends JFrame {

    private JPanel panelMain;
    private JPanelOne panel1;
    private JPanelTwo panel2;
    private JMenuBar menuBar;

    public JFrameTest() {

        MenuBar menuBarInstance = new MenuBar();

        frame = new JFrame();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setPreferredSize(new Dimension(720, 480));
        setJMenuBar(menuBarInstance.getMenuBar());
        menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
        menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
        pack();
        setLocationRelativeTo(null);
        setVisible(true);

        panelMain = new JPanel();
        panelMain.setBounds(0, 0, 420, 90);
        panelMain.setPreferredSize(new Dimension(200, 40));
        add(panelMain);

    }

    public JPanel getJPanelOne() {

        panel1 = new JPanelOne();
        panelMain.add(panel1);

        return panelMain;
    }

    public JPanel getJPanelTwo() {
        panel2 = new JPanelTwo();
        panelMain.add(panel2);

        return panelMain;
    }

}

Here is both my JPanel classes in which will be added whenever I select the appropriate item from the menu bar:

public class JPanelOne extends JPanel
{
    public JPanelOne()
    {
        // setting up black JPanel
        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(220, 40));
        panel.setBackground(Color.BLACK);

        JLabel label = new JLabel("Panel One");

        // adding button to the black JPanel
        panel.add(label);

        // adding blackJPanel
        add(panel);
    }
}

And a separate class for my other panel.

public class JPanelTwo extends JPanel
    {
        public JPanelTwo()
        {
            // setting up black JPanel
            JPanel panel = new JPanel();
            panel.setPreferredSize(new Dimension(220, 40));
            panel.setBackground(Color.RED);

            JLabel label = new JLabel("Panel One");

            // adding button to the black JPanel
            panel.add(label);

            // adding blackJPanel
            add(panel);
        }
    }

Create menu action listener and add it to my GUI:

public class MenuBar {

    private JMenuBar menuBar;
    private MyFrame frame;

    public MenuBar() {

        System.out.println("menuBar");

        //Creates a menubar for a JFrame
        menuBar = new JMenuBar();

        //Define addMenu items
        JMenuItem addPanelOneItem = new JMenuItem("Panel One");
        addPanelOneItem.setActionCommand("Panel One");

        //Define addMenu items
        JMenuItem addPanelTwoItem = new JMenuItem("Panel Two");
        addPanelTwoItem.setActionCommand("Panel Two");

        JMenu menu = new JMenu("Test");
        menuBar.add(menu);
        menu.add(addPanelOneItem);
        menu.add(addPanelOneItem);

    public JMenuBar getMenuBar()
    {
        return menuBar;
    }

}

My question is, how can I successfully display multiple JPanel's from different classes onto my main JFrame without creating new instances of said JFrame?

Thank you in advance.

juiceb0xk
  • 949
  • 3
  • 19
  • 46

3 Answers3

2

Your use case, seems perfect for CardLayout.

In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.

nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • This may be the alternative I'll have to take if I can't get my application running the way I would like it to. Thank you for your help. – juiceb0xk Apr 12 '17 at 15:21
0

It's creating a new JFrame each time because you are telling it to (new JFrameTest();). Instead, do something like:-

JFrameTest frame = new JFrameTest();

public void displayPanelOne() {
    // todo - remove existing panel if required?
    frame.getJPanelOne();
}
Steve Smith
  • 2,244
  • 2
  • 18
  • 22
  • I'm getting a StackOverflowError when i try it this way for some odd reason. I have tried XtremeBaumer's way, but I am still yielding a NullPointerException error. – juiceb0xk Apr 12 '17 at 15:21
  • Do you have a stack trace? – Steve Smith Apr 12 '17 at 15:32
  • I can't catch a stack for `JFrameTest frame = new JFrameTest();` because it's where I can't put any code to catch it. My guess is that it keeps looping through MyFrame and then produces a StackOverflowError. I'm unsure how to get around this. – juiceb0xk Apr 12 '17 at 21:52
  • You can catch any/all code; just put the try/catch around the code that creates the instance of the class that creates the JFrameTest. I usually (for simple programs) only have one try/catch, and that's in the `void main()` method, and that catches everything. – Steve Smith Apr 13 '17 at 08:31
0

your MenuActionListener class should look like this:

public class MenuActionListener implements ActionListener {
    private JFrameTest frame;
    public MenuActionListener(JFrameTest frame){
        this.frame=frame;
    }

    public void displayPanelOne() {
        frame.getJPanelOne();
    }
    public void displayPanelTwo() {
        frame.getJPanelTwo();
    }
    @Override
    public void actionPerformed(final ActionEvent e) {
        String command = e.getActionCommand();

        switch (command) {

            //Display panel one when I select the option on the menu bar
            case "Panel One":
                displayPanelOne();
                break;

            //Display panel two when I select the option on the menu bar
            case "Panel Two":
                displayPanelTwo();
                break;
            default:
        }
    }
}

and again we are missing the crucial part of the code, on which you create the MenuActionListener and add it to your GUI. if you post that code, we can solve your question. And also don't make a new question to the exact same problem as before

Copy the following code of your MenuBar

public class MenuBar {

    private JMenuBar menuBar;
    private MyFrame frame;

    public MenuBar() {
        System.out.println("menuBar");
        //Creates a menubar for a JFrame
        menuBar = new JMenuBar();

        //Define addMenu items
        JMenuItem addPanelOneItem = new JMenuItem("Panel One");
        addPanelOneItem.setActionCommand("Panel One");

        //Define addMenu items
        JMenuItem addPanelTwoItem = new JMenuItem("Panel Two");
        addPanelTwoItem.setActionCommand("Panel Two");
        JMenu menu = new JMenu("Test");
        menuBar.add(menu);
        menu.add(addPanelOneItem);
        menu.add(addPanelOneItem);
    }
public JMenuBar getMenuBar()
    {
        return menuBar;
    }

}

and in your JFrameTest class you then after setJMenuBar(menuBarInstance.getMenuBar());

add these lines of code:

menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));


public JFrameTest() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setPreferredSize(new Dimension(720, 480));
        menuBar=new MenuBar().getMenuBar();
        menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
        menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
        pack();
        setLocationRelativeTo(null);
        setVisible(true);

        panelMain = new JPanel();
        panelMain.setBounds(0, 0, 420, 90);
        panelMain.setPreferredSize(new Dimension(200, 40));

        add(panelMain);
        setJMenuBar(menuBar);

    }
XtremeBaumer
  • 6,275
  • 3
  • 19
  • 65
  • Hello, thank you for your help - I've posted the missing code. This is just how I initialize my menu items and add a action listener for them to display my panels. – juiceb0xk Apr 12 '17 at 15:04
  • On my `MenuActionListener` class, I am now generating a NullPointerException error at the following line: `frame.getPanelOne();`, same goes for Panel two. What exactly is null? – juiceb0xk Apr 12 '17 at 15:08
  • I'm sorry, whereabouts do I place the following code you have supplied: `menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(frame));`? The only class I can place that code is in my `MenuBar` class. If I put that code in my `JFrameTest` class, I cannot add `frame` as a parameter for the MenuActionListener. – juiceb0xk Apr 13 '17 at 09:05
  • @juiceb0xk my mistake, i forgot to change `frame` to `this`. now it should work – XtremeBaumer Apr 13 '17 at 09:19
  • `menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));` produces a NullPointerException error. I'm not sure as to why this is happening. Before the JFrameTest constructor, I have instantiated `private JMenuBar menuBar`, if this is correct? – juiceb0xk Apr 13 '17 at 09:39