Creating a new GUI in Java (1.8) Swing, I am searching for a way to override resize behavior of all my components.
Let me explain to you with some edited photos:
This is my full screen GUI, with 3 panels and a JToolBar
. The green one needs to have a fixed size, the others would be resizable.
Currently, I only have 2 small GridLayout
to organize them (one vertical, and one horizontal for green and cyan panels).
If I, for example, reduce the frame size from the right side, I want my blue and cyan panel to be resized according to the new frame size. But the green panel must be fixed. (Not the most difficult part I think.)
This is the most difficult part for me. As soon as the cyan (or blue) panel reach is minimum size, I want him to "push" the green panel to the left, even if it disappears off the frame.
Of course, pulling the frame to the right will make the green panel appear again.
How could I do it?
I thought of using JSplitPane
or a specific listener to manually decide the resize behavior but I need some advice.
Sorry if an existing post can answer this, I didn't find any answer explaining the issue for me.
Thanks in advance!
If you want more examples, look at the "Evernote" software which acts the same way
To resize a frame, There is a method JFrame. setSize(int width, int height) which takes two parameters width and height.
Java (Swing/AWT) uses something called LayoutManager s to place UI components on the screen. These LayoutManagers are responsible to render component such as TextField, CheckBox, etc in a predefined manner on your Window. For example: A LayoutManager called FlowLayout simply places components one after the other.
Using setSize() you can give the size of frame you want but if you use pack() , it will automatically change the size of the frames according to the size of components in it. It will not consider the size you have mentioned earlier.
Setting the max/min/preferred size of the Green
panel can keep that panel the same size under the first condition. To check for resizes, you can use a ComponentListener
on one of the other JPanel
's - if the size gets below a particular width then change the max/min/preferred size of the Green
panel.
Below is a hacked together example of doing this - it resizes the Green
panel when the Blue
is < 600, and the resize is a weighted resize (30% of total width). To get the true L&F and that you desire you may have to play with the layout/sizes.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
public class GridTest extends JPanel{
private boolean changeAllowed = false;
//keep reference to cyan for the height dimension
final JPanel cyan = new JPanel();
public GridTest(){
cyan.setPreferredSize(new Dimension(600, 300));//provide sizing hint
}
private Dimension getCustomDimensions(){
if ( changeAllowed ){
return new Dimension((int)(super.getParent().getBounds().width * 0.3), cyan.getBounds().height);
}else{
return new Dimension(200, cyan.getBounds().height);
}
}
@Override
public Dimension getMaximumSize(){
return getCustomDimensions();
}
@Override
public Dimension getMinimumSize(){
return getCustomDimensions();
}
@Override
public Dimension getPreferredSize(){
return getCustomDimensions();
}
public static void main(String[] args) throws Exception{
SwingUtilities.invokeAndWait(new Runnable(){
@Override
public void run() {
final int MINIMUM = 600;
JFrame frame = new JFrame();
frame.add(new JToolBar(), BorderLayout.NORTH);
final JPanel blue = new JPanel();
final GridTest green = new GridTest();
green.setBackground(Color.green);
green.setOpaque(true);
green.cyan.setBackground(Color.cyan);
green.cyan.setOpaque(true);
blue.setOpaque(true);
blue.setBackground(Color.blue);
blue.setPreferredSize(new Dimension(900, 300));//hint at size
blue.setMinimumSize(new Dimension(100, 200));//hint at size
//Nest Box Layouts
Box top = Box.createHorizontalBox();
top.add(blue);
Box bottom = Box.createHorizontalBox();
bottom.add(green);
bottom.add(green.cyan);
Box vert = Box.createVerticalBox();
vert.add(top);
vert.add(bottom);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(vert);
//listen for resizes
blue.addComponentListener(new ComponentAdapter(){
@Override
public void componentResized(ComponentEvent e) {
if ( blue.getBounds().width < MINIMUM ){//set flag
green.changeAllowed = true;
}else{
green.changeAllowed = false;
}
}
});
frame.pack();
frame.setSize(800, 600);
frame.setVisible(true);
}
});
}
}
This is how I do it and I am not sure this is the proper way:
First set the layout to null.
Next create a component resized event for your frame:
addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e){
}
});
Inside here you can manually make changes to the components as it is resized. I have done this for a few of my programs to keep a scroll pane on the left and right of the frame always the same width and have everything else size up and down as resized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With