anankElpis
anankElpis

Reputation: 131

Components in JPanel only show after Resizing

The Buttons in my JPanel don't show up when it's loaded, only when I resize the window or move my mouse over it. In other discussions the use of "validate()" or "repaint()" was suggested, but that doesn't work for me. I'm using a basic model view controller design and I am pretty sure that I'm doing everything else correctly. Just in case you wonder, of course more panels will be added to the frame, that's the purpose of the update() and changeCards() methods. Here's my frame:

public class View extends JFrame {

    private MainMenuPanel mainMenu;

    private final String MAIN_MENU_CONSTRAINTS = "MAIN_MENU";

    public View() {

        super();

        init();

        mainMenu = new MainMenuPanel();
        add(mainMenu;MAIN_MENU_CONSTRAINTS);
        validate();
        repaint(0,0,getWidth(),getHeight());
        setVisible(true);
    }


    private void init() {
        setVisible(false);

        setTitle("Test");

        // set card-layout
        setRootPaneCheckingEnabled(false);
        CardLayout cl = new CardLayout();
        this.setLayout(cl);

        // expand frame to whole display size
        setExtendedState(MAXIMIZED_BOTH);

        // set unclosable
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }


    public void update (Mode mode) {

        switch (mode) {

            case MAIN_MENU:
                changeCard(MAIN_MENU_CONSTRAINTS);
                break;

        }

    }

    public void changeCard(String card) {

        // update cards
        CardLayout cl = (CardLayout) getLayout();
        cl.show(this, card);
    }
}

And here's the Panel:

public class MainMenuPanel extends Panel implements ActionListener{


    private JButton startButton;
    private JButton quitButton;

    private final String START_ACTION_COMMAND = "START";
    private final String QUIT_ACTION_COMMAND = "QUIT";

    private MainMenuPanelListenerImpl listener;


    public MainMenuPanel() {

        super();

        init();

        initComponents();
        configureComponents();
        configureListeners();
        addComponents();

        revalidate();

    } 


    private void init() {
        setLayout(null);
    }

    private void initComponents() {
        startButton = new JButton();
        quitButton = new JButton();
    }

    private void configureComponents() {
        startButton.setText("Start");
        quitButton.setText("End");

        startButton.setBounds((int)(0.5*getWidth()-200), (int)(0.5*getHeight()-75), 400, 75);
        quitButton.setBounds((int)(0.5*getWidth()-200), (int)(0.5*getHeight()+25),400,75);
    }

    private void configureListeners() {
        startButton.addActionListener(this);
        startButton.setActionCommand(START_ACTION_COMMAND);
        quitButton.addActionListener(this);
        quitButton.setActionCommand(QUIT_ACTION_COMMAND);
    }

    private void addComponents() {
        add(startButton);
        add(quitButton);
        startButton.validate();
        quitButton.validate();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (e.getActionCommand()) {
            case START_ACTION_COMMAND:
                listener.start();
                break;
            case QUIT_ACTION_COMMAND:
                System.exit(0);
            break;
        }
    }

    public void setListener(MainMenuPanelListenerImpl listener) {
        this.listener = listener;
    }
}

Upvotes: 2

Views: 1903

Answers (2)

After you paint the elements, you put the setvisible(true) because if you put it before, the Jframe will paint no elements

Upvotes: 3

Alexander Heim
Alexander Heim

Reputation: 154

Well first of all you mix the old AWT-Components like Panel with newer SWING-Components like JFrame. Those don´t really work well together so I would try to fix that first. I would highly recommend using SWING or if you want to learn the newest Java GUI Library then JavaFX.

Don´t use the method repaint in the constructor of your JFrame, actually you shouldn´t use repaint in SWING at all. Nor do you need validate in the constructor. If you want to position your JFrame somewhere you should use something like this this.setLocation(0,0)

And to the main question: The panel probably only shows it´s components after resizing because you add it to the JFrame the wrong way. In SWING there is something called a content pane where you should add all of your stuff onto (except JMenuBar but that is a different story).

Simply set the layout of the content pane to the card layout that you want to use and then add your panel onto the content pane.

Here a link regarding the panel levels: https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html

Upvotes: 0

Related Questions