In the JFrame I have two components JMenuBar and JPanel. A selection in one of the options in menu bar change the content of panel as

JMenuItem jmiAddEmployee = new JMenuItem("Add Employee");
jmiAddEmployee.addActionListener(new ActionListener()
{
    public void actionPerformed(ActionEvent ae)
    {
        mainPanel.removeAll();
        mainPanel.add(addEP);
        validate();
    }
});

This will replace the content, unfortunately if the previous components in the old one been longer then the new ones I will get new components with bits of old where the content is shorter. Is there any solution to this problem or do I need to swap my JMenuBar+JPanel for JTabbedPane?

Recommended Answers

All 10 Replies

The problem is that the panel will only cover as much area as it needs. Anything beyond this area is "ignored" during a validate on the panel (since that area no longer "belongs" to the Panel. 2 "quick" possibilites (I would try the second first).

Have you tried

Dimension d = mainPanel.getSiez();
mainPanel.removeAll();
mainPanel.add(addEP);
mainPanel.setPreferredSize(d);
mainPanel.setSize(d);
validate();

or

mainPanel.removeAll();
mainPanel.add(addEP);
mainPanel.getParent().validate();

Unfortunately both of them still gives same result of "forgotten" content

How is the component containing "mainPanel" constructed? Can you show that (without any of the code behind the constructs, but simply what components are in it and how they get placed in it).

The "mainPanel" is just a container in which I drop one of the pre-made JPanels that are constructed separately. I though it will be easier to just drop pre-made component in JPanel and then do the cleaning with removeAll when different option selected. Right now I have only 3 panels

private AddEmployeePanel addEP = new AddEmployeePanel();
private EditEmployeePanel editEP = new EditEmployeePanel();
private AllClientsPanel allCP = new AllClientsPanel();

which are placed in "mainPanel" depending on pressed option

Yes, but what contains "mainPanel"? And how is mainPanel added to that container. Or is "mainPanel" the contentPane?

I have a more involved possibility but it involves the component that contains "mainPanel" more than it does "mainPanel" itself.

But, since you're saying that your adding "premade" Panels to mainPanel, then try this, as well:

Dimension d = mainPanel.getSiez();
mainPanel.removeAll();
mainPanel.add(addEP);
addEP.setPreferredSize(d);
addEP.setSize(d);
mainPanel.setPreferredSize(d);
mainPanel.setSize(d);
validate();

(and, if that works, you should probably be able to remove the two mainPanel.set*Size calls, but try including them, first).

No change

OK, here is construction of the JFrame

public void runBankSystem()
    {
        Dimension d = new Dimension(500, 500);
        setTitle("Bank Managment System");
        setSize(d);
        setLocation(rp.resultPosition(d));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setMenuBar();
        setJMenuBar(jmb);
        getContentPane().add(mainPanel);
        setVisible(true);
    }

and here is JMenuBar to call the changes

public void setMenuBar()
    {
        jmb = new JMenuBar();
        JMenu jmEmployee = new JMenu("Employee");
        JMenuItem jmiAddEmployee = new JMenuItem("Add Employee");
        jmiAddEmployee.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                mainPanel.removeAll();
                mainPanel.add(addEP);
                validate();
            }
        });
        JMenuItem jmiEditEmployee = new JMenuItem("Edit Employee");
        jmiEditEmployee.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                mainPanel.removeAll();
                mainPanel.add(editEP);
                validate();
            }
        });
        jmiEditEmployee.addActionListener(this);
        jmEmployee.add(jmiAddEmployee);
        jmEmployee.add(jmiEditEmployee);
        jmb.add(jmEmployee);
        JMenu jmClient = new JMenu("Client");
        JMenuItem jmiAllClients = new JMenuItem("All Customers");
        jmiAllClients.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                mainPanel.removeAll();
                mainPanel.add(allCP);
                validate();
            }
        });
        jmiAllClients.addActionListener(this);
        jmClient.add(jmiAllClients);
        jmb.add(jmClient);
        JMenu jmLogout = new JMenu("Logout");
        jmLogout.addActionListener(this);
        jmb.add(jmLogout);
    }

I'm sorry, but with some tests, it seems as though simply calling repaint after calling validate accomplishes your goal. (At least it did for me, although without it I also saw what you were experiencing.)

I would normally assume that a call to repaint() after a call to validate() would essentially be redundant, but seemingly not.

commented: Yes in deed, reapint() does the magic. Thank you +12

Yes in deed, repaint does the magic.

I was under impression that repaint() is called only when you working explicitly with some graphical content (images, lines, shapes etc.)

I was under impression that repaint() is called only when you working explicitly with some graphical content (images, lines, shapes etc.)

Well, it is a "Graphical User Interface". :P

I was under the impression, however, that validate triggered a repaint, which is the reason I waited until the end to try it. Guess I was wrong. Not the first time, won't be the last time. ;)

There is always something new to learn as long you want to do so...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.