首页 > 解决方案 > 如何在java GUI swing中制作更多按钮

问题描述

我想使用 java swing 制作两个按钮,一个将 +25 加到 100,初始值,另一个将 +10 加到 100,始终为初始值:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class GUI implements ActionListener {
    private int button1 = 100;
    private int button2 = 100;
    private JLabel label;
    private JFrame frame;
    private JPanel panel;
    
    
    public GUI() {
        
        JFrame frame = new JFrame();
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        // Bottone & etichetta per il player 1
        JButton button = new JButton("add 25");
        panel1.add(button);
        button.addActionListener(this);
        label = new JLabel("initial value: 100");
        panel1.add(label);
        // Bottone & etichetta per il player 1
        JButton button1 = new JButton("add 10");
        panel2.add(button1);
        button1.addActionListener(this);
        label = new JLabel("initial value: 100");
        panel1.add(label);
        
        
        // Impostazioni della finestra
        panel1.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30));
        panel1.setLayout(new GridLayout(0, 1));
    
        frame.add(panel1, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("GUI");
        frame.pack();
        frame.setVisible(true);
        // Impostazioni della finestra
     }  
        public static void main(String args[]) {
            new GUI();
       
        
    }
        @Override
        public void actionPerformed(ActionEvent e) {
            button1 = button1 + 25;
             label.setText("Value: " + button1);
        }
        public void actionPerformed2(ActionEvent e) {
            button2 = button2 + 10;
            label.setText("Value: " + button2);
        }
    
}

如您所见,它应该创建两个按钮,这是我最初收到的输出:

(button) add 25
(label) initial value: 100
(label) initial value: 100

https://i.stack.imgur.com/1MSHz.png

在我点击它之后,它只会在第一个中添加 25:

(button) add 25
(label) initial value: 125
(label) initial value: 100

标签: javaswing

解决方案


在创建 Swing GUI 时,将数据模型与 GUI 视图分开是一个非常好的主意。这种分离使得模型编码更容易,视图编码更容易。控制器更新模型,模型又更新视图。

这是我为说明此模型/视图/控制器模式而创建的 GUI。

增量图形用户界面

我做的第一件事是定义一些字段和一个数组。

private int[] values;

private int startValue;
private int currentValue;

startValue起始值 (100),currentValue是当前值(图中的 205),并且values是一个int包含值 10 和 25 的数组。

这是设置这些值的代码。我在类的构造函数中设置了这些值,因此在其他任何事情发生之前就设置了它们。

public IncrementGUI() {
    this.startValue = 100;
    this.currentValue = startValue;
    this.values = new int[] { 10, 25 };
}

由于我将值放入int数组中,如果我想添加另一个值,我所要做的就是将值添加到values数组中。

现在我们已经构建了模型,让我们从视图开始。这是我的主要方法。

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            IncrementGUI inc = new IncrementGUI();
            inc.createJFrame();
        }
    });
}

我调用该SwingUtilities invokeLater方法以确保我创建和执行的 Swing 组件是在Event Dispatch Thread上创建和执行的。这使我们不会遇到 GUI 的线程问题。

当我实例化类时,在构造函数中设置模型字段,然后创建 GUI。

这是我编写的创建 JFrame 的方法。

private void createJFrame() {
    JFrame frame = new JFrame("Increment Value");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    frame.add(createValuePanel(), 
            BorderLayout.BEFORE_FIRST_LINE);
    frame.add(createButtonPanel(), BorderLayout.CENTER);
    
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setVisible(true);
}

JFrame 方法必须按特定顺序调用。这是我用于大多数 Swing 应用程序的顺序。

setDefaultCloseOperation方法允许我在左键单击右上角的 X 按钮时关闭应用程序。该方法采用 Swing 组件并将它们“打包”到与 Swing 组件大小一致pack的最小可能中。JFramesetLocationByPlatform方法设置JFrame屏幕上的位置与平台操作系统一致。最后,该setVisible方法使JFrame可见。

