Why shouldn't I call setVisible(true) before adding components?
You're not breaking anything if you call it first, but you will probably then need to call it again if you've added anything. Else Swing won't render the added components. You need to have the JVM call the JFrame's paint(...)
method to have the JFrame's components rendered, and setVisible(true)
will ask the JVM to do just this. If you've ever add components after calling setVisible(true) and don't see the components, you'll find that they'll "materialize" if you re-size the JFrame. This is because re-sizing it causes the operating system to ask Swing to repaint the GUI, and this will result in paint(...)
being called.
Note that if you add a component after creating your GUI, you can call revalidate()
and often repaint()
on its container to get the new component laid out correctly and then rendered. The repaint()
will definitely be necessary if the change in components involves a deletion, or a component being drawn where another component was visualized previously.
A book suggestion that I highly recommend: Filthy Rich Clients buy Guy and Haase. Just buy it! You won't regret the purchase.
Calling setVisible(true) on an already visible frame
Calling setVisible(true)
on a JFrame
which is already visible works for you because this ends up calling validate()
internally, which in turn revalidates all subcomponents in the frame.
To see why, refer to the implementation of Component.setVisible(boolean b)
:
public void setVisible(boolean b) {
show(b);
}
public void show(boolean b) {
if (b) {
show();
} else {
hide();
}
}
But the show()
method is overriden in Window
(of which JFrame
is a subclass). So this ends up calling Window.show()
:
public void show() {
if (peer == null) {
addNotify();
}
validate();
[...]
Hope this explains the behaviour you are seeing.
I don't know why my main class doesn't obtain data from my Gameplay class
Firstly, when you add a component to a visible container, you have to call repaint
and revalidate
methods. So after obj.add(gamePlay);
do obj.repaint();
and obj.revalidate();
. In your case, you could easily obj.add(gamePlay);
and then obj.setVisible(true);
in order to avoid using repaint
and revalidate
.
Secondly, in Gameplay
class, you @Override
paint
method instead of paintComponent
method. It should be:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //Always call super when overriding paint component
//Custom painting
}
Finally, Swing applications should run in their own thread called EDT (Event dispatch thread). Use SwingUtilities#invokeLater
in order to do it. Something like:
SwingUtilities.invokeLater(() -> {
JFrame obj = new JFrame();
Gameplay gamePlay = new Gameplay();
obj.setBounds(10, 10, 700, 600);
obj.setTitle("Brick Breaker");
obj.setResizable(false);
obj.setVisible(true);
obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
obj.add(gamePlay);
});
Nothing in my JFrame appears
Add the components to the content pane :)
Here is a suggestion using the versatile MigLayout:
JPane panel = (JPanel) frame.getContentPane();
panel.setLayout(new MigLayout("fill, wrap 2", "[right][fill]"));
panel.add(lengthL);
panel.add(new JTextField());
panel.add(widthL);
panel.add(new JTextField());
panel.add(areaL);
panel.add(new JTextField());
panel.add(perimeterL);
panel.add(new JTextField());
how to find out a java Component being displayed on screen
After investigation I find out this method represents that the component is displayed on screen or not:
isDisplayable()
in my Example:
jPanel1.isDisplayable()
// returns true
jPanel2.isDisplayable()
// returns false
as Simple as this!
Swing components drawing inside each other
The immediate problem—painting artifacts in ListBox
—is caused by not honoring the opaque property. Using true
promises to paint all of the bits, but your paintComponent()
fails to do so.
Here are a few more suggestions:
Don't neglect the event dispatch thread.
Do use event listeners, but also consider the available adapters, which have convenient null implementations.
Don't reinvent existing components, and override
paintComponent()
only as a last resort.Do learn to use layout managers and borders.
Yes there is much to learn, but this kind of experimentation is invaluable.
Adding panels to frame, but not showing when app is run
When you add components to a container you may need to invalidate the container hierarchy in order to get them to become visible...
The problems is as highlight when you set the frame visible BEFORE you've added anything to it...
public static void drawFrame(){
// Create frame
JFrame frame = new JFrame("Frame");
// Set default close operation
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set frame attributes
// !! Don't do this here...
//frame.setVisible(true);
// ... IMHO, better to use pack...
//frame.setSize(400, 300);
frame.setResizable(false);
// Set Layout
frame.setLayout(new BorderLayout());
// Add Components
frame.add(drawMenuBar(), BorderLayout.NORTH);
JPanel twinPane = new JPanel();
frame.add(twinPane, BorderLayout.CENTER);
twinPane.setLayout(new GridLayout(1, 2));
twinPane.add(drawForm());
twinPane.add(drawInfo());
// !! Do it here instead...
frame.pack();
frame.setVisible(true);
} // Ends method drawFrame
Java: In AbsoluteLayout, JButtons do no show up until the mouse enters it
There are multiple errors in your program:
You're using
AbsoluteLayout
which in the end it's still anull layout
, see Null layout is evil and Why is it frowned upon to use a null layout in Swing?. While absolute positioning might seem like the fastest and easiest way to make complex GUI's for Swing beginners, the more you advance in your program the more errors you'll get due to this. Instead use a Layout Manager or combinations of them along with Empty borders for extra spacing if needed.You're creating a
JFrame
object and extendingJFrame
that, in other words, makes your class aJFrame
! There's no need to extendJFrame
if you really need to extend something extend aJPanel
which can be added later into other components whileJFrame
can't.You're making your
JFrame
visible before you have added all your components to it, that's the reason for your error, and probably the 1st one too. You should make it visible only in the end, after you have added all your components to it.
Related Topics
Good Reasons to Prohibit Inheritance in Java
Increasing the Jvm Maximum Heap Size for Memory Intensive Applications
Write a File in Hdfs with Java
Docker: Combine Multiple Images
Installed Java 7 on MAC Os X But Terminal Is Still Using Version 6
Storing a Map<String,String> Using JPA
Get the Indices of an Array After Sorting
Why Does My Sorting Loop Seem to Append an Element Where It Shouldn'T
Javafx Location Is Not Set Error Message
Jtable Model Listener Detects Inserted Rows Too Soon (Before They Are Drawn)
When to Use Entitymanager.Find() VS Entitymanager.Getreference() with JPA
How to Get the Caller Class in Java