2

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;
    }
}
  • 1
    Using `setLayout(null)` precludes the desired effect; use a [*layout manager*](https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html). – trashgod Aug 21 '17 at 13:51
  • 1
    1) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 2) A single blank line of white space in source code is all that is *ever* needed. Blank lines after `{` or before `}` are also typically redundant. 3) There seems to be no need in this GUI, to extend any .. – Andrew Thompson Aug 21 '17 at 13:58
  • 1
    .. existing component like `JFrame` or `JPanel`. Just use (plain) instances of each. – Andrew Thompson Aug 21 '17 at 13:59
  • Shouldn't this `add(mainMenu;MAIN_MENU_CONSTRAINTS);` have a `','` instead of `';'`? Also you're mixing AWT components (`Panel`) with Swing components `JFrame` – Frakcool Aug 21 '17 at 14:09
  • Where is your code of instantiating the JFrame? I am afraid the cause of your problem with buttons not showing up is not shown here. – user3437460 Aug 22 '17 at 08:15

2 Answers2

3

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

  • Welcome to StackOverflow. We appreciate your proactivity in answering. However, it will be nice if you add more details, preferably code, as many people can learn from this site. Have a read on [this](https://stackoverflow.com/help/how-to-answer) – Fabio Mendes Soares Jan 19 '21 at 19:22
  • Bro, thanks, no idea why this works, but it solved my problem – The Big Kahuna Apr 15 '23 at 03:36
0

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