【问题标题】:GUI, Java Swing, Labels and Text FieldsGUI、Java Swing、标签和文本字段
【发布时间】:2014-06-09 22:46:09
【问题描述】:

我最近开始学习如何在 Java swing 中编写代码,并且是手工编写的。 我正在尝试为一项任务制作一个 GUI,但我正在努力将四个标签附加到四个网格格式的文本字段。

文本字段在面板中,在面板中。所以我可以有按钮旁边的字段。

我真的很困惑如何从我所在的地方去。因为我希望每个标签都位于每个文本字段的左侧。因此,“Train on”位于文本字段“On”旁边的左侧,而“Train Moving”标签位于文本字段“off”的左侧。等等。我是这方面的新手,所以任何帮助将不胜感激,谢谢。我发布的代码目前有效。

编辑

出于某种原因不得不删除代码

【问题讨论】:

  • 这个问题似曾相识……前几天就看到了。啊,是的,stackoverflow.com/questions/23233473/…
  • 当您设计标签 - 字段表单时,GridBagLayout 是一个合适的选择。
  • @demongolem 是的,我看到了这个,但他没有使用任何标签或文本字段。
  • @GilbertLeBlanc 抱歉,您将如何使用 GridBagLayout?
  • @user3569279, How would you use the GridBagLayout sorry? 你读过关于使用 GridBagLayout 的教程吗?本教程有一个工作示例。教程的哪一部分你不明白?您在修改示例代码时遇到了什么问题?

标签: java swing layout-manager


【解决方案1】:

我所拥有的 GridBagLayout 的每个实际示例都很复杂。这是我拥有的最简单、真实的例子。此对话框在 BoxLayout 内有一个 GridBagLayout。该按钮位于使用 FlowLayout 的 JPanel 中

这是代码:

package com.ggl.sudoku.solver.view;

import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SolutionDialog {

    protected static final Insets   buttonInsets    = new Insets(10, 10, 0, 10);

    private int                     singleCount;
    private int                     guessCount;

    private long                    elapsedTime;

    private JDialog                 dialog;

    private SudokuFrame             frame;

    public SolutionDialog(SudokuFrame frame, int singleCount, int guessCount,
            long elapsedTime) {
        this.frame = frame;
        this.singleCount = singleCount;
        this.guessCount = guessCount;
        this.elapsedTime = elapsedTime;
        createPartControl();
    }

    private void createPartControl() {
        dialog = new JDialog(frame.getFrame(), "Statistics");
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

        JPanel resultsPanel = new JPanel();
        resultsPanel.setLayout(new GridBagLayout());

        int gridy = 0;

        JLabel singleCountLabel = new JLabel("Cells with one possible number:");
        addComponent(resultsPanel, singleCountLabel, 0, gridy, 1, 1,
                buttonInsets, GridBagConstraints.LINE_START,
                GridBagConstraints.HORIZONTAL);

        String s = singleCount + " cells";
        JLabel singleCountString = new JLabel(s);
        addComponent(resultsPanel, singleCountString, 1, gridy++, 1, 1,
                buttonInsets, GridBagConstraints.LINE_START,
                GridBagConstraints.HORIZONTAL);

        JLabel guessCountLabel = new JLabel("Cells where the solver guessed:");
        addComponent(resultsPanel, guessCountLabel, 0, gridy, 1, 1,
                buttonInsets, GridBagConstraints.LINE_START,
                GridBagConstraints.HORIZONTAL);

        s = guessCount + " cells";
        JLabel guessCountString = new JLabel(s);
        addComponent(resultsPanel, guessCountString, 1, gridy++, 1, 1,
                buttonInsets, GridBagConstraints.LINE_START,
                GridBagConstraints.HORIZONTAL);

        JLabel elapsedTimeLabel = new JLabel("Elapsed Time:");
        addComponent(resultsPanel, elapsedTimeLabel, 0, gridy, 1, 1,
                buttonInsets, GridBagConstraints.LINE_START,
                GridBagConstraints.HORIZONTAL);

        s = elapsedTime + " milliseconds";
        JLabel elapsedTimeString = new JLabel(s);
        addComponent(resultsPanel, elapsedTimeString, 1, gridy++, 1, 1,
                buttonInsets, GridBagConstraints.LINE_START,
                GridBagConstraints.HORIZONTAL);

        mainPanel.add(resultsPanel);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());

        JButton okButton = new JButton("OK");
        okButton.setAlignmentX(JButton.RIGHT_ALIGNMENT);
        okButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                dialog.setVisible(false);
                dialog.dispose();
            }
        });
        buttonPanel.add(okButton);

        mainPanel.add(buttonPanel);

        dialog.add(mainPanel);
        dialog.pack();
        dialog.setBounds(getBounds());
        dialog.setVisible(true);
    }

    private void addComponent(Container container, Component component,
            int gridx, int gridy, int gridwidth, int gridheight, Insets insets,
            int anchor, int fill) {
        GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
                gridwidth, gridheight, 1.0D, 1.0D, anchor, fill, insets, 0, 0);
        container.add(component, gbc);
    }

    protected Rectangle getBounds() {
        Rectangle f = frame.getBounds();
        Rectangle d = dialog.getBounds();
        d.x = f.x + (f.width - d.width) / 2;
        d.y = f.y + (f.height - d.height) / 2;
        return d;
    }

}

