Java布局格式(GridBagLayout)
尝试学习如何做一些优雅和更高级的Java布局格式(GridBagLayout),java,layout,awt,layout-manager,gridbaglayout,Java,Layout,Awt,Layout Manager,Gridbaglayout,尝试学习如何做一些优雅和更高级的JFrame布局。我正在尝试做一些我认为很简单的事情,但是我遇到了一些困难。与花几个小时(尽管我已经花了很多时间)试图让布局正常工作相反,我想我应该问一下,我将要描述的布局的最佳惯例是什么 布局 基本上,我想要两列,但是第一列要比第二列宽。在第一列中只有一个单元格,该单元格将有一个JLabel,并在单元格中居中附加一个图标。第二列将有4行,每行中都有一个JComponent(不管是什么)。另一个关键点是,JFrame中的每个组件都保留其首选大小,并且不会拉伸以适合
JFrame
布局。我正在尝试做一些我认为很简单的事情,但是我遇到了一些困难。与花几个小时(尽管我已经花了很多时间)试图让布局正常工作相反,我想我应该问一下,我将要描述的布局的最佳惯例是什么
布局基本上,我想要两列,但是第一列要比第二列宽。在第一列中只有一个单元格,该单元格将有一个
JLabel
,并在单元格中居中附加一个图标。第二列将有4行,每行中都有一个JComponent
(不管是什么)。另一个关键点是,JFrame
中的每个组件都保留其首选大小,并且不会拉伸以适合其单元格或您所拥有的内容
以下是所需布局的图片:
到目前为止,我已经想到了几种不同的方法:
BorderLayout
,中间有JLabel
-图标,其余部分由gridbagloayout
/gridbagloayout
控制GridBagLayout
4x4,其中JLabel
-图标占据了3x4区域,理论上占75%的空间也不要告诉我我想要的结果。想法/建议?非常感谢您的帮助和建议。您的第一个建议是合理的 标签可以垂直和水平居中 对于GridLayout,诀窍是将每个组件添加到使用带有默认gridbag约束的GridBagLayout的JPanel中。然后将面板添加到GridLayout。现在,如果框架确实调整大小,面板将增长,但面板上的组件不会增长,并且组件将在面板中居中
除了将GridLayout与其他子面板一起使用外,还可以使用垂直BoxLayout并在每个组件之前/之后添加“胶水”。并不是说使用这种方法时,您需要确保每个组件都使用居中的路线。此外,您可能需要将某些组件的最大大小设置为组件的首选大小,以便在空间可用时不会增长。您的第一个建议是合理的 标签可以垂直和水平居中 对于GridLayout,诀窍是将每个组件添加到使用带有默认gridbag约束的GridBagLayout的JPanel中。然后将面板添加到GridLayout。现在,如果框架确实调整大小,面板将增长,但面板上的组件不会增长,并且组件将在面板中居中
除了将GridLayout与其他子面板一起使用外,还可以使用垂直BoxLayout并在每个组件之前/之后添加“胶水”。并不是说使用这种方法时,您需要确保每个组件都使用居中的路线。此外,您可能需要将某些组件的最大大小设置为组件的首选大小,以便在空间可用时不会增长。为了我自己的理智,我通常会分离布局的各个元素。这有时可以简化流程,因为您只需要关注布局中(对每个部分)重要的区域 下面的示例使用单个布局来演示
GridBagLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class AdvancedLayout {
public static void main(String[] args) {
new AdvancedLayout();
}
public AdvancedLayout() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel image;
private JButton button;
private JLabel label;
private JComboBox comboBox;
private JButton otherButton;
public TestPane() {
setLayout(new GridBagLayout());
image = new JLabel();
button = new JButton("A button");
label = new JLabel("A label");
comboBox = new JComboBox();
otherButton = new JButton("Other");
try {
image.setIcon(new ImageIcon(ImageIO.read(new File("/path/to/a/image"))));
} catch (IOException ex) {
ex.printStackTrace();
}
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.6666666666666667;
gbc.weighty = 1f;
gbc.gridheight = GridBagConstraints.REMAINDER;
add(image, gbc);
gbc.gridheight = 1;
gbc.gridx++;
gbc.weightx = 0.3333333333333333f;
gbc.weighty = 0.25f;
add(button, gbc);
gbc.gridy++;
add(label, gbc);
gbc.gridy++;
add(comboBox, gbc);
gbc.gridy++;
add(otherButton, gbc);
}
}
}
这可以很容易地与两个
jpanel一起使用,一个用于图像,一个用于选项。这样就不需要使用gridheight
..为了我自己的理智,我通常会分离布局的各个元素。这有时可以简化流程,因为您只需要关注布局中(对每个部分)重要的区域
下面的示例使用单个布局来演示GridBagLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class AdvancedLayout {
public static void main(String[] args) {
new AdvancedLayout();
}
public AdvancedLayout() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel image;
private JButton button;
private JLabel label;
private JComboBox comboBox;
private JButton otherButton;
public TestPane() {
setLayout(new GridBagLayout());
image = new JLabel();
button = new JButton("A button");
label = new JLabel("A label");
comboBox = new JComboBox();
otherButton = new JButton("Other");
try {
image.setIcon(new ImageIcon(ImageIO.read(new File("/path/to/a/image"))));
} catch (IOException ex) {
ex.printStackTrace();
}
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.6666666666666667;
gbc.weighty = 1f;
gbc.gridheight = GridBagConstraints.REMAINDER;
add(image, gbc);
gbc.gridheight = 1;
gbc.gridx++;
gbc.weightx = 0.3333333333333333f;
gbc.weighty = 0.25f;
add(button, gbc);
gbc.gridy++;
add(label, gbc);
gbc.gridy++;
add(comboBox, gbc);
gbc.gridy++;
add(otherButton, gbc);
}
}
}
这可以很容易地与两个jpanel一起使用,一个用于图像,一个用于选项。这样就不需要使用gridheight
…为什么第一个解决方案不起作用?对我来说似乎不错。如果您希望它保持其大小,为什么不使用JFrame.setresizeable(false)
?组件必须保持其大小。例如,使用GridLayout
(据我所知,如果我错了,请纠正我,这就是我在这里的原因)一个JButton
将占用其单元格的整个空间。不管我把它设置成什么尺寸。这不是我想要的。为什么你的第一个解决方案不起作用?对我来说似乎不错。如果您希望它保持其大小,为什么不使用JFrame.setresizeable(false)
?组件必须保持其大小。例如,使用GridLayout
(据我所知,如果我错了,请纠正我,这就是我在这里的原因)一个JButton
将占用其单元格的整个空间。不管我把它设置成什么尺寸。这不是我想要的。它有点像,但它似乎太复杂了——多种布局等等。这取决于你的喜好。我更喜欢具有最小约束的多个布局,因为我觉得它们更容易理解。其他人更喜欢单一布局,在使用每个组件时使用多个约束,如GridBagLayout、GroupLayout或MigLayout。我不喜欢需要一个教程来理解所有的限制。我想这是真的。为什么要让它变得比必要的更复杂呢。我想我只是喜欢均匀性。我会检查胶水。谢谢。有点像,但似乎太复杂了——多种布局等等。这取决于你的喜好。我更喜欢具有最小约束的多个布局,因为我觉得它们更容易理解。其他人更喜欢单一布局,在使用每个组件时使用多个约束,如GridBagLayout、GroupLayout或MigLayout。我不喜欢需要一个教程来理解所有的约束条件