Get the real size of a JFrame content (NEW) - java

I am writing a Game in Java, and I don't want to use a layout manager for my JFrame. My class extends JFrame, and looks something like this:
//class field
static JPanel contentPane;
//in the class constructor
this.contentPane = new JPanel();
this.contentPane.setLayout(null);
this.setContentPane(contentPane);
I want my JPanel be exactly 600x600 px, but when I set the size of my JFrame by calling the this.setSize(600,600) method, the JPanel size is less than the 600x600 px because the border of the JFrame window is included too.
How can I set the size of the JPanel to be exactly 600x600 px?
P.S. I have seen all of the previous post and none of them work for me.
For example:
Get the real size of a JFrame content does not work for me.
What else can I do?

How can I set the size of the JPanel to be exactly 600x600 px?
Override the getPreferredSize() method of your custom game panel to return the size you want the panel to be.
#Override Dimension getPreferredSize()
{
return new Dimension(600, 600);
}
Then the basic code to create your frame will be:
GamePanel panel = new GamePanel();
frame.add(panel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
Now all your game logic will be contained in the GamePanel class.

If you don't need the Frame-Decorations (icon, title, min/max/close-buttons and the border), you can make a Frame undecorated, then it has exactly the size you gave it
java.awt.Frame.setUndecorated(boolean)

Related

Java cannot display the JPanel, but can display JLabel?

The question is that I cannot add JPanel and JLabel in the Frame at the same time.
When i using following code, only MyPanel will be visible. myFrame.add(myLabel);myFrame.add(myPanel);myFrame.setVisible(true);
when I execute: myFrame.add(myLabel);myFrame.setVisible(true);myFrame.add(myPanel);
only myLabel will be visible.
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
MyFrame myFrame = new MyFrame();
MyLabel myLabel = new MyLabel();
MyPanel myPanel = new MyPanel();
myFrame.add(myLabel);
myFrame.add(myPanel);
myFrame.setVisible(true);
}
}
public class MyFrame extends JFrame {
MyFrame() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //exit out of application.
//https://docs.oracle.com/javase/7/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29
this.setSize(750, 750); //set the size.
this.setResizable(true);//resize the frame.
this.setTitle("Welocme to new world."); //set the Title.
ImageIcon imageIcon = new ImageIcon("logo.png");
this.setIconImage(imageIcon.getImage());
this.getContentPane().setBackground(new Color(217, 217, 217));
this.setBackground(Color.YELLOW);//this.setVisible(true);//Make the frame visible.
}}
import javax.swing.*;
import java.awt.*;
public class MyPanel extends JPanel {
MyPanel() {
this.setBackground(Color.white);
this.setBounds(2,2,25,25);
}}
import javax.swing.*;
import java.awt.*;
public class MyLabel extends JLabel {
MyLabel(){
this.setText("<html>Heaven <br/>Heaven's body\"<br/> Whirl around me <br/>Make me wonder</html>");
//,SwingConstants.CENTER);
//https://stackoverflow.com/questions/1090098/newline-in-jlabel
//How to print multi line in java
ImageIcon image = new ImageIcon("Cosmogony_Björk_Cover.jpg");
this.setIcon(image);
//jLabel.setForeground(new Color(217,217,217));
this.setForeground(Color.BLACK);
this.setFont(new Font("helvetica",Font.PLAIN,18));
this.setBackground(Color.gray);
this.setOpaque(true);
//jLabel.setVerticalTextPosition(JLabel.TOP); Set the relative text position of the label.
//jLabel.setBorder();
this.setVerticalAlignment(JLabel.CENTER);
this.setHorizontalAlignment(JLabel.CENTER);
}}
The default Layout Manager of JFrame is the BorderLayout.
Since you did not change the layout manager of your JFrame this is also the current layout manager used in your snippet.
Usually, when using the BorderLayout, you specify which area of the BorderLayout should be populated when adding a component. This is usually done via
frame.add(component, BorderLayout.CENTER);
Notice the area specification in the add() method, which tells the BorderLayout where to place the component.
Here is the issue however. If you use the add() method in combination with the BorderLayout without specifying the placement of the component, it will always place the component in BorderLayout.CENTER. (Causing the component which is currently there to be replaced)
To work around this, do one of the following things:
Specify the placement explicitly, so both components will show up:
frame.add(component1, BorderLayout.PAGE_START);
frame.add(component2, BorderLayout.CENTER);
Or use a different Layout Manager, which will take care of the placement for you. E.g. FlowLayout
JPanel contentPanel = new JPanel(); // JPanel uses flowlayout by default!
contentPanel.add(component1);
contentPanel.add(component2);
myFrame.setContentPane(contentPanel);
You could also explicitly set the layout:
Container contentPane = myFrame.getContentPane();
// creates new FlowLayout and sets on content pane
contentPane.setLayout(new FlowLayout());
contentPane.add(component1);
contentPane.add(component2);
Sidenotes:
Look through the Laying out components within a container Oracle tutorial, which will give you more information on which layout managers there are and how to work with them.
When building your GUI, setVisible() on the JFrame should be the last thing you are doing after adding all components. Because if you add components after setting the frame visible, the changes will not immediately take effect without you telling swing that something changed.
When correctly working with the Swing Layout Managers, there should be no need to use things like setBounds(...) or setSize(). After adding all components, calling pack() on the JFrame is the preferred way to go. This will size the JFrame according to the preferred size of the components inside.

