-2

I'm having a problem trying to change JPanels by using buttons. I have a JFrame with 2 panels, 1 of them is for the buttons, which i want them to always be showed. The other one is the one that i will be switching everytime i press one ot the buttons of the other panel. The problem is that everytime i press them nothing really ever displays, i keep my buttons but the other panel that i call does not appear.

Code for one of the buttons is as follows

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        ReparacaoPanel r = new ReparacaoPanel(this, this.jPanel1);
        this.getContentPane().remove(this.jPanel1);
        this.getContentPane().add(r);
        //this.setContentPane(r);
        this.visiblePanel.setVisible(false);
        this.visiblePanel = r;
        this.pack();
        this.setVisible(true);

        r.setLocation(200, 200);
        this.getContentPane().revalidate();
        this.repaint();
    }

If i try to use "this.setContentPane(r);" (it sets the frame to only show the panel) the panel shows. But when i try to call it as i'm trying to do in the code above nothing is showed apart from the panel that has the buttons.

I have no idea what i'm doing wrong, it does not seem to be a problem with the JPanel that i'm trying to call as it shows if used alone.

Anyone can help me out?

  • 3
    Consider using a [CardLayout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) to switch between visible panels. – isaias-b Jun 22 '14 at 10:15
  • Question seems similar to [this](http://stackoverflow.com/q/16079886/3165552) – isaias-b Jun 22 '14 at 10:19
  • thanks for the suggestion but that does not fit what i'm trying to do. I need them to switch right away and not calling for a cardlayout to switch them. I've seen this working, i just don't know what i'm doing wrong. – user3726782 Jun 22 '14 at 10:20
  • 2
    *"I need them to switch right away and not calling for a cardlayout to switch them."* Does that mean something in your head? In mine, it sounds like complete nonsense. – Andrew Thompson Jun 22 '14 at 10:22
  • it's not exactly the same. As i said on the topic if i use this.setContentPane(r); the panel shows, but i need it to just switch one of the panels of the mainframe to the one that i'm calling – user3726782 Jun 22 '14 at 10:23
  • The only maybe slightly acceptable reason to not use the `CardLayout` could be that the layout switches between already known panels. A more dynamic scenario then just keeps adding a new panel to it to switch to right after adding it. Even then i would stick to it. – isaias-b Jun 22 '14 at 10:23
  • It's not nonsense, this is for an academic project and i'm supposed to do it this way. If i present it with card layout they'll go like: "What the hell is that? Why use such a thing? CardLayout for 7 options? that is more clicks than buttons, not pratical". I'd prefer to use menus rather than using CardLayout. Then again i would prefer to get this working rather than using anything else – user3726782 Jun 22 '14 at 10:27
  • What is visiblePanel? what is the declaration of `this`? What is jPanel1? One of the things about doing odd stuff in UI -- like stoutly refusing to use standard layout managers for reasons that are unclear -- is that it's harder to trust that other parts of your code can be filled in *a priori* as though they were written like other code we've seen. You can illustrate your problem with a small example -- JFrame, 2-3 JPanels, a button, and demo what you're trying to do in less than 100 lines, and then post the whole thing. That's what I recommend you do now. – arcy Jun 22 '14 at 10:37
  • thanks, but i already figured it out, thanks to isi's answer. I didn't tested the full example but i started thinking about the possibility of it being hidden by using automatic resizing operations so i tried to remove this.pack(); and aparently it was hiding the panel, i don't understand why tho. Maybe i'll just use setLocation get get it where i really want it and set a default size and make it not resizable. Thanks for everything – user3726782 Jun 22 '14 at 10:56
  • Resizing comes in handy with layout managers. Have you considered using an WYSIWYG editor to create your GUI, like the free google window builder inside of eclipse? This makes it a lot easier to layout a program and is neat when it produces code of good quality. – isaias-b Jun 22 '14 at 11:00

1 Answers1

2

Consider this working example for switching manually between panels. Which produces this output.

enter image description here enter image description here.........

Some tiny NumberPanel

Every new instance shows another number in the center.

import javax.swing.JPanel;
public class NumberPanel extends JPanel {
    private static int counter = 0;
    public NumberPanel() {
        setLayout(new BorderLayout(0, 0));
        JLabel lblNewLabel = new JLabel("" + counter++);
        lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
        add(lblNewLabel);
    }
}

Setting up a frame

private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    frame.getContentPane().add(panel, BorderLayout.SOUTH);

    JButton btnNewButton = new JButton("New button");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            frame.getContentPane().remove(numberPanel);
            numberPanel = new NumberPanel();
            frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
            frame.pack();
        }
    });
    panel.add(btnNewButton);

    numberPanel = new NumberPanel();
    frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
    frame.pack();
}

Testprogram

import java.awt.BorderLayout;
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.JPanel;
public class TestPanelSwitch {
    private JFrame frame;
    private NumberPanel numberPanel;
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TestPanelSwitch window = new TestPanelSwitch();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public TestPanelSwitch() {
        initialize();
    }
    private void initialize() {
        // see above
    }
}

Back to the Question

I think you only need to pack your frame, like in the anonymous ActionListener.

frame.getContentPane().remove(numberPanel);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();

EDIT

As leonidas mentioned it is also possible to revalidate the frame. This requires only to replace the upper call to pack by theese.

frame.invalidate();
frame.validate();
isaias-b
  • 2,255
  • 2
  • 25
  • 38