网格袋布局 25% 50% 25%
GridBagLayout 25% 50% 25%
这是防止 GridBagLayout 单元格相对于其内容调整大小的正确方法吗?
gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
SSCCE
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.AbstractListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
public class GridBagLayoutTemplate extends JFrame {
private JPanel contentPane;
public GridBagLayoutTemplate() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel panel = new JPanel();
contentPane.add(panel);
GridBagLayout gbl_panel = new GridBagLayout();
gbl_panel.rowHeights = new int[] {1};
gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
gbl_panel.columnWeights = new double[]{1.0, 4.0, 1.0};
gbl_panel.rowWeights = new double[]{1.0};
panel.setLayout(gbl_panel);
JScrollPane scrollPane = new JScrollPane();
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.insets = new Insets(0, 0, 0, 5);
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.gridx = 0;
gbc_scrollPane.gridy = 0;
panel.add(scrollPane, gbc_scrollPane);
JList list = new JList();
scrollPane.setViewportView(list);
list.setModel(new AbstractListModel() {
String[] values = new String[] {"qwe"};
public int getSize() {
return values.length;
}
public Object getElementAt(int index) {
return values[index];
}
});
JScrollPane scrollPane_1 = new JScrollPane();
GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
gbc_scrollPane_1.insets = new Insets(0, 0, 0, 5);
gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
gbc_scrollPane_1.gridx = 1;
gbc_scrollPane_1.gridy = 0;
panel.add(scrollPane_1, gbc_scrollPane_1);
JList list_1 = new JList();
scrollPane_1.setViewportView(list_1);
list_1.setModel(new AbstractListModel() {
String[] values = new String[] {"qwe"};
public int getSize() {
return values.length;
}
public Object getElementAt(int index) {
return values[index];
}
});
JScrollPane scrollPane_2 = new JScrollPane();
GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints();
gbc_scrollPane_2.fill = GridBagConstraints.BOTH;
gbc_scrollPane_2.gridx = 2;
gbc_scrollPane_2.gridy = 0;
panel.add(scrollPane_2, gbc_scrollPane_2);
JList list_3 = new JList();
scrollPane_2.setViewportView(list_3);
list_3.setModel(new AbstractListModel() {
String[] values = new String[] {"qweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqwe"};
public int getSize() {
return values.length;
}
public Object getElementAt(int index) {
return values[index];
}
});
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GridBagLayoutTemplate frame = new GridBagLayoutTemplate();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
有意思。我以前从未见过这样的方法。
通常使用 GridBagLayout 这样:
- 每个组件根据其首选大小
分配space
- 如果额外 space 可用,则根据分配给每个组件的 weightx(权重)值将 space 分配给每个组件。
因此只有额外的space分配在25% 50% 25%的比例。
您的方法似乎忽略了组件的首选大小,并以 25% 50% 25% 的比例分配 space。
但是,您首先需要进行以下更改以获得正确的比率:
//gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
//gbl_panel.columnWeights = new double[]{1.0, 4.0, 1.0};
gbl_panel.columnWidths = new int[] {1000, 2000, 1000};
gbl_panel.columnWeights = new double[]{1.0, 2.0, 1.0};
下面是我用来测试将 space 分配给 400 像素宽的面板上的组件的简化代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagLayoutRelative extends JPanel
{
public GridBagLayoutRelative()
{
setPreferredSize( new Dimension(400, 300) );
// Components will be allocated relative widths of 25%, 50%, 25%
// (preferred width will be ignored)
GridBagLayout gbl = new GridBagLayout();
//gbl.columnWidths = new int[] {25, 50, 25}; // doesn't work
gbl.columnWidths = new int[] {250, 500, 250}; // larger value in same ratio
gbl.columnWeights = new double[] {25.0, 50.0, 25.0};
setLayout(gbl);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1.0;
gbc.gridy = 0;
JPanel red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(30, 200) );
gbc.gridx = 0;
add(red, gbc);
JPanel green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(40, 200) );
gbc.gridx = 1;
add(green, gbc);
JPanel blue = new JPanel();
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(50, 200) );
gbc.gridx = 2;
add(blue, gbc);
addComponentListener( new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
System.out.println( e.getComponent().getSize() );
for (Component c: getComponents())
System.out.println( "\t" + c.getSize() );
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("GridBagLayout Relative");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GridBagLayoutRelative());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
结果是:
java.awt.Dimension[width=100,height=300]
java.awt.Dimension[width=200,height=300]
java.awt.Dimension[width=100,height=300]
所以我会说这种方法有效。
注意:如果您有兴趣,过去我建议您可以使用专为此类布局设计且更易于使用的Relative Layout。
使用 RelativeLayout
以上行为将通过使用复制:
RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS);
rl.setFill(true);
setLayout( rl );
JPanel red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(30, 200) );
add(red, new Float(25));
JPanel green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(40, 200) );
add(green, new Float(50));
JPanel blue = new JPanel();
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(50, 200) );
add(blue, new Float(25));
这是防止 GridBagLayout 单元格相对于其内容调整大小的正确方法吗?
gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
SSCCE
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.AbstractListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
public class GridBagLayoutTemplate extends JFrame {
private JPanel contentPane;
public GridBagLayoutTemplate() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel panel = new JPanel();
contentPane.add(panel);
GridBagLayout gbl_panel = new GridBagLayout();
gbl_panel.rowHeights = new int[] {1};
gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
gbl_panel.columnWeights = new double[]{1.0, 4.0, 1.0};
gbl_panel.rowWeights = new double[]{1.0};
panel.setLayout(gbl_panel);
JScrollPane scrollPane = new JScrollPane();
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.insets = new Insets(0, 0, 0, 5);
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.gridx = 0;
gbc_scrollPane.gridy = 0;
panel.add(scrollPane, gbc_scrollPane);
JList list = new JList();
scrollPane.setViewportView(list);
list.setModel(new AbstractListModel() {
String[] values = new String[] {"qwe"};
public int getSize() {
return values.length;
}
public Object getElementAt(int index) {
return values[index];
}
});
JScrollPane scrollPane_1 = new JScrollPane();
GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
gbc_scrollPane_1.insets = new Insets(0, 0, 0, 5);
gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
gbc_scrollPane_1.gridx = 1;
gbc_scrollPane_1.gridy = 0;
panel.add(scrollPane_1, gbc_scrollPane_1);
JList list_1 = new JList();
scrollPane_1.setViewportView(list_1);
list_1.setModel(new AbstractListModel() {
String[] values = new String[] {"qwe"};
public int getSize() {
return values.length;
}
public Object getElementAt(int index) {
return values[index];
}
});
JScrollPane scrollPane_2 = new JScrollPane();
GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints();
gbc_scrollPane_2.fill = GridBagConstraints.BOTH;
gbc_scrollPane_2.gridx = 2;
gbc_scrollPane_2.gridy = 0;
panel.add(scrollPane_2, gbc_scrollPane_2);
JList list_3 = new JList();
scrollPane_2.setViewportView(list_3);
list_3.setModel(new AbstractListModel() {
String[] values = new String[] {"qweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqwe"};
public int getSize() {
return values.length;
}
public Object getElementAt(int index) {
return values[index];
}
});
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GridBagLayoutTemplate frame = new GridBagLayoutTemplate();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
有意思。我以前从未见过这样的方法。
通常使用 GridBagLayout 这样:
- 每个组件根据其首选大小 分配space
- 如果额外 space 可用,则根据分配给每个组件的 weightx(权重)值将 space 分配给每个组件。
因此只有额外的space分配在25% 50% 25%的比例。
您的方法似乎忽略了组件的首选大小,并以 25% 50% 25% 的比例分配 space。
但是,您首先需要进行以下更改以获得正确的比率:
//gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
//gbl_panel.columnWeights = new double[]{1.0, 4.0, 1.0};
gbl_panel.columnWidths = new int[] {1000, 2000, 1000};
gbl_panel.columnWeights = new double[]{1.0, 2.0, 1.0};
下面是我用来测试将 space 分配给 400 像素宽的面板上的组件的简化代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagLayoutRelative extends JPanel
{
public GridBagLayoutRelative()
{
setPreferredSize( new Dimension(400, 300) );
// Components will be allocated relative widths of 25%, 50%, 25%
// (preferred width will be ignored)
GridBagLayout gbl = new GridBagLayout();
//gbl.columnWidths = new int[] {25, 50, 25}; // doesn't work
gbl.columnWidths = new int[] {250, 500, 250}; // larger value in same ratio
gbl.columnWeights = new double[] {25.0, 50.0, 25.0};
setLayout(gbl);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1.0;
gbc.gridy = 0;
JPanel red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(30, 200) );
gbc.gridx = 0;
add(red, gbc);
JPanel green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(40, 200) );
gbc.gridx = 1;
add(green, gbc);
JPanel blue = new JPanel();
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(50, 200) );
gbc.gridx = 2;
add(blue, gbc);
addComponentListener( new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
System.out.println( e.getComponent().getSize() );
for (Component c: getComponents())
System.out.println( "\t" + c.getSize() );
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("GridBagLayout Relative");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GridBagLayoutRelative());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
结果是:
java.awt.Dimension[width=100,height=300]
java.awt.Dimension[width=200,height=300]
java.awt.Dimension[width=100,height=300]
所以我会说这种方法有效。
注意:如果您有兴趣,过去我建议您可以使用专为此类布局设计且更易于使用的Relative Layout。
使用 RelativeLayout
以上行为将通过使用复制:
RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS);
rl.setFill(true);
setLayout( rl );
JPanel red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(30, 200) );
add(red, new Float(25));
JPanel green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(40, 200) );
add(green, new Float(50));
JPanel blue = new JPanel();
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(50, 200) );
add(blue, new Float(25));