在Swing GUI中定位组件

我有一些关于定位组件的问题以及关于文本字段和文本区域的一些问题(Java Swing)。 任何帮助是极大的赞赏。

现在我试图让两个文本字段彼此相邻,每个文本字段上面都有一个不同的标签,用于描述该文本字段的作用。 为此,我将它们放在GridLayout(2, 2)

  1. 这是最好的方法吗? 这是我知道直接在另一个组件上标签的唯一方法。 有没有更好的办法? 如果一个按钮上方只有一个标签怎么办? 通过GridLayout(2, 1)来定位它是否明智? 我视力受损,所以我不认为定位按钮只是它们的像素位置是一个选项,除非有一个简单的方法将组件放在相对像素数的另一个组件。

  2. 这引出了我的下一个问题。 拥有与上面相同的UI但是在其下居中的另一个组件(按钮)的最佳方法是什么。 本质上,UI应该由两个命名文本字段组成,其下有一个计算按钮。 我这样做的方法是将上面的组件放在一个面板中,然后将这个加上计算按钮添加到带有GridLayout(2, 1)的周围面板。 问题是按钮变得和它上面的面板一样大(我假设)。 如何调整此选项仍然可以在文本字段/标签面板下完美对齐按钮? 与文本区域上方的标签类似。 标签应该很小,但文本区域下面有更大的空间。

  3. (文本字段):再次参考上面的UI,如果用户在第一个文本字段中键入了许多字符,那么字母是否会超过右侧的文本字段? 如果是这样我怎么能阻止这个?

  4. 如果我将文本附加到文本区域并且它已经满了,它会自动允许用户滚动吗? 如果不是什么是使文本区域可滚动的简单方法?

  5. 现在我没有设置文本区域的大小。 它是否随着我添加文字而增长? 它是否具有字符数的默认大小?

有许多布局管理器可能能够为您提供所需的function。

  • MigLayout
  • JGoodies FormLayout
  • GridBagLayout的

因为, GridBagLayout将是我的选择(我有偏见,因为我过去12年一直在使用这个布局管理器;))

在此处输入图像描述

 public class TestLayout17 { public static void main(String[] args) { new TestLayout17(); } public TestLayout17() { 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 { public TestPane() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(2, 2, 2, 2); add(new JLabel("Label 1"), gbc); gbc.gridx++; add(new JLabel("Label 2"), gbc); gbc.gridx = 0; gbc.gridy++; gbc.fill = GridBagConstraints.HORIZONTAL; add(new JTextField(10), gbc); gbc.gridx++; add(new JTextField(10), gbc); gbc.gridx = 0; gbc.gridy++; gbc.fill = GridBagConstraints.NONE; gbc.gridwidth = 2; add(new JButton("Click"), gbc); } } } 

我也同意Eng.Fouad的建议,即从长远来看,使用复合容器可以让您的生活更轻松

您可能会发现在容器中放置组件值得阅读。

现在我试图让两个文本字段彼此相邻,每个文本字段上面都有一个不同的标签,用于描述该文本字段的作用。 为此,我将它们放在GridLayout(2,2)中。 这是最好的方法吗? 这是我知道直接在另一个组件上标签的唯一方法。 有没有更好的办法? 如果一个按钮上方只有一个标签怎么办? 通过GridLayout(2,1)来定位它是否明智?

我自己,我总是通过BorderLayout嵌套面板来做。 例如:

