I have had this problem a few times before, and I finally attempted to solve it, but I cannot fond the right solution. I have a simple JFrame program. The basic JFrame code looks like this:
JFrame frame = new JFrame("halp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setResizable(false);
frame.setVisible(true);
Here's an image of what I'm trying to accomplish:
As you can see, there's space taken up by the top bar and the borders of the window. One way to fix this is to increase the size of the window, but that isn't neat at all, and also not every system has the same border sizes of the window.
I've done research and tried a few things I found on earlier asked questions:
frame.pack(). This method only set the window to minimal size, as if I didn't set the size at all.
frame.getContentPane().setSize(500,500);. The window still has the borders counted in the frame size.
frame.setPreferredSize(new Dimension(500, 500)); and JPanel.setPreferredSize(new Dimension(500, 500));. The frame went into minimum size, as with frame.pack().
I tried combining these methods, but nothing seemed to work.
What am I missing? Is there another aspect of the JFrame I need to add? Is it an incompatibility issue of BlueJ?
frame.getContentPane().setPreferredSize(new Dimension(500,500));
followed by a
frame.pack();
should solve your problem.
Related
I'm creating MTG game for school Java class and I run into problem. I'm currenty testing something... I have my game GUI (extends from JFrame), and when I doublclick on exile "pile" I create a new JFrame, then I add my cards into this JFrame (Card extends JPanel) and I tried to setsize based on frame.getComponentCount()
But problem is, it returns 1, whether a card was added or not.. like my card wasn't even counted as a component.
Code:
JFrame frame=new JFrame();
Image cardImage;
cardImage = ImageIO.read(new File("pics/background.png")).getScaledInstance(this.getWidth(),this.getHeight(),Image.SCALE_SMOOTH);
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.add(new Card(cardImage,false));
frame.add(new Card(cardImage,false));
frame.add(new Card(cardImage,false));
frame.setSize(frame.getComponentCount()*80, frame.getComponentCount()*80);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
So my frame.setSize doesn't work, because of wrong return.
...
Can anyone help me identify a problem? I don't get it, because frame.add input parameter is component (according to javadoc), but when I try getComponentCount is isn't counted as a component.
Just to be clear, everything else work, I get the new window, there are 3 cards as they supposed to be, I just have to manually resize it to see them.
You're getting back the count from the JFrame's single contentPane component. To get the sub components, call the method on the contentPane itself.
frame.getContentPane().getComponentCount()
But regardless, your design for setting size this way seems brittle, and is not how I would do things. Instead, have your components return their own best preferred sizes and call pack() on your JFrame after adding components.
My question have 3 parts.
I would like to know, how can I set JFrame window to be resizable, but can not go under a minim size so the user cant make it smaller then the minimum size.
I would like to know, how can I set JFrame window to be resizable, but still keep the aspect ratio (16:9) even if the user is resizing it.
I would like to know, how can I make the program become really full screen after he clicks a button so there are no borders and runs like a game or something (and if there is any specific issues how can I revert it back safely).
Thanks for your help and patient for my not perfect English and not perfect Java knowledge.
The provided answer is useful and answers part of my question, but still most of it still blank for me.
The part of the code:
private void createDisplay() {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
frame = new JFrame(title); //setting the title of the window
frame.setSize(width, height); //setting the width and height of the window
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //make sure program closes down properly
frame.setResizable(true);
frame.setLocationRelativeTo(null); //the window will apparel on the center
frame.setVisible(true);
frame.setIconImage(Assets.ImageMap.get("icon"));
canvas = new Canvas();
canvas.setPreferredSize(new Dimension(width, height));
canvas.setMaximumSize(new Dimension(width, height));
canvas.setMinimumSize(new Dimension(gd.getDisplayMode().getWidth() / 2, gd.getDisplayMode().getHeight() / 2));
canvas.setFocusable(false);
frame.add(canvas);
frame.pack(); //resize the window a little bit so able to see all of canvas
}
Set the frame's minimum size (setMinimumSize)
Is more difficult, as you are notified of the size change after the fact, so you'll always be fighting the system as it changes (and then you run into problems with who generated the size change event). It might be better to focus on keeping the ratio of the contents of the frame based on the available space within the frame (VLC is a good example of this)
Full screen exclusive mode
I have a JFrame maximized using
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
Some code between that and at the end
frame.setVisible(true);
frame.setResizeable(false);
Tough, Dragging the top of the window down resizes it anyways.
I added a ComponentListener to it to see if it detects being resized, and it does. The componentResized function gets called when i do the resize.
Any fix for this?
Thanks.
Dragging the top of the window down resizes it anyways
This is the way applications work in Windows. Try a native Windows application and you will see the dragging the window causes it to shrink to a preferred size.
You could try code like the following:
JFrame frame = new JFrame();
frame.setResizable(false);
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
frame.setMinimumSize(frame.getSize());
You can still drag the frame from its position, but you will not be able to resize it.
I would like to know how to put a JLabel on top of another JLabel at a specific position, in a class that extends JPanel in Java. People have asked for help with this before but the solutions that I found do not satisfy me. I am using GridLayout, here is some of my code:
//imports
public class Game extends JPanel implements MouseListener {
Icon background = new ImageIcon(getClass().getResource("/background.jpg"));
Icon foreground = new ImageIcon(getClass().getResource("/foreground.jpg"));
JLabel backgr = new JLabel(background);
JLabel foregr = new JLabel(foreground);
JFrame frame = new JFrame("Game");
public Game() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
backgr.addMouseListener(this);
frame.setLayout(new FlowLayout());
frame.setPreferredSize(new Dimension(200,200));
frame.pack();
frame.setVisible(true);
frame.addMouseListener(this);
backgr.setLayout(new BorderLayout());
frame.add(backgr);
backgr.add(foreground);
}
}
(I have a lot of other methods in this class, such as some mouse stuff, but I don't include them here since they are not relevant to this problem.)
Currently the code almost works as I want, the foreground picture is displayed on top of the background, right in the middle of it. But I would like the foreground picture to be displayed at specific coordinates on the background picture. I thought that if I wanted to display the foreground at coordinates (50, 50), I could say backgr.add(foreground, 50,50), this compiles but returns an error when I run the program. Any tips of what to do? It would be really appreciated.
Edit: I discovered that by saying backgr.setLayout(null), backgr.add(foregr) and then foregr.setLocation(50,50), we can do what I was looking for. But since not using a layout manager is discouraged, I am looking for better solutions, so that I can use the coordinates on the backgr Icon.
People have asked for help with this before but the solutions that I found do not satisfy with me since they require me to set the frame layout to null, but I am using GridBagLayout
The frame is using a GridBagLayout.
You are adding the foreground JLabel, so the background JLabel. The background label can use any layout (including null) that you wish.
the foreground picture is displayed on top of the background, right in the middle of it.
That is because you are using a BorderLayout and are adding the foreground to the CENTER, which is the default when you don't specify a constraint.
i have created FlowLayoutEx with some operations.then tried to put them into frame in standart way.
public static void main(String args[]){
FlowLayoutEx applet=new FlowLayoutEx();
JFrame frame=new JFrame("HW2LayoutSettings");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(applet,BorderLayout.PAGE_END);
applet.init();
applet.start();
frame.setSize(400,300);
frame.pack();
frame.setVisible(true);
}
It probably does show up, but maybe it's too small or an Exception was thrown before, it's impossible to know without knowing what your FlowLayoutEx class is.
But when you call pack() you set the window to a size corresponding to the preferred size of its components. It means:
Your previous call to setSize is useless since the size is set again by the call to pack
Your custom component should be set a preferred size.
What is the preferred size (re getPreferredSize()) of applet? Could it be (0, 0)? Is the JFrame using a BorderLayout? I think that is the default, but I'm not sure. Try setting it yourself: frame.setLayout(new BorderLayout()). Not sure about BorderLayout.PAGE_END - I always use BorderLayout.CENTER (for the main, or only, component in a JFrame).