If I set the size of JPanel first, then set the panel to be the content pane of an unsized frame, the frame will be squeezed into a very small rectangle in the top-left corner of the screen.
But if I set the size of frame first and then set the panel to be its content pane the frame will be properly drawn.
Why does this happen and how do I solve this if I really want to specify the size of JPanel rather than JFrame?
You should tell the frame to pack itself when it is first shown:
frame.pack();
frame.setVisible(true);
This will cause the frame to adopt a size that suits its contents.
Related
I've been using Java Swing for quite some time now and I never found a solution to this problem. When I create a JFrame the window surrounding it is actually smaller than the frame. In the included picture below my JFrame size is 800x600. The 2 white lines crosses at the center of the frame, 400,300. As you can see they are not at the center of the window. If I stretch the window right and down I can see some of the black background of the frame was hidden. When the black background is revealed you can see the the lines do indeed cross at the center (2nd picture).
Why is it working like that? Anything I can do to solve this problem? Im making a game where the playable character is in the center of the screen so this causes me a lot of problem. The 1st image is larger because i've left the code in the background. As we can see it's a standard JFrame creation.
Not centered because part of the frame is hidden:
centered when frame is fully revealed:
my JFrame size is 800x600
You are doing things backward.
The frame has decorations (ie. the title bar and borders). The panel where you do the painting is added to the frame, so therefore it will be less than the size of the frame.
The proper approach is to override the getPreferredSize() method of the JPanel where you do the custom painting to return the desired size of the panel.
Then you add the panel to the frame you invoke the pack() method on the frame. Now the frame will be sized slightly larger (to fit the complete panel and the frame decorations) and your painting will be accurate.
Currently, I have a full screen JFrame. Within that JFrame, is a panel called MainPanel which is 1280 by 640, a portion of the full screen game. The MainPanel is where my game is rendered to. Is there any way to scale this MainPanel to fit JFrame without having to adjust all the component sizes of sprites and such? I'm thinking of rendering MainPanel to an image and drawing it over JFrame, but I do not know how to go about this.
Thanks.
By default, the layout manager of a JFrame is BorderLayout, and adding a JPanel to it without any arguments will place it in CENTER, which will automatically scale to the size of the JFrame. It will ignore any size you have given the JPanel.
How should I get real JPanel size in JFrame?
The size will be 0,0 until it is displayed because the components and layout are not calculated beforehand.
thePanel.getSize();
This returns the Dimension.
I sometimes add a ComponentListener to show the dimension when the panel is resized.
EDIT: If you want the size of the content pane of the JFrame then
theFrame.getContentPane().getSize();
I have a JInternal Frame and I want to draw a circle(using 2Dgraphics) in it and make it flexible. I mean when I change the size of frame the circle become smaller or in making frame larger circle also become larger. Can somebody help?
You would draw in the paintComponent method of a JPanel or JComponent that is held in the JInternalFrame's contentPane, same as you would draw in any other JPanel. I'd get the dimensions of the JPanel at the start of the paintComponent method and use those values to tell how big to draw the circle.
Also, if you add the JPanel directly to the JInternalFrame's contentPane, it will be added by default BorderLayout.CENTER, and so when the JInternalFrame changes size, the JPanel also changes size, it's paintComponent will be called by the JVM, and the new drawing will be resized automatically.
add a WindowListener to the jInteralFrame and redraw whenever the size changes
I'll try to explain my problem as simply as possible but it's a tricky topic and people who haven't encountered the issue probably won't know what I'm talking about.
I want to use a BorderLayout using west, east, north, south, etc. components that are my "normal" components (JLabels, JButtons, etc.) then I want the center component to be an "image" (that is: pixels). To this end I'm using a BufferedImage and using setIcon on a JLabel that is inside a panel that is part of the "center".
However I want my image/pixels to be "fluid": whenever the user resizes the app, I want to compute the exact size of the JLabel (icon/text gap is set to 0) and then create a new image (pixels that I manipulate directly in a BufferedImage but whatever) that has exactly that size.
Now it does work fine. But only when I resize the main window ("window" as in "one of the window of the operating system) by making it bigger.
It doesn't work when I downsize my main window.
The reason, after a lot of testing, is obviously because the size of my JLabel (in which I did a setIcon( img ) is influencing the computation of the layout manager.
So here comes the billion dollar question: how should I use a BorderLayout (or any other layout) so that I can create a "fluid" rectangle of pixels in the center of my app?
Answering my own question with an answer that I will not accept even tough it does work...
The problem can be "worked around" by creating a picture a few pixels smaller than the getVisibleRect of the center area.
So in my case I create an ImageIcon from a BufferedImage that is 20 pixels smaller (both in width and height) than the area that will hold it.
What happens then is that because the picture is smaller it doesn't "block"/prevent the layout manager from putting everything at their correct place when downsizing the main window.
So by using such an hack I get the "fluid" behavior I want.
This is however an hack whose level of hackyness cannot be understated and I'm sure there's a very clean way to solve this.
The reason, after a lot of testing, is
obviously because the size of my
JLabel (in which I did a setIcon( img
) is influencing the computation of
the layout manager.
The preferred size of the JLabel is used in the preferred size of the panel, but this size is ignored when you resize the frame, since the CENTER only gets whatever space is left over after the preferred size of the other 4 components is considered.
To this end I'm using a BufferedImage
and using setIcon on a JLabel that is
inside a panel that is part of the
"center".
Sounds to me like it should work.
Create the panel with a BorderLayout. Add the JLabel to the Center of your main panel. Then add a ComponentListener to the panel. Now when the frame is resized the center panel size will be adjusted to take the space available to it. Now that you know the size of the center panel you can recreate the Icon and add it to your JLabel,
This is how you write a SSCCE:
import java.awt.*;
import javax.swing.*;
public class LabelTest2 extends JFrame
{
public LabelTest2()
{
JLabel picture = new JLabel(new ImageIcon("???.jpg"));
add(picture);
}
public static void main(String[] args)
{
LabelTest2 frame = new LabelTest2();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}