在 addComponent 方法中,我为每个 Swing 组件创建一个新的 GridBagConstraints。我这样做是因为我不喜欢记住默认值。我更喜欢为每个 Swing 组件指定所有约束。

这些 Swing 组件创建一个 JDialog,但创建 JPanel 时也适用相同的原则。

如果您想了解整个 Swing 应用程序如何组合在一起,请阅读我的文章 Sudoku Solver Swing GUI

这是另一个更复杂的示例,但它包含 JTextFields。

下面是创建输入面板的代码:

package com.ggl.envelopes.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.ggl.envelopes.model.Address;
import com.ggl.envelopes.model.EnvelopeModel;
import com.ggl.envelopes.model.State;

public class AddressPanel {

    private static final Insets entryInsets = 
            new Insets(0, 10, 4, 10);
    private static final Insets spaceInsets = 
            new Insets(10, 10, 4, 10);

    private Address currentAddress;

    private AddressComboBoxItemListener listener;

    private DefaultComboBoxModel<Address> addressComboBoxModel;
    private DefaultComboBoxModel<State> stateComboBoxModel;

    private EnvelopeModel model;

    private JButton updateButton;
    private JButton deleteButton;

    private JComboBox<Address> addressComboBox;
    private JComboBox<State> stateComboBox;

    private JLabel messageLabel;

    private JPanel mainPanel;

    private JTextField nameField;
    private JTextField address1Field;
    private JTextField address2Field;
    private JTextField cityField;
    private JTextField zip5Field;
    private JTextField zip4Field;

    public AddressPanel(EnvelopeModel model) {
        this.model = model;
        this.listener = new AddressComboBoxItemListener();
        this.addressComboBoxModel = 
                new DefaultComboBoxModel<Address>();
        this.stateComboBoxModel =
                new DefaultComboBoxModel<State>();
        createPartControl();
    }

    private void createPartControl() {
        mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());

        int gridy = 0;

        if (model.getAddresses().size() > 0) {
            gridy = createAddressComboBox(gridy);
        }

