问题
I have a problem with my JButton
objects behaving in an odd way:
JFrame frame = new JFrame();
frame.setSize(new Dimension(200, 200));
frame.setVisible(true);
//Constraints
GridBagConstraints constraints = new GridBagConstraints();
constraints.weightx = 1.0;
constraints.weighty = 1.0;
...
//
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
JButton button = new JButton("Categories:");
panel.add(button, constraints);
frame.add(panel);
This results in the following GUI:

Where is the button?
When I replace the last few lines with the following:
JPanel panel = new JPanel();
JButton button = new JButton();
panel.add(button, constraints);
button.setText("Categories:");
frame.add(panel);
I get the following GUI:

The button now shows up.
Why is this? I thought giving a string in the constructor of the button would result in the same as explicitly calling the setter.
回答1:
As people have pointed out components should be added to the GUI before you pack() the frame and make the frame visible.
Why does a JButton not show unless text is set after JButton is added to JPanel?
However, to answer the above question, you can add components to the GUI even when the frame is visible. When you do this you must tell the Swing that components have been added (or removed) so the layout manager can be invoked. You do this with code like the following:
panel.add(...);
panel.revalidate();
panel.repaint();
In your case when you invoke the setText(...)
method on the button the button actually invokes revalidate() and repaint() for you. This is done whenever you change a property of a Swing component so effectively you are invoking the layout manager which means the button can be assigned a size/location by the layout manager before it is painted.
In your original code the layout manager was not invoked when you added button to the GUI so it had a default size of (0, 0);
回答2:
As MadProgrammer pointed out (thank you!), the problem was caused by the position of the frame.setVisible(true).
This needs to be the last thing called, or the frame's refresh mode may cause for unrendered components like happened in my case.
来源:https://stackoverflow.com/questions/27285233/why-does-a-jbutton-not-show-unless-text-is-set-after-jbutton-is-added-to-jpanel