Centering a fixed size canvas in a JFrame

I'm in the process of creating a circuit editor (similar to any regular paint software with a basic menu and a canvas with specifiable dimensions). I am currently trying to transform the previously unscrollable canvas (JPanel) to a scrollable one.
The obvious design error at the moment is that while the scrollbars seem to correctly reflect the internal size of the canvas (which can of course be way bigger than the JFrame), due to the canvas JPanel being added in the CENTER of the BorderLayout of the master panel, it always resizes along with the JFrame.
public final class MainFrame extends JFrame
{
public MainFrame()
{
JPanel menuPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
// Populate Menu Panel
// ...
JPanel canvasPanel = new JPanel();
canvasPanel.setBackground(Color.white);
Dimension canvasDims = new Dimension(800,600);
canvasPanel.setPreferredSize(canvasDims);
canvasPanel.setMinimumSize(canvasDims);
canvasPanel.setMaximumSize(canvasDims);
JScrollPane canvasScrollPane = new JScrollPane(
canvasPanel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JPanel masterPanel = new JPanel(new BorderLayout());
masterPanel.add(menuPanel, BorderLayout.NORTH);
masterPanel.add(canvasScrollPane, BorderLayout.CENTER);
setContentPane(masterPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1200, 700);
setMinimumSize(new Dimension(500, 500));
setLocationRelativeTo(null);
setVisible(true);
}
I've read quite a few posts regarding centering JPanels and scrollbars but with both complexities added together, things might be a bit more complicated as I haven't yet found a solution.
What I'm really trying to achieve is to have the canvas' JPanel fixed in whatever size the user might have specified and centered in the middle as well as the scrollbars behaving as one would expect like in the beloved windows' paint:
How would you go about doing this/fixing my design? Any help would be greatly appreciated!
P.S. Happy new Year :)
JPanel fixed in whatever size the user might have specified and centered in the middle as well as the scrollbars behaving as one would expect
So you need to nest panels so the canvas panel can be displayed at its preferred size, while the parent panel resizes with the size of the frame.
An easy way to do this is with a JPanel that uses a GridBagLayout. Then you add the canvas panel to this panel using the default GridBagConstraints.
So the basic structure of the panels would be:
JPanel canvas = new JPanel();
canvas.setPreferredSize( new Dimension(300, 300) );
canvas.setBackground(Color.RED);
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(canvas, new GridBagConstraints() );
frame.add(new JScrollPane(wrapper));
Note: there is no need for your "masterPanel". The default layout manager for the content pane of a JFrame is a BorderLayout, so you just add the "menuPanel" and "scrollPane" directly to the frame with the proper BorderLayout constraints.

Centering a JFrame?

I'm using one of the methods to try to center my frame called
frame.setLocationRelativeTo(null);
but it's centering it by putting the upper-right corner of the frame in the center of the screen, and that's not what I wanted. I wanted to make it so that it centers the frame itself in the middle, or in other words, I want the center of the frame to the in the center of the screen. Is there any other methods to do this? Thanks for the help.
More codes below:
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
} //I'm using this method to override the Jframe and return the panel size
and I'm using the:
frame.pack();
method to make the Jframe fit whatever size the jpanel size is, which is why a size isn't created for the jframe. But even if I do create the size for the jframe, and use the setLocationRelativeTo(null) method, nothing changes.
Normally if you're using Java 1.4 or newer the method setLocationRelativeTo(null) should help. It's weird that it reacts like that, could you maybe post your java file so we can see what's wrong?
Also, you have to setSize() your frame BEFORE using the setLocationRelativeTo(null) method.
Kindly,
Solid
You can get the size of your screen with Toolkit.getDefaultToolkit().getScreenSize(). Assuming you're not using multiple displays, it's simple from there to set the location of your JFrame such that it is centered in the screen.
public static void main(String[] args){
JFrame f = new JFrame();
f.getContentPane().add(new JLabel("Label"), BorderLayout.CENTER);
f.getContentPane().add(new JButton("Button"), BorderLayout.SOUTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation((screen.width - f.getWidth())/2, (screen.height - f.getHeight())/2);
f.setVisible(true);
}
It is important that the pack() call happens before setLocation, or it might not be centered again.
You could even create a subclass of JFrame that re-centers itself whenever it packs, as such:
class CenteredFrame extends JFrame{
#Override
public void pack(){
super.pack();
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screen.width - getWidth())/2, (screen.height - getHeight())/2);
}
}