在此处输入图像描述

 JFrame frame = new JFrame("The Title"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panOuter = new JPanel(new BorderLayout()); JPanel panLeft = new JPanel(new BorderLayout()); panLeft.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panRight = new JPanel(new BorderLayout()); panRight.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panOuter.add(panLeft, BorderLayout.WEST); panOuter.add(panRight, BorderLayout.EAST); JLabel lblLeft = new JLabel("Label 1", JLabel.CENTER); JLabel lblRight = new JLabel("Label 2", JLabel.CENTER); JTextField txtLeft = new JTextField(10); JTextField txtLright = new JTextField(10); panLeft.add(lblLeft, BorderLayout.NORTH); panLeft.add(txtLeft, BorderLayout.CENTER); panRight.add(lblRight, BorderLayout.NORTH); panRight.add(txtLright, BorderLayout.CENTER); frame.setContentPane(panOuter); frame.pack(); frame.setVisible(true); 

请注意,您可以通过设置空边框来操纵组件之间的间隙。 此外,您可以使用BorderLayout.LINE_STARTBorderLayout.LINE_END而不是使用BorderLayout.WESTBorderLayout.EAST ,这将添加对RTL语言的支持(例如阿拉伯语)。


这引出了我的下一个问题。 拥有与上面相同的UI但是在其下居中的另一个组件(按钮)的最佳方法是什么。 本质上,UI应该由两个命名文本字段组成,其下有一个计算按钮。 我这样做的方法是将上面的组件放在一个面板中,然后将这个加上计算按钮添加到带有GridLayout(2,1)的周围面板。 问题是按钮变得和它上面的面板一样大(我假设)。 如何调整此项并仍然在文本字段/标签面板下完美对齐按钮?

我会像之前那样通过嵌套面板来实现,但是现在底部面板有一个FlowLayout布局管理器来获得一个好的按钮大小:

在此处输入图像描述

 JFrame frame = new JFrame("The Title"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panOuter = new JPanel(new BorderLayout()); JPanel panLeft = new JPanel(new BorderLayout()); panLeft.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panRight = new JPanel(new BorderLayout()); panRight.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panBottom = new JPanel(); // default is FlowLayout panBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panOuter.add(panLeft, BorderLayout.WEST); panOuter.add(panRight, BorderLayout.EAST); panOuter.add(panBottom, BorderLayout.SOUTH); JLabel lblLeft = new JLabel("Label 1", JLabel.CENTER); JLabel lblRight = new JLabel("Label 2", JLabel.CENTER); JTextField txtLeft = new JTextField(10); JTextField txtLright = new JTextField(10); JButton btnBottom = new JButton("Press it!"); panLeft.add(lblLeft, BorderLayout.NORTH); panLeft.add(txtLeft, BorderLayout.CENTER); panRight.add(lblRight, BorderLayout.NORTH); panRight.add(txtLright, BorderLayout.CENTER); panBottom.add(btnBottom); frame.setContentPane(panOuter); frame.pack(); frame.setVisible(true); 

与文本区域上方的标签类似。 标签应该很小,但文本区域下面有更大的空间。

我建议你使用TitledBorder

在此处输入图像描述

 JFrame frame = new JFrame("The Title"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panOuter = new JPanel(new BorderLayout()); JPanel panLeft = new JPanel(new BorderLayout()); panLeft.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panRight = new JPanel(new BorderLayout()); panRight.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panBottom = new JPanel(); // default is FlowLayout panBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panInput = new JPanel(new BorderLayout()); panInput.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panConsole = new JPanel(new BorderLayout()); Border outsideBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); Border insideBorder = BorderFactory.createTitledBorder("The Console"); Border theBorder = BorderFactory.createCompoundBorder(outsideBorder, insideBorder); panConsole.setBorder(theBorder); panInput.add(panLeft, BorderLayout.WEST); panInput.add(panRight, BorderLayout.EAST); panInput.add(panBottom, BorderLayout.SOUTH); panOuter.add(panInput, BorderLayout.NORTH); panOuter.add(panConsole, BorderLayout.CENTER); JLabel lblLeft = new JLabel("Label 1", JLabel.CENTER); JLabel lblRight = new JLabel("Label 2", JLabel.CENTER); JTextField txtLeft = new JTextField(10); JTextField txtLright = new JTextField(10); JButton btnBottom = new JButton("Press it!"); JTextArea txtConsole = new JTextArea(5, 10); panLeft.add(lblLeft, BorderLayout.NORTH); panLeft.add(txtLeft, BorderLayout.CENTER); panRight.add(lblRight, BorderLayout.NORTH); panRight.add(txtLright, BorderLayout.CENTER); panBottom.add(btnBottom); panConsole.add(txtConsole, BorderLayout.CENTER); frame.setContentPane(panOuter); frame.pack(); frame.setVisible(true); 

第三个(文本字段):再次参考上面的UI,如果用户在第一个文本字段中键入了许多字符,那么字母是否会超过右侧的文本字段? 如果是这样我怎么能阻止这个?

试试上面的代码,看看它的行为:)


第四:如果我将文本附加到文本区域并且它已经满了,它会自动允许用户滚动吗? 如果不是什么是使文本区域可滚动的简单方法?

你需要使用一个名为JScrollPane东西:

在此处输入图像描述

 JFrame frame = new JFrame("The Title"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panOuter = new JPanel(new BorderLayout()); JPanel panLeft = new JPanel(new BorderLayout()); panLeft.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panRight = new JPanel(new BorderLayout()); panRight.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panBottom = new JPanel(); // default is FlowLayout panBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panInput = new JPanel(new BorderLayout()); panInput.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel panConsole = new JPanel(new BorderLayout()); Border outsideBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); Border insideBorder = BorderFactory.createTitledBorder("The Console"); Border theBorder = BorderFactory.createCompoundBorder(outsideBorder, insideBorder); panConsole.setBorder(theBorder); panInput.add(panLeft, BorderLayout.WEST); panInput.add(panRight, BorderLayout.EAST); panInput.add(panBottom, BorderLayout.SOUTH); panOuter.add(panInput, BorderLayout.NORTH); panOuter.add(panConsole, BorderLayout.CENTER); JLabel lblLeft = new JLabel("Label 1", JLabel.CENTER); JLabel lblRight = new JLabel("Label 2", JLabel.CENTER); JTextField txtLeft = new JTextField(10); JTextField txtLright = new JTextField(10); JButton btnBottom = new JButton("Press it!"); JTextArea txtConsole = new JTextArea(5, 10); JScrollPane srcPane = new JScrollPane(txtConsole, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); panLeft.add(lblLeft, BorderLayout.NORTH); panLeft.add(txtLeft, BorderLayout.CENTER); panRight.add(lblRight, BorderLayout.NORTH); panRight.add(txtLright, BorderLayout.CENTER); panBottom.add(btnBottom); panConsole.add(srcPane, BorderLayout.CENTER); frame.setContentPane(panOuter); frame.pack(); frame.setVisible(true); 

我希望我回答你所有的问题:)