I'm making Minesweeper as a school project. It's close to completion, but the only problem now is setting JFrame's size. I just can't figure out a way to set frames to the size I want.
The program looks almost like a Swing version of the original Minesweeper on Windows XP.
The main frame's layout is flow layout. There's a top panel for the time, mines, and reset button. The top panel's using flow layout, and the bottom panel's using grid layout for the buttons.
I set the preferred size of the frame's content pane. Getting the width is easy (The numbers of fields in a row * my button size), but the problem is getting the height right. The frame always go down to the 2nd last row of the minefield.
I also tried pack() but it resizes it to the preferred size of the content pane, which isn't the right size to begin with. What can I do?
Don't have the JFrame (or better its contentPane) use FlowLayout since this won't give the JFrame the best size for its components. Instead why not have it use the default BorderLayout? Your mine cell's will probably have their getPreferredSize() method overridden and thus will direct the size of the enclosing containers. As always, call pack() on the JFrame after filling it with components and before calling setVisible(true) on it.
Set a preferred size for the buttons in the GridLayout and pack() the frame after adding them.
Don't try to manually set the size. You should let each component display at its preferred size and use the pack() method.
The main frame's layout is flow layout. There's a top panel for the time, mines, and reset button
I would use a BorderLayout. Create a top panel and add it to the NORTH.
Then create a panel for the grid and add it to the CENTER. If you have problems with the buttons in the grid resizing then try creating a JPanel as a wrapper panel. Add the buttons to this panel and then add this panel to the CENTER of the frame. The panel will retain its preferred size.
Related
What is the best way to display let's say rectangle (3x5) with icons 20x20 px.? I want to change the image file of every pic icon later (= it's not just static pictures). I tried to make JFrame full of JPanels, but i was able to display only one panel at a time. I don't want to use GridLayout, because I need just small rectangle inside a frame. Any ideas how to do it? Couldn't find any tutorial or solution. I'm completely new to GUI developement. Thanks
You do want to use a GridLayout. Your problem is that the JFrame you put the icons into uses a BorderLayout by default (and really, you shouldn't change the layout of a top level component).
What this means is that, if you add multiple panels to the frame, without using one of the NORTH, EAST, SOUTH, WEST constraints, only one of the panels will be visible and take up all the space. If you use a GridLayout for that one panel you get, the icons will be stretched, because the panel receives all the space due to the frame's BorderLayout. An alternate layout that doesn't stretch its contents is FlowLayout, but the layout to use depends heavily on your context.
To display the icons, a JLabel is handy. Use an ImageIcon for the label's icon. You can later use setIcon() on the label to choose a new icon.
overall, my approach would be this:
use a JFrame which has a BorderLayout
to the frame, add a JPanel to the frame. The default layout is a FlowLayout, which will prevent the stretching
to the panel, add a JPanel with an appropriate GridLayout
to that panel, add the JLabels, each having an appropriate ImageIcon
I have a JFrame that has a JPanel inside. I call "setPreferredSize(new Dimension(500, 600));" but I want the JPanel and its contents to resize when someone resizes the JFrame.
BorderLayout is the way to go. Components start at their preferred size, but are expanded as needed to fill the region they are in.
Set your layout on your frame with BorderLayout
Add your JPanel by
frame.add(yourPanel, BorderLayout.CENTER);
This will allow it to stretch vertically & horizontally
As for the Contents inside a JPanel, give it a layout that will accommodate stretching as well.
Use a layout manager instead of setting the bounds for each component.
It is going to vary from program to program how you want your components to move.
Take a look at this and try to see which layout will work best for you.
So I'm making a program as a project for school.
In this program I have a panel inside a scrollpane.
When I click a button a panel with info is added to the panel inside the scrollpane.
I can keep adding as much of these panels as I want.
I set the layout of the panel to FlowLayout.
I disabled the horizontal scrolling and set the width of the panel to the width of the scrollpane so I neatly get two of those 'forms' next to each other before it starts a new row of panels.
Problem is the vertical scrolling doesn't activate so I can see only 1,5 rows of panels. (see picture)
http://i1281.photobucket.com/albums/a518/Bas_Van_den_Steen/Screenshot2014-05-22191813_zps44483b9b.png
I suspect this has something to do with the height of the main panel I had to define if I wanted to set a width.
Ideally there should be an option to set the height to 'automatic', but there isn't.
I know scrolling works because when I enable horizontal scrolling and don't set any dimensions for the panel it just keeps adding forms in a single row which I can scroll through.
I think I might need to use another LayoutManager (but I don't have any experience setting those up) or change some of the settings of the scrollpane or main panel.
Can someone help me with this?
I set the width of the panel to the width of the scrollpane so I neatly get two of those 'forms' next to each other before it starts a new row of panels. Problem is the vertical scrolling doesn't activate
A FlowLayout is designed to display components horizontally and the preferred size is always based on a single row of components.
Use a different layout manager. Maybe a vertical BoxLayout, or GridBagLayout or GridLayout depending on your exact requirement.
Read the section from the Swing tutorial on Using Layout Managers for more information and working examples.
set the width of the panel to the width of the scrollpane
You should not be manually setting the preferred width of you panel. As I mentioned earlier that is the job of the layout manager. Maybe the GridLayout is closes to what you need.
I have a JTabbedPane and a JTextArea, I want the Textareas/Panes to resize to fit the window when the window is resized. How do I do this? I'm also fuzzy on if it's the right text component to use.
Really Muddled.
EDIT: I was setting explicit size as a dumb dumb. I've got it all worked out. What I did is set the viewport of a JScrollPane as the JTextArea and remove all explicit sizing.
Thanks chaps!
You can use whatever components you like. All JComponents can resize with a resizing parent container. You simply need to choose the correct LayoutManager.
Depending on how you want everything set up, I assume you will want to add your JTabbedPane to your JFrame like so:
JTabbedPane jtp;
JFrame frame;
// JFrame's default layour is border layout.
frame.add(jtp, BorderLayout.CENTER);
This will cause the JTabbed pane to take up all of the space of the JFrame.
You will also need to set your JTabbedPane's layout manager to BorderLayout, and also any tab you add to the JTabbedPane will need to have a BorderLayout.
To set the layout of your components, do:
JComponent anyComponent;
anyComponent.setLayout(new BorderLayout());
Have a look at the Java LayoutManager tutorials for more information.
I should mention that the reason I suggest BorderLayout is because any component added to the CENTER of a BorderLayout will automatically take up any space not taken up by any of the borders. And, since you aren't adding anything to any of the other borders (NORTH, SOUTH, EAST, WEST) the component in the center will take up the entire space.
Every JComponent is resized automatically when the container it resides in, is resized.
It's not a matter of the right component but more a matter of which LayoutManager to use.
When adding a Component to a container, you can set the minimum size, default size and maximum size.
On resizing the container, the component will scale automatically until reaching the desired maximum size.
If you need code snippets, tell me and I will fire up my IDE later.
cheers
EDIT: jjnguy beat me to it.. nvm then :p
I created a JFrame initialized with a BorderLayout and a JScrollPane as its CENTER element.
The scroll pane is set with VERTICAL_SCROLLBAR_ALWAYS and HORIZONTAL_SCROLLBAR_NEVER policies. The intent of my frame is to have a controlled width, while the height should grow/shrink as data is added/removed.
Inside my scroll pane, I added a simple JPanel (lets call it the content panel) which is initialized with a FlowLayout (and LEADING policy).
In order to test this, I simply populate my content panel with 20 JLabel("Item " + n) components where n is the loop counter.
I would expect to see my labels shown on a single row if the frame is large enough and the labels wrap to other lines when I shrink the width. But instead, there is only a single line displayed with no wrapping... ever.
Does anyone know why the flow layout does not wrap when a scroll pane is involved?
If I remove the scroll pane all together and put the content panel directly in the frame, the desired wrapping effect occurs, but if the frame height is shrunk smaller than the content panel height it just disappears.
The idea is that I want my labels to be wrapped when necessary but also always be visible if it means having to scroll up/down.
Any suggestions on how to fix this?
Thanks.
Wrap Layout gives an explanation and a solution.
If you work with the designer, you have to set the prefferedSize property to null (delete what is set) then set the preferred size by clicking the triple dots [...] button next to the prefferedsize property name and put your preferred value.
I encountered the same problem and it works for me.