尝试学习如何做一些优雅且更高级的JFrame
布局。我正在尝试制作一些我认为相当简单的东西,但我遇到了一些困难。而不是乱搞几个小时(尽管我已经有)试图让布局工作,我想我会问我将要描述的布局的最佳约定是什么。
布局
基本上,我想要2列,但第一列要比第二列宽。在第一列中,将只有一个单元格,该单元格将具有JLabel
,其中附有图标,以单元格为中心。第二列将有4行,每行包含JComponent
(无关紧要)。另一个关键是JFrame
中的每个组件都保留其首选大小,并且不会伸展以适应其单元格或者您拥有的内容。
这是所需布局的图片:
到目前为止,我已经想过以不同的方式做这件事:
BorderLayout
,中间有JLabel
- 图标,其余为GridLayout
/ GridBagLayout
。GridBagLayout
4x4,其中JLabel
- 图标占据3x4区域,理论上占据了75%的空间。既没有给我我正在寻找的结果。思考/建议?非常感谢所有的帮助和建议。
答案 0 :(得分:2)
你的第一个建议是合理的。
标签可以垂直和水平居中。
对于GridLayout,技巧是将每个组件添加到使用具有默认网格包约束的GridBagLayout的JPanel。然后将面板添加到GridLayout。现在,如果框架调整大小,面板将增长,但面板上的组件不会增长,组件将在面板中居中。
您可以使用垂直BoxLayout并在每个组件之前/之后添加“胶水”,而不是将GridLayout与其他子面板一起使用。不是这种方法,您需要确保每个组件都使用居中对齐。此外,您可能需要将某些组件的最大大小设置为等于组件的首选大小,以便在空间可用时不会增大。
答案 1 :(得分:2)
为了我自己的理智,我通常会将布局的各个元素分开。这有时可以简化流程,因为您只需要关注重要的布局区域(对每个部分)。
以下示例仅使用一个布局来演示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);
}
}
}
这可以很容易地与两个JPanels
一起使用,一个用于图像,一个用于选项。这样就无需使用gridheight
...