Reputation: 3
I have a JPanel with the paintComponent method drawing things in a square shape. I would like that square to always be centered horizontally in my JFrame (filling the whole height of the frame) and to have two black JPanels (one on each side) filling the rest of the width (they will contain buttons and text).
However I can't manage to force the JPanel containing the Graphic object to be how I need. The JPanel always fills the rest of the screen and I don't know how to fix that or to force the side panels to be come to the sides of the square.
What I'd like to achieve:
What I have right now:
Upvotes: 0
Views: 708
Reputation: 51565
What you want isn't how Java Swing normally allocates space.
I created a GUI that keeps the center JPanel
square.
Here's the GUI at its defined size.
Here's the GUI after I manually stretched it out.
Stack Overflow shrank the image to fit the answer. You can tell because the text font appears to shrink.
Caution: If you maximize the GUI by clicking on the square in the upper right, you lose the ability to restore the GUI to its original size.
I did this by creating three JPanels
and setting their preferred size. I put these three JPanels
inside of the main JPanel
, whose size I monitor with a ComponentListener
.
When you resize the JFrame
by grabbing an edge and dragging, the ComponentListener
calculates the new size of the three JPanels
, keeping the center JPanel
square, and dividing the rest of the space between the left JPanel
and the right JPanel
.
I used FlowLayouts
for the three JPanels
. You can also use a GridBagLayout
. The layout manager you choose to use has to respect the JPanel
resizing.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TripleJPanelGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new TripleJPanelGUI());
}
private JFrame frame;
private JPanel leftPanel;
private JPanel centerPanel;
private JPanel rightPanel;
@Override
public void run() {
frame = new JFrame("Triple JPanel GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PanelListener listener = new PanelListener(this);
frame.add(createMainPanel(listener), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel(PanelListener listener) {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
panel.addComponentListener(listener);
leftPanel = createLeftPanel();
centerPanel = createCenterPanel();
rightPanel = createRightPanel();
panel.add(leftPanel);
panel.add(centerPanel);
panel.add(rightPanel);
return panel;
}
private JPanel createLeftPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBackground(Color.YELLOW);
panel.setPreferredSize(new Dimension(100, 400));
JLabel label = new JLabel("JPanel");
label.setFont(panel.getFont().deriveFont(24f));
panel.add(label);
return panel;
}
private JPanel createCenterPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBackground(Color.GREEN);
panel.setPreferredSize(new Dimension(400, 400));
JLabel label = new JLabel("Always a Square");
label.setFont(panel.getFont().deriveFont(24f));
panel.add(label);
return panel;
}
private JPanel createRightPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBackground(Color.BLUE);
panel.setPreferredSize(new Dimension(100, 400));
JLabel label = new JLabel("JPanel");
label.setFont(panel.getFont().deriveFont(24f));
label.setForeground(Color.WHITE);
panel.add(label);
return panel;
}
public void updateLeftPanel(int width, int height) {
leftPanel.setPreferredSize(new Dimension(width, height));
}
public void updateCenterPanel(int width, int height) {
centerPanel.setPreferredSize(new Dimension(width, height));
}
public void updateRightPanel(int width, int height) {
rightPanel.setPreferredSize(new Dimension(width, height));
}
public JFrame getFrame() {
return frame;
}
private class PanelListener extends ComponentAdapter {
private TripleJPanelGUI frame;
public PanelListener(TripleJPanelGUI frame) {
this.frame = frame;
}
@Override
public void componentResized(ComponentEvent event) {
JPanel panel = (JPanel) event.getSource();
Dimension d = panel.getSize();
int width = (d.width - d.height) / 2;
int height = d.height;
frame.updateLeftPanel(width, height);
frame.updateCenterPanel(height, height);
frame.updateRightPanel(width, height);
frame.getFrame().pack();
}
}
}
Upvotes: 1