• Post Reply Bookmark Topic Watch Topic
  • New Topic

How to create a JPanel that maintains the same aspect ratio when resized?

 
Louis Lewis
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello, I'm trying to create a chess program that uses a JPanel with an 8 by 8 grid layout with 64 jlabels with icons. However, I don't want the icons to be distorted if the user resizes the window in such a way that makes the panel not square. Is there any way I could create a JPanel that maintains a square aspect ratio when it is resized?
 
Chris Barrett
Bartender
Posts: 317
24
Eclipse IDE Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Louis,

GridLayout will resize the JLabel to fill all available space within it's cell, but the ImageIcon dimensions would be fixed. So, it shouldn't be an issue. If the icon was 25 x 25, and the JLabel dimensions was 50 x 25, 12.5 pixels of padding would appear on each side of the icon. Please see my attached example output that I drummed up quickly using:



For more information on using GridLayout, please review: http://docs.oracle.com/javase/tutorial/uiswing/layout/grid.html

Cheers!
Chris
2014-02-22_19-58-16.png
[Thumbnail for 2014-02-22_19-58-16.png]
Really Wide
2014-02-22_19-58-05.png
[Thumbnail for 2014-02-22_19-58-05.png]
Really Tight
 
Louis Lewis
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe I didn't phrase my question correctly, but your pictures are exactly what I'm trying to avoid. I would like the board to be a square no matter what size it, even if this means leaving empty space below or to the side of it. I don't ever want any space in between the board squares, I just want all of them to get bigger or smaller when the window is resized. And I have figured out how to get the pictures themselves to maintain their aspect ratio within gridlayout, but I'm trying to avoid the shifting of the space between the rows and columns of the board by creating a jpanel to house all the squares in that stays square no matter how it is resized.
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not sure how the ProportionalPanel should work. I think the logic is more complicated than that.

Take a look at this example. It overrides the getPreferredSize() method of the panel to base its size on the size of its parent panel.

You will need to modify the code for your requirement, but it should get you started in the right direction.
 
Louis Lewis
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, I modified and combined the example code with mine, and now the board successfully stays square. However, I would like the board to be in the top left of the main panel at all times, but the example has the board constantly centered (which the author says is very important). When I remove the centering of the chessboard within the main panel, sure enough, the old resizing behavior takes over. Anyone know how to fix this? I thought components in java were positioned based on their top left corner, not the center, so I didn't think position would matter to making the board resize correctly, but apparently it does. Here is my code right now:

 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
but the example has the board constantly centered (which the author says is very important).


That was a requirement for the author's app. The easiest way to center a component is the use a GridBagLayout.

Read the section from the Swing tutorial on How to use Grid Bag Layout. The wightx/weighty constraints allow you to align a component.

 
Louis Lewis
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've tried changing the gridbag constraints, but this doesn't seem to affect anything. I think the problem is this set of lines:



When I change the layout of the whole thing to anything other than BorderLayout, or when I change the third line above to anything other than BorderLayout.CENTER, the whole board dissapears. Do you know why this is?
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just use a FlowLayout left aligned, instead of the GridBagLayout.
 
Piet Souris
Rancher
Posts: 1635
36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another possibility is to use a BufferedImage as your chessboard. It is then very easy
to draw it in the left upper corner of the JPanel, with size equal to the minimum of
getWidth() and getHeight().

Of course, that has some consequnces for detecting mouse clicks and updating
your board, but I don't think it is difficult to implement.

And anyway, in my chess program, I simply made the frame unresizable
 
Louis Lewis
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To Piet, I'll look into that thank you.

And to Rob, I did try adding the panel as the first (and only) component) in a flow layout, but then the board promptly dissapeared, and I'm not sure (it also dissapears for any layout other than BorderLayout, and any other BorderLayout specification than BorderLayout.CENTER). Here is what I tried:

 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know what you are doing. I suggested you need to use a left aligned FlowLayout instead of a GridBagLayout.

Only one statement in your code uses a GridBagLayout. Why are you changing other lines of code?

Also, a proper SSCCE, includes the main(...) method.
 
Louis Lewis
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Awesome, that worked thank you! I'm not sure I understand what I've done exactly though-so many panels inside panels inside panels with different layouts. So I'll have to go back over the code to figure out what its doing now. Here is the final code:

 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!