呼如林
简短的回答是,是的,长的回答有些复杂。首先,我会用GridBagLayout我的布局管理器的主要选择,但我可能会考虑GridLayout,并BorderLayout作为额外的选项。关键是,您希望将布局分解为可管理的功能块,并找出解决特定问题的最佳解决方案。然后,您想将这些单独的元素拼凑成一张大图,使用最适合解决每个部分呈现的问题的布局管理器。我只想说你的基本布局JTable让我尖叫。但是,如果您对非矩形窗口感兴趣,那么它会变得有些困难,主要是因为 Java 不支持装饰透明窗口(即具有本机框架的窗口)如果没有,我也会对解释感兴趣好的,这有点复杂,但是,它基本上归结为屏幕上绘制的所有内容都包含在一个矩形边界框中的事实。这个框填充了背景颜色,内容被绘制在它上面。这样做是为了提高效率,因为不需要绘制此边界框后面的所有内容。随着硬件变得更快,渲染管道更多地利用了高端库,如 DirectX 和 OpenGL,开始处理系统更广泛范围内的不透明度成为可能,如单个窗口。因此,即使您看到非常酷、弯曲、时髦的 UI,它也包含在一个透明的矩形边界框内:/这是非常基本的图形概念。请记住,计算矩形边界框(交叉点/命中检测等)比计算非矩形边界框要容易和快捷得多每像素 alpha 实际上是相当密集的执行,这是它最初不是在操作系统/日常级别使用的另一个原因,系统资源可以更好地用于其他事情可运行示例import java.awt.Color;import java.awt.EventQueue;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import javax.swing.JButton;import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;import javax.swing.border.LineBorder;public class Test { public static void main(String[] args) { new Test(); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setUndecorated(true); frame.setBackground(new Color(0, 0, 0, 0)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new MainPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class MainPane extends JPanel { public MainPane() { setOpaque(false); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.5; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.NORTH; add(new FieldsPane(), gbc); gbc.gridx++; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; add(new JScrollPane(new JTextArea(20, 20)), gbc); } } public class FieldsPane extends JPanel { private JPanel fields; private JLabel filler; public FieldsPane() { setBorder(new LineBorder(Color.GRAY)); fields = new JPanel(new GridBagLayout()); filler = new JLabel(); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weighty = 1; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; fields.add(filler, gbc); addFields(new JLabel("Col1"), new JLabel("Col2"), new JLabel("Col3 ")); addFields(new JTextField(10), new JTextField(10), new JTextField(10)); setLayout(new GridBagLayout()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 1; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; add(fields, gbc); JPanel buttons = new JPanel(new GridBagLayout()); JButton add = new JButton("Add"); JButton remove = new JButton("Remove"); buttons.add(add); buttons.add(remove); gbc.gridy++; gbc.weightx = 1; gbc.weighty = 0; gbc.fill = GridBagConstraints.HORIZONTAL; add(buttons, gbc); } protected void addFields(JComponent col1, JComponent col2, JComponent col3) { GridBagLayout layout = (GridBagLayout) fields.getLayout(); GridBagConstraints gbc = layout.getConstraints(filler); fields.add(makeRow(col1, col2, col3), gbc); gbc.gridy++; layout.setConstraints(filler, gbc); } protected JPanel makeRow(JComponent col1, JComponent col2, JComponent col3) { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridy = 0; gbc.weightx = 0.33; gbc.fill = GridBagConstraints.HORIZONTAL; panel.add(col1, gbc); panel.add(col2, gbc); panel.add(col3, gbc); return panel; } }}