java - 如何在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
在我点击它之后,它只会在第一个中添加 25:
(button) add 25
(label) initial value: 125
(label) initial value: 100
解决方案
在创建 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
的最小可能中。JFrame
该setLocationByPlatform
方法设置JFrame
屏幕上的位置与平台操作系统一致。最后,该setVisible
方法使JFrame
可见。
我们创建了两个JPanels
,一个用于保存“价值”JLabel
和JTextField
,另一个用于保存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
方法写成一个单独的方法,因为我们要actionPerformed
在ActionListener
.
我们使用 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);
}
}
推荐阅读
- java - 如何在java中使用TThreadedSelectorServer的TBufferedTransport
- cmd - 使用 BAT 文件作为 NSSM 服务
- java - Java-8 流:转换 List<{String,List
}> 到地图 > - java - Robotframework Appium - 当前未设置 JAVA_HOME
- symfony - 修改引导数据表
- javascript - 为什么 headerTransparent 和自定义参数 headerTitle 不能一起工作?
- salesforce - 在 LWC 中重新加载导航选项卡
- wpf - 适合 WPF Mvvm 中的窗口
- postgresql - 尝试在一个连接到另一个 postgres 的容器中运行 go 程序时出现拨号错误(拨号 tcp 172.18.0.2:8001:连接:连接被拒绝)
- elasticsearch - 从 Elasticsearch 中删除数据 Maxed out index