在Swing GUI中定位组件

Saa*_*ieh 4 java swing jtextfield jtextarea layout-manager

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

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

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

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

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

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

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

Eng*_*uad 9

现在我试图让两个文本字段彼此相邻,每个文本字段上面都有一个不同的标签,用于描述该文本字段的作用.为此,我将它们放在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);
Run Code Online (Sandbox Code Playgroud)

请注意,您可以通过设置空边框来操纵组件之间的间隙.此外,您可以使用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);
Run Code Online (Sandbox Code Playgroud)

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

我建议你使用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);
Run Code Online (Sandbox Code Playgroud)

第三个(文本字段):再次参考上面的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);
Run Code Online (Sandbox Code Playgroud)

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


Mad*_*mer 9

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

因为,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);

        }

    }

}
Run Code Online (Sandbox Code Playgroud)

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

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