        gridy = createAddressControl(gridy);
    }

    private int createAddressComboBox(int gridy) {
        JLabel addressesLabel = new JLabel("Addresses:");
        addressesLabel.setHorizontalAlignment(JLabel.LEFT);
        addComponent(mainPanel, addressesLabel, 0, gridy, 
                1, 1, spaceInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        buildAddressComboBoxModel();

        addressComboBox = new JComboBox<Address>(addressComboBoxModel);
        addressComboBox.addItemListener(listener);
        addComponent(mainPanel, addressComboBox, 1, gridy++, 
                4, 1, spaceInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        return gridy;
    }

    private int createAddressControl(int gridy) {
        JLabel nameLabel = new JLabel("Name:");
        nameLabel.setHorizontalAlignment(JLabel.LEFT);
        addComponent(mainPanel, nameLabel, 0, gridy, 
                1, 1, spaceInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        nameField = new JTextField(30);
        nameLabel.setLabelFor(nameField);
        addComponent(mainPanel, nameField, 1, gridy++, 
                4, 1, spaceInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        JLabel address1Label = new JLabel("Address:");
        address1Label.setHorizontalAlignment(JLabel.LEFT);
        addComponent(mainPanel, address1Label, 0, gridy, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        address1Field = new JTextField(30);
        address1Label.setLabelFor(address1Field);
        addComponent(mainPanel, address1Field, 1, gridy++, 
                4, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        JLabel address2Label = new JLabel(" ");
        address2Label.setHorizontalAlignment(JLabel.LEFT);
        addComponent(mainPanel, address2Label, 0, gridy, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        address2Field = new JTextField(30);
        address2Label.setLabelFor(address2Field);
        addComponent(mainPanel, address2Field, 1, gridy++, 
                4, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        JLabel dummyLabel = new JLabel(" ");
        dummyLabel.setHorizontalAlignment(JLabel.LEFT);
        addComponent(mainPanel, dummyLabel, 0, gridy, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        cityField = new JTextField(10);
        dummyLabel.setLabelFor(cityField);
        addComponent(mainPanel, cityField, 1, gridy, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        buildStateComboBoxModel();

        stateComboBox = new JComboBox<State>(stateComboBoxModel);
        stateComboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                if (event.getActionCommand()
                        .equals("comboBoxEdited")) {
                    String s = stateComboBox.getSelectedItem()
                            .toString();
                    State t = model.getStateByAbbreviation(s);
                    if (t != null) {
                        stateComboBox.setSelectedItem(t);
                    }
                }
            }   
        });
        stateComboBox.setEditable(true);
        addComponent(mainPanel, stateComboBox, 2, gridy, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        zip5Field = new JTextField(6);
        addComponent(mainPanel, zip5Field, 3, gridy, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        zip4Field = new JTextField(6);
        addComponent(mainPanel, zip4Field, 4, gridy++, 
                1, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        messageLabel = new JLabel(" ");
        messageLabel.setHorizontalAlignment(JLabel.LEFT);
        addComponent(mainPanel, messageLabel, 0, gridy++, 
                5, 1, entryInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        JPanel buttonPanel = createButtonPanel();
        addComponent(mainPanel, buttonPanel, 0, gridy++, 
                5, 1, spaceInsets, GridBagConstraints.LINE_START, 
                GridBagConstraints.HORIZONTAL);

        return gridy;
    }

    private void buildAddressComboBoxModel() {
        addressComboBoxModel.removeAllElements();
        for (Address address : model.getAddresses()) {
            addressComboBoxModel.addElement(address);
        }
    }

    private void buildStateComboBoxModel() {
        stateComboBoxModel.removeAllElements();
        for (State state : model.getStates()) {
            stateComboBoxModel.addElement(state);
        }
    }

    private JPanel createButtonPanel() {
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 3, 20, 0));

        JButton addButton = new JButton("Add Address");
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                String message = checkFields();
                if (message.equals("")) {
                    Address address = createAddress();
                    model.addAddress(address);
                    if (model.getAddresses().size() == 1) {
                        mainPanel.removeAll();
                        int gridy = 0;
                        gridy = createAddressComboBox(gridy);
                        gridy = createAddressControl(gridy);
                    } else {
                        clearFields();
                        addressComboBox.removeItemListener(listener);
                        buildAddressComboBoxModel();
                        addressComboBox.addItemListener(listener);
                    }
                    messageLabel.setForeground(Color.GREEN);
                    messageLabel.setText("Address \"" + 
                            address.getName() + "\" saved");
                } else {
                    messageLabel.setForeground(Color.RED);
                    messageLabel.setText(message);
                }
            }           
        });
        addButton.setHorizontalAlignment(JButton.CENTER);
        buttonPanel.add(addButton);

        updateButton = new JButton("Change Address");
        updateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                String message = checkFields();
                if (message.equals("")) {
                    Address changedAddress = createAddress();
                    updateReturnSenderAddresses(
                            currentAddress, changedAddress);
                    model.updateAddress(
                            currentAddress, changedAddress);
                    clearFields();
                    addressComboBox.removeItemListener(listener);
                    buildAddressComboBoxModel();
                    addressComboBox.addItemListener(listener);
                    messageLabel.setForeground(Color.GREEN);
                    messageLabel.setText("Address \"" + 
                            currentAddress.getName() + "\" changed");
                    updateButton.setEnabled(false);
                    deleteButton.setEnabled(false);
                } else {
                    messageLabel.setForeground(Color.RED);
                    messageLabel.setText(message);
                }
            }   
        });
        updateButton.setEnabled(false);
        updateButton.setHorizontalAlignment(JButton.CENTER);
        buttonPanel.add(updateButton);

        deleteButton = new JButton("Delete Address");
        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                deleteReturnSenderAddresses(currentAddress);
                model.removeAddress(currentAddress);
                clearFields();
                addressComboBox.removeItemListener(listener);
                buildAddressComboBoxModel();
                addressComboBox.addItemListener(listener);
                messageLabel.setForeground(Color.GREEN);
                messageLabel.setText("Address \"" + 
                        currentAddress.getName() + "\" deleted");
                updateButton.setEnabled(false);
                deleteButton.setEnabled(false);
            }   
        });
        deleteButton.setEnabled(false);
        deleteButton.setHorizontalAlignment(JButton.CENTER);
        buttonPanel.add(deleteButton);

        return buttonPanel;
    }

    private void addComponent(Container container, Component component,
            int gridx, int gridy, int gridwidth, int gridheight, 
            Insets insets, int anchor, int fill) {
        GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
                gridwidth, gridheight, 1.0D, 1.0D, anchor, 
                fill, insets, 0, 0);
        container.add(component, gbc);
    }

    private String checkFields() {
        String message = "";

        State state = null;
        try {
            state = (State) stateComboBox.getSelectedItem();
        } catch (ClassCastException e) {
            message = "State abbreviation is invalid";
            return message;
        }

        if (state == null) {
            message = "State abbreviation is null";
            return message;
        }

        String abbreviation = state.getAbbreviation();

        boolean n = nameField.getText().trim().isEmpty();
        boolean a = address1Field.getText().trim().isEmpty();
        boolean c = cityField.getText().trim().isEmpty();
        boolean s = abbreviation.trim().isEmpty();
        boolean z = zip5Field.getText().trim().isEmpty();

        if (n || a || c || s || z) {
            message = "One or more required fields are empty";
            return message;
        }

//      boolean x = stateField.getText().trim().length() > 2;
        boolean g = isNumeric(zip5Field.getText().trim());

//      if (x) {
//          message = "State is more than 2 characters";
//          return message;
//      }

        if (!g) {
            message = "Zip 5 is not numeric";
            return message;
        }

        if (zip4Field.getText().trim().isEmpty()) {
            return message;
        } else {
            if (isNumeric(zip4Field.getText().trim())) {
                return message;
            } else {
                message = "Zip 4 is not numeric";
                return message;
            }
        }
    }

    private boolean isNumeric(String s) {
        try {
            Integer.valueOf(s);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private Integer setZip(String s) {
        return (s.isEmpty()) ? null : Integer.valueOf(s);
    }

    private Address createAddress() {
        String abbreviation = 
                ((State) stateComboBox.getSelectedItem())
                .getAbbreviation();

        return new Address(
                nameField.getText().trim(),
                address1Field.getText().trim(),
                address2Field.getText().trim(),
                cityField.getText().trim(),
                abbreviation.toUpperCase(),
                setZip(zip5Field.getText().trim()),
                setZip(zip4Field.getText().trim())
                );
    }

    private void clearFields() {
        nameField.setText("");
        address1Field.setText("");
        address2Field.setText("");
        cityField.setText("");
        stateComboBox.setSelectedIndex(0);
        zip5Field.setText("");
        zip4Field.setText("");
    }

    private void setFields(Address address) {
        nameField.setText(address.getName());
        address1Field.setText(address.getAddressLine1());
        address2Field.setText(address.getAddressLine2());
        cityField.setText(address.getCity());
        stateComboBox.setSelectedItem(
                model.getStateByAbbreviation(address.getState()));
        zip5Field.setText(String.format("%05d", address.getZip5()));
        zip4Field.setText(displayZip4(address.getZip4()));
    }

    private String displayZip4(Integer value) {
        return (value == null) ? "" : String.format("%04d", value);
    }

    private void updateReturnSenderAddresses(Address oldAddress,
            Address newAddress) {
        if (oldAddress.equals(model.getReturnAddress())) {
            model.setReturnAddress(newAddress);
        }
        if (oldAddress.equals(model.getSenderAddress())) {
            model.setSenderAddress(newAddress);
        }
    }

    private void deleteReturnSenderAddresses(Address address) {
        if (address.equals(model.getReturnAddress())) {
            model.clearReturnAddress();
        }
        if (address.equals(model.getSenderAddress())) {
            model.clearSenderAddress();
        }
    }

    public void refresh() {
        messageLabel.setText(" ");
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    public class AddressComboBoxItemListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent event) {
            currentAddress = (Address) 
                    addressComboBox.getSelectedItem();
            setFields(currentAddress);
            updateButton.setEnabled(true);
            deleteButton.setEnabled(true);
        }

    }

}

我使用相同的 addComponent 方法将 Swing 组件添加到主 JPanel。你可以看到我是如何处理 JTextFields 的。

【讨论】:

  • 谢谢,我想我只是让自己更加困惑,因为我创建了四个没有标识符的文本字段。因为我需要一个标识符才能正确使用 addComponent 吗?我也不知道,如果我确实单独创建字段,我不知道如何使用布局管理器让它们像网格一样布局,而不需要创建更多面板。
  • @user3569279:我不确定我是否了解您的 cmets。每个 Swing 组件都必须有一个字段名称,以便您可以将 Swing 组件添加到布局管理器。字段名称可以是 createPartControl 方法的本地名称,也可以是 JTextField 的全局名称,因为您最终希望在操作侦听器中获取文本。
  • 我不明白,当我添加一个组件时,如何区分不同的 JTextField。添加不同的标签。
  • @user3569279:给他们不同的字段名称,就像我在代码示例中所做的那样。我在答案中添加了对话框的图片。希望它能让 GridBagLayout 的列和行更清晰。
  • 对,我想我只需要考虑一下。非常感谢您的帮助。
猜你喜欢
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多