We created a small SWING test application with three panels. The main JPanel, which contains two smaller ones. One on the left (panel panel), the other on the right (side panel). Both inner panels are set to the required specific size, calling the minimum, preferred and maximum methods. The button on the right panel makes the parent JFrame non-re-significant. Everything looks great until the parent frame is resized, which causes (?!) A change in the size of the frame and the main panel, which become larger.
Look for why resizing occurs, and what can be done so that the main panel and frame size are covered by only two internal panels, and no more, once the frame is frozen.
Highlighted the borders of the panel and added an event log for debugging calibration issues.
Thanks for the help and understanding!
edit: This problem occurs in JRE 8. In JRE 9, it goes away, but introduces a scaling problem. The whole application scales on my 4k monitor, running on Windows 10.
package org.fubar;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PanelTest {
private static final String appTitle = "JPanel Test by Fubar.org(c)";
public static JFrame myFrame = null;
public static JPanel mainPanel = null;
public static JPanel boardPanel = null;
public static JPanel sidePanel = null;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Create and show GUI");
JFrame myFrame = new JFrame(appTitle);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel = new MainPanel();
myFrame.add(mainPanel);
myFrame.pack();
centreWindow(myFrame);
myFrame.setVisible(true);
}
public static void centreWindow(Window frame) {
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
frame.setLocation(x, y);
}
public static void barfSize(JPanel panel, String panelName) {
Dimension panelSize = panel.getSize();
System.out.println(String.format("%s size:(%d,%d);",panelName,panelSize.width,panelSize.height));
}
}
class MainPanel extends JPanel {
static final long serialVersionUID = 1;
public MainPanel() {
setBorder(BorderFactory.createLineBorder(Color.green));
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
PanelTest.boardPanel = new BoardPanel();
PanelTest.boardPanel.setAlignmentY(TOP_ALIGNMENT);
add(PanelTest.boardPanel);
PanelTest.sidePanel = new SidePanel();
PanelTest.sidePanel.setAlignmentY(TOP_ALIGNMENT);
add(PanelTest.sidePanel);
}
public void paintComponent(Graphics gooey) {
super.paintComponent(gooey);
PanelTest.barfSize(this, "Main Panel");
}
}
class BoardPanel extends JPanel {
static final long serialVersionUID = 1;
public BoardPanel() {
setBorder(BorderFactory.createLineBorder(Color.red));
Dimension mySize = new Dimension(400,200);
setMinimumSize(mySize);
setPreferredSize(mySize);
setMaximumSize(mySize);
JLabel lblText = new JLabel("Board Panel");
add(lblText);
}
public void paintComponent(Graphics gooey) {
super.paintComponent(gooey);
PanelTest.barfSize(this, "Board Panel");
}
}
class SidePanel extends JPanel implements ActionListener {
static final long serialVersionUID = 1;
public SidePanel() {
setBorder(BorderFactory.createLineBorder(Color.blue));
Dimension mySize = new Dimension(200,200);
setMinimumSize(mySize);
setPreferredSize(mySize);
setMaximumSize(mySize);
JLabel lblText = new JLabel("Side Panel");
add(lblText);
JButton btnFreeze = new JButton("Freeze");
btnFreeze.setActionCommand("Freeze");
btnFreeze.setToolTipText("Click me to freeze frame");
btnFreeze.setBorderPainted(true);
btnFreeze.setEnabled(true);
btnFreeze.addActionListener(this);
add(btnFreeze);
}
public void actionPerformed(ActionEvent action) {
String command = action.getActionCommand();
if ( command == "Freeze") {
freezeFrame();
System.out.println("Froze frame.");
}
Dimension panelSize = getSize();
System.out.println(String.format("Side Panel size:(%d,%d);",panelSize.width,panelSize.height));
}
public void paintComponent(Graphics gooey) {
super.paintComponent(gooey);
PanelTest.barfSize(this, "Side Panel");
}
public void freezeFrame() {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
Dimension parentSize = this.getParent().getSize();
topFrame.setMaximumSize(parentSize);
topFrame.setResizable(false);
}
}
Screen 1:
Application is disabled before resizing the frame
Screen Cover 2:
Disabled After Resizing Frame
Execution log
Create and show GUI
Main Panel size:(602,202);
Side Panel size:(200,200);
Board Panel size:(400,200);
Main Panel size:(602,202);
Side Panel size:(200,200);
Board Panel size:(400,200);
Froze frame.
Side Panel size:(200,200);
Main Panel size:(618,218);
Side Panel size:(200,200);
Board Panel size:(400,200);
Main Panel size:(618,218);
Side Panel size:(200,200);
Board Panel size:(400,200);