JButton added to JPanel doesn't show

I can't seem to add a JButton to a JPanel.
I have a PropWindow (JFrame) that has a PropView (JPanel) in it. the PropView-JPanel seems to be added correctly because I can draw shapes on it with paint().
But when I use this to try adding a button it just won't show up att all :/
JButton testButton;
public PropView(int width, int height) {
super(true);
setLayout(null);
setSize(width, height);
//TestButton
testButton = new JButton("Test");
testButton.setLocation(10,10);
testButton.setSize(100, 50);
testButton.setVisible(true);
add(testButton);
setFocusable(true);
setVisible(true);
}
The JFrame and the JPanel are both 250x600 px.
I can't tell from the code snippet you posted but just in case: make sure you call pack () on the frame after you have added the panel or any other components.
Also, it's usually discouraged to extend a JPanel or JFrame, unless you have a good reason to do it, just a heads up.
Here you have a short tutorial about displaying frames:
And some sample code in it that might help:
//1. Create the frame.
JFrame frame = new JFrame("FrameDemo");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3. Create components and put them in the frame.
//...create emptyLabel...
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);
Make sure you added PropPanel to PropWindow using myPropWindow.getContentPane().add(myPropPanel), not just myPropWindow.add(myPropPanel).

Layering JPanels with background image

I wanted to have a background image and two panels atop them. Learnt that JLayeredpane's are quite suitable. So I extended a JLayeredPane in my class and tried to draw the image from paint(). I got it working. But when I added other layers over it they weren't visible.
Again I thought of removing the bgimage from LayeredPane, added to the first layer above it(in JPanel). Now the image is not visible. Why does it happen? I wanted to do some thing like the screenshot I've provided. Pls help.
My code:
From my JFrame:
Container cp = this.getContentPane();
JLayeredPane backDropPanel = new JLayeredPane();
cp.add(backDropPanel,BorderLayout.CENTER);
backDropPanel.add(new bgPanel(), new Integer(1),0);
backDropPanel.add(new itemScrollerPanel(), new Integer(1),0);
Panel's:
class bgPanel extends JPanel{
String imageLocation = "/home/phantom/Desktop/BackDrop3.jpg";
private Image bgImage;
bgPanel(){
bgImage = new ImageIcon(imageLocation).getImage();
setPreferredSize(new Dimension(800,500));
setLayout(null);
setOpaque(true);
}
public void paint(Graphics g){
super.paint(g);
g.drawImage(bgImage,0,0,this);
}}
class itemScrollerPanel extends JPanel{
itemScrollerPanel(){
setBounds(0,100,200,200);
setBackground(Color.RED);
setOpaque(true);
}}
In this code I get to see the itemsScrollerPanels's RED BG drawn. But not the image of bgPanel class.
My requirement is something like this:
Without setting your bgPanel size explicitly, I get
System.err.println(bgPanel.getSize());
//java.awt.Dimension[width=0,height=0]
If you change your code from
setPreferredSize(new Dimension(800, 500));
to
setPreferredSize(new Dimension(800, 500));
setSize(800,500);
You should see the panel painted.
Try to change the setOpaque() to false so that all the pixels of JPanel are not painted .Thus making it transparent.If you still cant do it,check whether the Jpanel is actually opaque or not using isOpaque()

Categories

Resources