调整多个 JPanel 的大小以适应 window
Resizing of multiple JPanels to fit window
我是 Java Swing 工具包的新手,并且创建了一系列 JPanel
,其中 JLabel
组件对应于每个面板的索引和值。但是,当 window 太小而无法一次调整所有面板的大小时,我似乎无法正确调整面板的大小。导致所有面板右侧出现额外的红色边距(参见。Window)。
有没有办法让子 Panels/Spacer 面板以不允许额外边距的方式调整大小?或者设置更好的摆动布局来处理这种大小调整?
代码演示:
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
public class Frame extends JFrame {
private int numBox = 20;
public class SubPanel extends JPanel {
public SubPanel(int i) {
setMinimumSize(new Dimension(20, 20));
setMaximumSize(new Dimension(1000, i*30));
setBackground(Color.BLACK);
setLayout(new BorderLayout());
setAlignmentY(Component.BOTTOM_ALIGNMENT);
JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
labelValue.setForeground(Color.WHITE);
add(labelValue, BorderLayout.NORTH);
JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
labelIndex.setForeground(Color.WHITE);
add(labelIndex, BorderLayout.SOUTH);
}
}
public class SpacerPanel extends JPanel {
public SpacerPanel() {
setBackground(Color.WHITE);
setMaximumSize(new Dimension(3, 10000));
setMinimumSize(new Dimension(3, 0));
}
}
public Frame(String title) {
super(title);
JPanel mainPanel = new JPanel();
mainPanel.setBackground(Color.RED);
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
for (int i = 1; i < numBox + 1; i++) {
mainPanel.add(new SpacerPanel());
mainPanel.add(new SubPanel(i));
}
mainPanel.add(new SpacerPanel());
add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame("Frame").setSize(1200, 700);
}
}
如果您有 40 个组件并且将框架的大小调整了几个像素,则 BoxLayout 在将这些像素分配给每个组件时会遇到问题。
相反,您可以使用 Relative Layout,它允许您指定应如何分配这些像素。
RelativeLayout
还允许您指定每个组件之间的间隙,因此您无需添加 SpacerPanel。
但是,您需要修改“子面板”的逻辑。标签的高度需要固定,以便将它们涂成黑色。所以我创建了一个“labelPanel”来保存标签。
使用 RelativeLayout
的重构代码将是:
import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
public class Frame extends JFrame {
private int numBox = 20;
public class SubPanel extends JPanel {
public SubPanel(int i) {
// setMinimumSize(new Dimension(20, 20));
// setMaximumSize(new Dimension(1000, i*30));
// setPreferredSize(new Dimension(20, i*30));
setBackground(Color.RED);
setLayout(new BorderLayout());
// setAlignmentY(Component.BOTTOM_ALIGNMENT);
JPanel labelPanel = new JPanel( new BorderLayout() );
labelPanel.setBackground( Color.BLACK );
labelPanel.setPreferredSize(new Dimension(20, i*30));
add(labelPanel, BorderLayout.PAGE_END);
JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
labelValue.setForeground(Color.WHITE);
labelPanel.add(labelValue, BorderLayout.NORTH);
JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
labelIndex.setForeground(Color.WHITE);
labelPanel.add(labelIndex, BorderLayout.SOUTH);
}
}
public class SpacerPanel extends JPanel {
public SpacerPanel() {
setBackground(Color.WHITE);
setMaximumSize(new Dimension(3, 10000));
setMinimumSize(new Dimension(3, 0));
}
}
public Frame(String title) {
super(title);
JPanel mainPanel = new JPanel();
// mainPanel.setBackground(Color.RED);
mainPanel.setBackground(Color.WHITE);
// mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 5);
rl.setFill( true );
rl.setRoundingPolicy(RelativeLayout.EQUAL);
rl.setAlignment(RelativeLayout.TRAILING);
mainPanel.setLayout( rl );
Float constraint = new Float(1);
for (int i = 1; i < numBox + 1; i++) {
// mainPanel.add(new SpacerPanel());
// mainPanel.add(new SubPanel(i));
mainPanel.add(new SubPanel(i), constraint);
}
// mainPanel.add(new SpacerPanel());
add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame("Frame").setSize(1200, 700);
}
}
或者这个方法更接近你原来的贴子。仍然使用间隔条,黑色列的高度会随着框架高度的降低而缩小:
import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
public class Frame2 extends JFrame {
private int numBox = 20;
public class SubPanel extends JPanel {
public SubPanel(int i) {
// setMinimumSize(new Dimension(20, 20));
// setMaximumSize(new Dimension(1000, i*30));
// setBackground(Color.BLACK);
setBackground(Color.RED);
// setLayout(new BorderLayout());
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(Box.createVerticalGlue());
// setAlignmentY(Component.BOTTOM_ALIGNMENT);
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.Y_AXIS));
labelPanel.setBackground( Color.BLACK );
labelPanel.setPreferredSize(new Dimension(50, i*30));
labelPanel.setMaximumSize(new Dimension(1000, labelPanel.getPreferredSize().height));
add(labelPanel, BorderLayout.CENTER);
JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
labelValue.setForeground(Color.WHITE);
labelValue.setAlignmentX(JLabel.CENTER_ALIGNMENT);
// add(labelValue, BorderLayout.NORTH);
labelPanel.add(labelValue);
labelPanel.add(Box.createVerticalGlue());
JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
labelIndex.setForeground(Color.WHITE);
labelIndex.setAlignmentX(JLabel.CENTER_ALIGNMENT);
// add(labelIndex, BorderLayout.SOUTH);
labelPanel.add(labelIndex);
}
}
public class SpacerPanel extends JPanel {
public SpacerPanel() {
setBackground(Color.WHITE);
setMaximumSize(new Dimension(3, 10000));
setMinimumSize(new Dimension(3, 0));
}
}
public Frame2(String title) {
super(title);
JPanel mainPanel = new JPanel();
mainPanel.setBackground(Color.RED);
// mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 0);
rl.setFill( true );
rl.setRoundingPolicy(RelativeLayout.EQUAL);
rl.setAlignment(RelativeLayout.TRAILING);
mainPanel.setLayout( rl );
Float constraint = new Float(1);
for (int i = 1; i < numBox + 1; i++) {
mainPanel.add(new SpacerPanel());
// mainPanel.add(new SubPanel(i));
mainPanel.add(new SubPanel(i), constraint);
}
mainPanel.add(new SpacerPanel());
add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame2("Frame").setSize(1200, 700);
}
}
我是 Java Swing 工具包的新手,并且创建了一系列 JPanel
,其中 JLabel
组件对应于每个面板的索引和值。但是,当 window 太小而无法一次调整所有面板的大小时,我似乎无法正确调整面板的大小。导致所有面板右侧出现额外的红色边距(参见。Window)。
有没有办法让子 Panels/Spacer 面板以不允许额外边距的方式调整大小?或者设置更好的摆动布局来处理这种大小调整?
代码演示:
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
public class Frame extends JFrame {
private int numBox = 20;
public class SubPanel extends JPanel {
public SubPanel(int i) {
setMinimumSize(new Dimension(20, 20));
setMaximumSize(new Dimension(1000, i*30));
setBackground(Color.BLACK);
setLayout(new BorderLayout());
setAlignmentY(Component.BOTTOM_ALIGNMENT);
JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
labelValue.setForeground(Color.WHITE);
add(labelValue, BorderLayout.NORTH);
JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
labelIndex.setForeground(Color.WHITE);
add(labelIndex, BorderLayout.SOUTH);
}
}
public class SpacerPanel extends JPanel {
public SpacerPanel() {
setBackground(Color.WHITE);
setMaximumSize(new Dimension(3, 10000));
setMinimumSize(new Dimension(3, 0));
}
}
public Frame(String title) {
super(title);
JPanel mainPanel = new JPanel();
mainPanel.setBackground(Color.RED);
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
for (int i = 1; i < numBox + 1; i++) {
mainPanel.add(new SpacerPanel());
mainPanel.add(new SubPanel(i));
}
mainPanel.add(new SpacerPanel());
add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame("Frame").setSize(1200, 700);
}
}
如果您有 40 个组件并且将框架的大小调整了几个像素,则 BoxLayout 在将这些像素分配给每个组件时会遇到问题。
相反,您可以使用 Relative Layout,它允许您指定应如何分配这些像素。
RelativeLayout
还允许您指定每个组件之间的间隙,因此您无需添加 SpacerPanel。
但是,您需要修改“子面板”的逻辑。标签的高度需要固定,以便将它们涂成黑色。所以我创建了一个“labelPanel”来保存标签。
使用 RelativeLayout
的重构代码将是:
import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
public class Frame extends JFrame {
private int numBox = 20;
public class SubPanel extends JPanel {
public SubPanel(int i) {
// setMinimumSize(new Dimension(20, 20));
// setMaximumSize(new Dimension(1000, i*30));
// setPreferredSize(new Dimension(20, i*30));
setBackground(Color.RED);
setLayout(new BorderLayout());
// setAlignmentY(Component.BOTTOM_ALIGNMENT);
JPanel labelPanel = new JPanel( new BorderLayout() );
labelPanel.setBackground( Color.BLACK );
labelPanel.setPreferredSize(new Dimension(20, i*30));
add(labelPanel, BorderLayout.PAGE_END);
JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
labelValue.setForeground(Color.WHITE);
labelPanel.add(labelValue, BorderLayout.NORTH);
JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
labelIndex.setForeground(Color.WHITE);
labelPanel.add(labelIndex, BorderLayout.SOUTH);
}
}
public class SpacerPanel extends JPanel {
public SpacerPanel() {
setBackground(Color.WHITE);
setMaximumSize(new Dimension(3, 10000));
setMinimumSize(new Dimension(3, 0));
}
}
public Frame(String title) {
super(title);
JPanel mainPanel = new JPanel();
// mainPanel.setBackground(Color.RED);
mainPanel.setBackground(Color.WHITE);
// mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 5);
rl.setFill( true );
rl.setRoundingPolicy(RelativeLayout.EQUAL);
rl.setAlignment(RelativeLayout.TRAILING);
mainPanel.setLayout( rl );
Float constraint = new Float(1);
for (int i = 1; i < numBox + 1; i++) {
// mainPanel.add(new SpacerPanel());
// mainPanel.add(new SubPanel(i));
mainPanel.add(new SubPanel(i), constraint);
}
// mainPanel.add(new SpacerPanel());
add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame("Frame").setSize(1200, 700);
}
}
或者这个方法更接近你原来的贴子。仍然使用间隔条,黑色列的高度会随着框架高度的降低而缩小:
import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
public class Frame2 extends JFrame {
private int numBox = 20;
public class SubPanel extends JPanel {
public SubPanel(int i) {
// setMinimumSize(new Dimension(20, 20));
// setMaximumSize(new Dimension(1000, i*30));
// setBackground(Color.BLACK);
setBackground(Color.RED);
// setLayout(new BorderLayout());
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(Box.createVerticalGlue());
// setAlignmentY(Component.BOTTOM_ALIGNMENT);
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.Y_AXIS));
labelPanel.setBackground( Color.BLACK );
labelPanel.setPreferredSize(new Dimension(50, i*30));
labelPanel.setMaximumSize(new Dimension(1000, labelPanel.getPreferredSize().height));
add(labelPanel, BorderLayout.CENTER);
JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
labelValue.setForeground(Color.WHITE);
labelValue.setAlignmentX(JLabel.CENTER_ALIGNMENT);
// add(labelValue, BorderLayout.NORTH);
labelPanel.add(labelValue);
labelPanel.add(Box.createVerticalGlue());
JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
labelIndex.setForeground(Color.WHITE);
labelIndex.setAlignmentX(JLabel.CENTER_ALIGNMENT);
// add(labelIndex, BorderLayout.SOUTH);
labelPanel.add(labelIndex);
}
}
public class SpacerPanel extends JPanel {
public SpacerPanel() {
setBackground(Color.WHITE);
setMaximumSize(new Dimension(3, 10000));
setMinimumSize(new Dimension(3, 0));
}
}
public Frame2(String title) {
super(title);
JPanel mainPanel = new JPanel();
mainPanel.setBackground(Color.RED);
// mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 0);
rl.setFill( true );
rl.setRoundingPolicy(RelativeLayout.EQUAL);
rl.setAlignment(RelativeLayout.TRAILING);
mainPanel.setLayout( rl );
Float constraint = new Float(1);
for (int i = 1; i < numBox + 1; i++) {
mainPanel.add(new SpacerPanel());
// mainPanel.add(new SubPanel(i));
mainPanel.add(new SubPanel(i), constraint);
}
mainPanel.add(new SpacerPanel());
add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame2("Frame").setSize(1200, 700);
}
}