我们创建了两个JPanels,一个用于保存“价值”JLabelJTextField,另一个用于保存JButtons. 我们这样做是因为我想使用两个不同的Swing 布局管理器来布局 Swing 组件。

默认情况下JFrame有一个BorderLayout。我将值放在JPanel第一行(顶部)和JPanel中间的按钮之前。

JPanel接下来,我在方法中对值的细节进行了编码createValuePanel

private JPanel createValuePanel() {
    JPanel panel = new JPanel(new FlowLayout());
    
    JLabel label = new JLabel("Value: ");
    panel.add(label);
    
    valueField = new JTextField(10);
    valueField.setEditable(false);
    setValueField(currentValue);
    panel.add(valueField);
    
    return panel;
}

public void setValueField(int value) {
    valueField.setText(NF.format(value));
}

我用 aJTextField来保存当前值。我使它不可编辑,因此用户无法更改该值。

我把这个setValueField方法写成一个单独的方法,因为我们要actionPerformedActionListener.

我们使用 a 是FlowLayout因为我希望 Swing 组件从左向右流动。

JPanel接下来,我在方法中编写了按钮的详细信息createButtonPanel

private JPanel createButtonPanel() {
    JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
    panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    
    for (int index = 0; index < values.length; index++) {
        JButton button = new JButton("Add " + values[index]);
        button.addActionListener(this);
        button.setActionCommand(Integer.toString(values[index]));
        panel.add(button);
    }
    
    return panel;
}

我用 aGridLayout来保存JButtons. 我在周围放置了一些空白区域并JButtons带有空白边框,以使 GUI 在视觉上更具吸引力。

因为我JButtons在 for 循环中创建了,所以我创建了与数组中的值一样多JButtons的值。values这样,当您向values数组添加值时,将创建一个新的 JButton。

AJButton可以保存操作命令String以及显示文本。我们使用此操作命令String将增量值传递给actionPerformed方法。

最后,我对actionPerformed方法进行了编码。这很简单。我从 中获取增量值JButton,增加当前值,并在 中显示当前值JTextField

@Override
public void actionPerformed(ActionEvent event) {
    int value = Integer.valueOf(event.getActionCommand());
    currentValue += value;
    setValueField(currentValue);
}

这是整个可运行的示例。我希望这个解释可以帮助您创建更复杂的 Swing GUI。

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class IncrementGUI implements ActionListener {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                IncrementGUI inc = new IncrementGUI();
                inc.createJFrame();
            }
        });
    }
    
    private static NumberFormat NF = 
            NumberFormat.getIntegerInstance();
    
    private int[] values;
    
    private int startValue;
    private int currentValue;
    
    private JTextField valueField;
    
    public IncrementGUI() {
        this.startValue = 100;
        this.currentValue = startValue;
        this.values = new int[] { 10, 25 };
    }
    
    private void createJFrame() {
        JFrame frame = new JFrame("Increment Value");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createValuePanel(), 
                BorderLayout.BEFORE_FIRST_LINE);
        frame.add(createButtonPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createValuePanel() {
        JPanel panel = new JPanel(new FlowLayout());
        
        JLabel label = new JLabel("Value: ");
        panel.add(label);
        
        valueField = new JTextField(10);
        valueField.setEditable(false);
        setValueField(currentValue);
        panel.add(valueField);
        
        return panel;
    }
    
    public void setValueField(int value) {
        valueField.setText(NF.format(value));
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        for (int index = 0; index < values.length; index++) {
            JButton button = new JButton("Add " + values[index]);
            button.addActionListener(this);
            button.setActionCommand(Integer.toString(values[index]));
            panel.add(button);
        }
        
        return panel;
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        int value = Integer.valueOf(event.getActionCommand());
        currentValue += value;
        setValueField(currentValue);
    }

}

推荐阅读