[英]Trying to add ActionListener to JButtons
I cannot figure out how to add Actionlisteners
to the JButton
s, any help would be much appreciated. 我不知道如何将
Actionlisteners
添加到JButton
,任何帮助将不胜感激。
public class Translator extends JPanel implements MouseListener, ActionListener {
private JButton french = new JButton();
private JButton german = new JButton();
private JButton irish = new JButton();
public Translator(){
french = new JButton("French");
german = new JButton("German");
irish = new JButton("Irish");
setLayout(new GridLayout(2,1));
buttonPanel.setLayout(new GridLayout(1,3));
buttonPanel.add(french);
buttonPanel.add(german);
buttonPanel.add(irish);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
}
There are plenty of ways to add an ActionListener
, to a given JComponent
(that supports it's use). 有很多方法可以将
ActionListener
添加到给定的JComponent
(支持它的使用)中。 I have added some comments in the code snippets, to help explain them a bit better, and some links in the comments for future reference. 我在代码段中添加了一些注释,以帮助更好地解释它们,并在注释中添加了一些链接,以供将来参考。
1.) If the class implements the ActionListener
interface, ie the class itself contains the actionPerformed(...)
method , then one can do it, in this manner: 1.) 如果该类实现了
ActionListener
接口,即该类本身包含actionPerformed(...)
方法 ,则可以通过以下方式做到这一点:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Skeleton implements ActionListener {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is one way of attaching an ActionListener
* to the JButton, but the main disadvantage of
* this approach is, it breaks encapsulation,
* as you can see the public method, actionPerformed(),
* is lying free to be accessed by any code outside
* the scope of the class
*/
button.addActionListener(this);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Skeleton().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
}
2.) If one doesn't wants to create unnecessary class
files. 2) 如果不想创建不必要的
class
文件。 Then this approach, which uses, EventHandler
can be used: 然后可以使用
EventHandler
这种方法:
import java.awt.*;
import java.awt.event.*;
import java.beans.EventHandler;
import javax.swing.*;
public class Example1 {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is another way of attaching
* an ActionListener to the JButton,
* the main advantage of this approach
* is, that one does not have to create
* a new class to handle events
* More info regarding the use of this
* approach, can be found on this link :
* http://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
*/
button.addActionListener((ActionListener)
EventHandler.create(ActionListener.class
, Example1.this, "buttonAction", ""));
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example1().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
public void buttonAction(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
}
3.) If one is more concern about the concept of Encapsulation
, then this approach is beneficial: 3.) 如果人们更关心
Encapsulation
的概念,那么这种方法是有益的:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example2 {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private ActionListener buttonActions =
new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
};
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is another way of attaching
* an ActionListener to the JButton,
* the main advantage of this approach
* is, it adheres to encapsulation.
*/
button.addActionListener(buttonActions);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example2().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
4.) If one is more inclined towards creation of Anonymous Classes, then this approach can be used: 4.) 如果更倾向于创建匿名类,则可以使用这种方法:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example3 {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is the fourth way of attaching
* an ActionListener to the JButton,
* the main advantage of this approach
* is, it adheres to encapsulation, the
* public method remains hidden
* inside the Anonymous Class
* More info can be found on this link :
* http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
* The main disadvantage of this approach is
* that it doesnot gives you the privilege
* of separation of concerns, which can
* be done using the fifth approach,
* which is MVC - Pattern (Model-View-Controller)
* and moreover, it creates a hell lot of classes, in
* your project, which can lead to extra overhead
*/
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
});
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example3().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
EDIT: 编辑:
5.) This approach, includes using Action
instead of ActionListener
. 5.) 这种方法包括使用
Action
而不是ActionListener
。 This is to be used for sharing same functionality among various JComponent
s, which leads to code reusability 这用于在各种
JComponent
之间共享相同的功能,从而导致代码可重用性
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example4 {
private JFrame frame;
private JPanel contentPane;
private JMenuItem showMenuItem;
private JButton button;
private Action myActions;
/*
* This approach is basically used, when
* one wants to share the same functionality
* of different JComponents among each other,
* without writing redundant codes for each
* one of those components. Here JMenuItem
* and JButton are both using the same
* functionality, to perform the same task.
* More info can be found on this link:
* http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
*/
private class MyActions extends AbstractAction {
public MyActions(String title, String desc) {
super(title);
putValue(SHORT_DESCRIPTION, desc);
}
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
}
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
myActions = new MyActions("Show", "A small description");
button.setAction(myActions);
contentPane.add(button);
frame.setJMenuBar(getJMenuBar());
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JMenuBar getJMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
showMenuItem = new JMenuItem(myActions);
fileMenu.add(showMenuItem);
menuBar.add(fileMenu);
return menuBar;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example4().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
french.addActionListener(an_instance_of_the_class_where_actionPerformed_is);
which, as I can see after the edit, would be this
其中,因为我可以编辑看到后,会是
this
Also, see this Example and some tutorial text in this corner of the web 另外,请参阅此示例和网络此角的一些教程文本
I think that the reference to the tutorial and the many examples is highly relevant. 我认为对本教程和许多示例的引用非常相关。
button.addActionListener(<your_ActionListener_here>);
In your case, it'll be: 在您的情况下,它将是:
french.addActionListener(this);
If you want to use the same ActionListener for all the three buttons, you can use the getSource() function of ActionEvent e to detect which button was actually pressed. 如果要对所有三个按钮使用相同的ActionListener,则可以使用ActionEvent e的getSource()函数来检测实际按下了哪个按钮。
If you are using Java8, you can try this. 如果您使用的是Java8,则可以尝试此操作。
JButton french = new JButton("French");
french.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae){
System.out.println("Button french clicked!");
}
});
french.addActionListener(button -> System.out.println("Button Click listener..."));
JFrame frame = new JFrame("Button Listener Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(french, BorderLayout.CENTER);
frame.setSize(250, 250);
frame.setVisible(true);
Obviously the answer is place this
into your addActionListener
method. 显然答案是将
this
放入您的addActionListener
方法中。
The addActionListener
method takes as an argument an object that implements ActionListener
interface, this interface force you to implements/place-in-your-code the actionPerformed
method which is the one that is called, when an action is triggered to the component that is assigned. addActionListener
方法将实现 ActionListener
接口的对象作为参数,当操作被触发给分配给组件的组件时,该接口将强制您实现/将您执行的代码放置在被执行的actionPerformed
方法中。 。
So, placing this
in your method, it will search inside the object you passed, in our case, the Translator
object for an actionPerformed
method and call it. 所以,把
this
在你的方法,将您传递的对象中进行搜索,在我们的情况下, Translator
对象的actionPerformed
方法并调用它。
this.french.addActionListener(this);
Of course there is a lot of code missing in order to work. 当然,为了工作,缺少很多代码。
I really liked @Sandeep answer take use of lambda expression. 我真的很喜欢@Sandeep答案使用lambda表达式。 You can see a full example below.
您可以在下面看到完整的示例。
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Translator extends JPanel implements ActionListener {
private JButton french = new JButton();
private JButton german = new JButton();
private JButton irish = new JButton();
@SuppressWarnings("empty-statement")
public Translator(){
french = new JButton("French");
german = new JButton("German");
irish = new JButton("Irish");
// setLayout(new GridLayout(2,1));
this.setLayout(new GridLayout(1,3));
this.add(french);
this.add(german);
this.add(irish);
ActionListener ac = (ActionEvent ae) -> { System.out.println(((JButton) ae.getSource()).getText()); };
this.french.addActionListener(ac);
this.german.addActionListener(ac);
this.irish.addActionListener(ac);
this.irish.addActionListener(Translator.this);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(((JButton) e.getSource()).getText());
}
public static void main(String[] args) {
JFrame jframe = new JFrame("StackOverflow");
jframe.add(new Translator());
jframe.pack();
jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
}
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//To-Do
//Button clicked
});
Hope this helps, it's relatively simple! 希望这会有所帮助,这相对简单! You just need to add an ActionListener to your desired JButton
您只需要将ActionListener添加到所需的JButton中
To give you a broader idea of how to implement it in a case-scenario where I would like to run a new GUI frame after pressing a button: 为了让您更广泛地了解如何在需要按下按钮后运行新GUI框架的情况下实现它:
startNewFrame.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Starting new frame");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
NewFrame newFrame = new NewFrame();
newFrame.setVisible(true);
dispose();//Disposes of current frame
}
});
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.