英文:
How to find what button was pressed last in Java Swing
问题
我现在正在使用Java JDK 14.0.2进行Java Swing项目开发。我正在使用Eclipse(如果这有关系的话)。我尝试使用附加到我的JButton的动作监听器来查看先前按下了哪个按钮,然后根据先前按下的按钮执行不同的操作。
我有以下的项目:
TestFrame.java
```Java
package TestSwing;
import javax.swing.JFrame;
public class TestFrame extends JFrame {
public TestFrame() {
super();
this.add(new TestPanel());
this.pack();
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setVisible(true);
}
}
TestFrame.java 被实例化在另一个包含主方法的文件中。
TestPanel.Java
package TestSwing;
import javax.swing.JPanel;
public class TestPanel extends JPanel {
public TestPanel() {
super();
this.add(new TestButton1());
this.add(new TestButton2());
}
}
现在问题的关键部分:这两个按钮:
TestButton1.java
package TestSwing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class TestButton1 extends JButton {
public TestButton1() {
super();
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (/*在此之前按下的按钮是TestButton2*/) {
System.out.println("上次按下的是按钮2");
}
else if (/*在此之前按下的按钮是自己*/) { // 这个else if很重要
System.out.println("上次按下的是按钮1");
}
}
});
this.setText("按钮1");
}
}
这是按钮2:
package TestSwing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class TestButton2 extends JButton {
public TestButton2() {
super();
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
;
}
});
this.setText("按钮2");
}
}
我已经尝试搜索解决方案,但没有找到我需要的内容,也不知道如何开始自己实现。提前感谢您的帮助。
<details>
<summary>英文:</summary>
I am working with Java JDK 14.0.2 right now on a java swing project. I am using Eclipse (if that matters). I am trying to use the action listener attached to my JButtons in order to see which button was pressed previously and then perform a different action based on what button was pressed before.
I have the following project:
TestFrame.java
```Java
package TestSwing;
import javax.swing.JFrame;
public class TestFrame extends JFrame {
public TestFrame() {
super();
this.add(new TestPanel());
this.pack();
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setVisible(true);
}
}
TestFrame.java is being instantiated in a different file where the main method is.
TestPanel.Java
package TestSwing;
import javax.swing.JPanel;
public class TestPanel extends JPanel {
public TestPanel() {
super();
this.add(new TestButton1());
this.add(new TestButton2());
}
}
Now the important part of the question The two buttons:
TestButton1.java
package TestSwing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class TestButton1 extends JButton {
public TestButton1() {
super();
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (/*last button pressed before this one is TestButton2*/) {
System.out.println("Button 2 was pressed last");
}
else if (/*last button pressed before this one was itself*/) { // It is important that this is else if
System.out.println("Button 1 was pressed last");
}
}
});
this.setText("Button 1");
}
}
And here is button 2:
package TestSwing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class TestButton2 extends JButton {
public TestButton2() {
super();
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
;
}
});
this.setText("Buttton 2");
}
}
I have already tried searching for a solution for this but cannot find what I was looking for and I have no idea on how to begin to do this myself. Thanks in advance for the help.
答案1
得分: 5
-
不要扩展JButton。没有必要这样做,而且这只会导致混淆,因为你的监听器是内部的在JButton类中。
-
将监听器与按钮分离 - 将其移到JButton类之外。
-
为什么不给两个按钮相同的动作监听器?
-
在监听器中添加一个JButton字段,该字段被分配为ActionEvent的源引用(通过
e.getSource()
获得)。这将保存对上次按下的按钮的引用。
例如:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.*;
public class LastButtonPressed {
private JButton lastButton = null;
private JButton previousButton = null;
private JTextField lastButtonsText = new JTextField(10);
private JTextField previousButtonsText = new JTextField(10);
private JPanel mainPanel = new JPanel(new BorderLayout());
public LastButtonPressed() {
int sides = 8;
JPanel buttonGridPanel = new JPanel(new GridLayout(sides, sides));
ActionListener listener = e -> {
previousButton = lastButton;
lastButton = (JButton) e.getSource();
previousButtonsText.setText(lastButtonsText.getText());
lastButtonsText.setText(e.getActionCommand());
};
for (int i = 0; i < sides * sides; i++) {
String text = "Button " + (i + 1);
JButton button = new JButton(text);
button.addActionListener(listener);
buttonGridPanel.add(button);
}
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Previous Button:"));
topPanel.add(previousButtonsText);
topPanel.add(Box.createHorizontalStrut(20));
topPanel.add(new JLabel("Last Button:"));
topPanel.add(lastButtonsText);
mainPanel.add(topPanel, BorderLayout.PAGE_START);
mainPanel.add(buttonGridPanel);
}
public JPanel getMainPanel() {
return mainPanel;
}
public JButton getLastButton() {
return lastButton;
}
public JButton getPreviousButton() {
return previousButton;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Last Button Pressed");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LastButtonPressed().getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
- 更新以添加上一个按钮的信息
英文:
- Don't extend JButton. There is no need and it only serves to confuse since you have your listener internal in the JButton class.
- Separate the listener from the button -- get it outside of your JButton class.
- Why not give both buttons the same action listener?
- Within the listener add a JButton field that is assigned the ActionEvent's source reference (obtained via
e.getSource()
). This will hold the reference to the last button pressed.
For example:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.*;
public class LastButtonPressed {
private JButton lastButton = null;
private JButton previousButton = null;
private JTextField lastButtonsText = new JTextField(10);
private JTextField previousButtonsText = new JTextField(10);
private JPanel mainPanel = new JPanel(new BorderLayout());
public LastButtonPressed() {
int sides = 8;
JPanel buttonGridPanel = new JPanel(new GridLayout(sides, sides));
ActionListener listener = e -> {
previousButton = lastButton;
lastButton = (JButton) e.getSource();
previousButtonsText.setText(lastButtonsText.getText());
lastButtonsText.setText(e.getActionCommand());
};
for (int i = 0; i < sides * sides; i++) {
String text = "Button " + (i + 1);
JButton button = new JButton(text);
button.addActionListener(listener);
buttonGridPanel.add(button);
}
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Previous Button:"));
topPanel.add(previousButtonsText);
topPanel.add(Box.createHorizontalStrut(20));
topPanel.add(new JLabel("Last Button:"));
topPanel.add(lastButtonsText);
mainPanel.add(topPanel, BorderLayout.PAGE_START);
mainPanel.add(buttonGridPanel);
}
public JPanel getMainPanel() {
return mainPanel;
}
public JButton getLastButton() {
return lastButton;
}
public JButton getPreviousButton() {
return previousButton;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Last Button Pressed");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LastButtonPressed().getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
- updated to add previous button information
Explanation of portions the code
Variables (fields) that hold that last button pressed as well as the previous button pressed before the last one:
private JButton lastButton = null;
private JButton previousButton = null;
JTextFields to display the text held on these last buttons:
private JTextField lastButtonsText = new JTextField(10);
private JTextField previousButtonsText = new JTextField(10);
Main JPanel that holds the application:
private JPanel mainPanel = new JPanel(new BorderLayout());
Create a JPanel that holds an 8x8 grid of JButtons:
int sides = 8;
JPanel buttonGridPanel = new JPanel(new GridLayout(sides, sides));
Create an ActionListener that is added to the buttons. Inside the listener, set the previous button as well as the last button, and update the text held by the JTextFields:
ActionListener listener = e -> {
previousButton = lastButton;
lastButton = (JButton) e.getSource();
previousButtonsText.setText(lastButtonsText.getText());
lastButtonsText.setText(e.getActionCommand());
};
In a for-loop, create the 8x8 JButtons, add the ActionListener to each button and add each button to the JPanel grid:
for (int i = 0; i < sides * sides; i++) {
String text = "Button " + (i + 1);
JButton button = new JButton(text);
button.addActionListener(listener);
buttonGridPanel.add(button);
}
Add everything to the sub-JPanels and the main JPanel:
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Previous Button:"));
topPanel.add(previousButtonsText);
topPanel.add(Box.createHorizontalStrut(20));
topPanel.add(new JLabel("Last Button:"));
topPanel.add(lastButtonsText);
mainPanel.add(topPanel, BorderLayout.PAGE_START);
mainPanel.add(buttonGridPanel);
Create a JFrame in a Swing thread-safe manner, create our LastButtonPressed instance and add its main JPanel to the JFrame, and finally display the JFrame:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Last Button Pressed");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LastButtonPressed().getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论