简体   繁体   中英

Java Swing UI Layout

I am creating a basic user interface in Swing and was hoping for some help. Below is a screenshot of what I am trying to achieve:

在此处输入图片说明

My code currently is as follows:

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();
    }

}

Which looks like this:

在此处输入图片说明

So what I would like to do is set a specific size for the top two JTextFields, as the top one will contain multiple lines of text, and the one below will contain just one line of text. I am unsure how to do this without using setSize, as I have been told it is bad coding practice to use this.

I would also like to add some padding between the JLabels, JTextFields and JButtons in the bottom JPanel.

If anyone could give me some suggestions on resizing these components I would be most grateful

  • Since you want your textfields to be multilined, use JTextAreas . JTextFields are single lined only.
  • Your components are right next to each other which isn't the same look as your intended outcome. There may be some method that gives your components some breathing room before you would call frame.pack()
  • Look for any method that can make a component fill the total amount of room it's given; especially when you want something to fill a large chunk of space.
  • You can set the number of columns instead of using setSize() for your JTextFields/JTextAreas. Just saying.
  • Reviewing all of Java's Layout Managers would help you get a grasp of the capabilities and use cases for each layout manager

There are a few layout managers that are flexible enough to perform this, such as Mig, Gridbag, and SpringLayout .

In your case, you'd have the following constraints:

outputarea - south border constrained to be ###px from the north border of the contentPane

errorReportArea - north border constrained to be 0px from outputarea 's south, and south border constrained to be 0px from inputPanel 's north.

inputPanel - north border constrained to be ##px from the south border of the contentPane .

GUI builders such as WindowBuilder will allow you to do this pretty quickly. You just drop in the layout onto the contentPane and then set the constraints.

If you have to use a box layout look at the glue and rigidArea methods in Box . If you can use other layouts, go with those suggested by the other answers.

I have created a solution with the MigLayout manager.

Here are some recommendations:

  • Put application code outside the constructor; in the solution, the code is placed in the initUI() method.
  • The application should be started on EDT by calling the EventQueue.invokeLater() . (See the main() method of the provided solution.)
  • Use a modern, flexible layout manager: MigLayout , GroupLayout , or FormLayout . Take some time to study them to fully understand the layout management process. It is important have a good understanding of this topic.
  • Shorten the labels; use more descriptive tooltips instead.
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);
            }
        });
    }
}

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM