【问题标题】:Java Swing UI LayoutJava Swing UI 布局
【发布时间】:2014-12-20 08:32:54
【问题描述】:

我正在 Swing 中创建一个基本的用户界面,希望能得到一些帮助。下面是我想要实现的截图:

我目前的代码如下:

package testui;

import java.awt.Container;
import javax.swing.*;

public class TestUI{

    private JTextField outputArea = new JTextField();
    private JTextField errorReportArea = new JTextField();
    
    private JPanel inputPanel = new JPanel();
    
    private JLabel nameLabel = new JLabel("Item Name");
    private JLabel numberLabel = new JLabel("Number of units (or Volume in L)");
    private JLabel priceLabel = new JLabel("Price per unit (Or L) in pence");
    
    private JTextField nameField = new JTextField(10);
    private JTextField numberField = new JTextField(10);
    private JTextField priceField = new JTextField(10);
    
    private JButton addVolumeButton = new JButton("Add by Volume");
    private JButton addNumberButton = new JButton("Add by number of units");         
    
    public TestUI() {
        JFrame frame = new JFrame("Fuel Station");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        outputArea.setEditable(false);
        errorReportArea.setEditable(false);
        
        inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS));
        inputPanel.add(nameLabel);
        inputPanel.add(nameField);
        inputPanel.add(numberLabel);
        inputPanel.add(numberField);
        inputPanel.add(priceLabel);
        inputPanel.add(priceField);
        inputPanel.add(addVolumeButton);
        inputPanel.add(addNumberButton);
        
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
        contentPane.add(outputArea);
        contentPane.add(errorReportArea);
        contentPane.add(inputPanel);
        
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        TestUI test1 = new TestUI();
    }
    
}

看起来像这样:

所以我想做的是为顶部的两个 JTextField 设置一个特定的大小,因为顶部的将包含多行文本,而下面的将只包含一行文本。我不确定如何在不使用 setSize 的情况下执行此操作,因为有人告诉我使用它是不好的编码习惯。

我还想在底部 JPanel 的 JLabels、JTextFields 和 JButtons 之间添加一些填充。

如果有人可以就调整这些组件的大小给我一些建议,我将不胜感激

【问题讨论】:

    标签: java swing layout-manager


    【解决方案1】:
    • 由于您希望您的文本字段是多行的,请使用JTextAreas。 JTextField 仅是单行的。
    • 您的组件彼此相邻,这与您的预期结果不同。在您致电frame.pack() 之前,可能有一些方法可以为您的组件提供一些喘息的空间
    • 寻找任何可以使组件填满它给定的空间总量的方法;尤其是当您希望某物填满一大块空间时。
    • 您可以为 JTextFields/JTextAreas 设置列数,而不是使用 setSize()。只是说说而已。
    • 查看所有 Java's Layout Managers 将帮助您了解每个布局管理器的功能和用例

    【讨论】:

    • +1 表示文本区域。但是请取出“remove the frame.pack()”。框架应该被打包。使用 BorderLayout 以及文本区域的行/列提示应该为 OP 提供他们想要的内容
    • *已修复。我认为在大多数情况下,您应该使用frame.pack(),这样您就没有空荡荡的房间了。
    • 感谢您的建议,我已将第一个文本字段更改为文本区域,并使用 outputArea.setRows(30) 设置其大小。在查看了 Layout Managers 之后,我还将底部面板的 boxlayout 更改为 FlowLayout,效果很好,并且默认情况下还包括组件上的 5px 填充
    【解决方案2】:

    有一些布局管理器足够灵活,可以执行此操作,例如 Mig、Gridbag 和 SpringLayout。

    在您的情况下,您将受到以下限制:

    outputarea - south 边界从contentPane 的北边界限制为###px

    inputPanel - north 边界从contentPane 的南边界限制为##px。

    WindowBuilder 等 GUI 构建器可让您快速完成此操作。您只需将布局放到 contentPane 上,然后设置约束。

    【讨论】:

    • 感谢您的建议,不幸的是我们只在我正在学习的课程中学习了Swing,因此我们只能使用这些
    • @user3371750 javax.swing.SpringLayout 是 Swing 的一部分:
    【解决方案3】:

    如果您必须使用盒子布局,请查看 Box 中的粘胶和刚性区域方法。如果您可以使用其他布局,请使用其他答案建议的布局。

    【讨论】:

      【解决方案4】:

      我已经使用MigLayout 经理创建了一个解决方案。

      以下是一些建议:

      • 将应用程序代码放在构造函数之外;在解决方案中,代码 放在initUI() 方法中。
      • 应用程序应在 EDT 上通过调用 EventQueue.invokeLater()。 (请参阅所提供解决方案的main() 方法。)
      • 使用现代、灵活的布局管理器:MigLayout、GroupLayout 或 FormLayout。 花一些时间研究它们以充分了解布局管理过程。它 对这个主题有很好的理解很重要。
      • 缩短标签;使用更具描述性的工具提示 而是。
      package com.zetcode;
      
      import java.awt.EventQueue;
      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JScrollPane;
      import javax.swing.JTextArea;
      import javax.swing.JTextField;
      import net.miginfocom.swing.MigLayout;
      
      public class MigLayoutSolution extends JFrame {
      
          private JTextArea outputArea;
          private JTextField errorReportField;
      
          private JLabel nameLabel;
          private JLabel numberLabel;
          private JLabel priceLabel;
      
          private JTextField nameField;
          private JTextField numberField;
          private JTextField priceField;
      
          private JButton addVolumeButton;
          private JButton addNumberButton;
      
          public MigLayoutSolution() {
      
              initUI();
          }
      
          private void initUI() {
      
              setLayout(new MigLayout());
      
              outputArea = new JTextArea(10, 20);
              errorReportField = new JTextField(15);
      
              nameLabel = new JLabel("Item name");
              numberLabel = new JLabel("# of units");
              numberLabel.setToolTipText("Number of units (or Volume in L)");
              priceLabel = new JLabel("Price per unit");
              priceLabel.setToolTipText("Price per unit (Or L) in pence");
              nameField = new JTextField(10);
              numberField = new JTextField(10);
              priceField = new JTextField(10);
      
              addVolumeButton = new JButton("AddVol");
              addVolumeButton.setToolTipText("Add by Volume");
              addNumberButton = new JButton("AddNum");
              addNumberButton.setToolTipText("Add by number of units");
      
              add(new JScrollPane(outputArea), "grow, push, wrap");
              add(errorReportField, "growx, wrap");
              add(nameLabel, "split");
              add(nameField);
              add(numberLabel);
              add(numberField);
              add(priceLabel);
              add(priceField);
              add(addVolumeButton);
              add(addNumberButton);
      
              pack();
      
              setTitle("Fuel station");
              setLocationRelativeTo(null);
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }
      
          public static void main(String[] args) {
      
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      MigLayoutSolution ex = new MigLayoutSolution();
                      ex.setVisible(true);
                  }
              });
          }
      }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-29
        • 2019-04-04
        • 2018-05-03
        • 2016-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多