Java 我应该将事件侦听器放在哪里?
我制作了许多对象,如JButton、JLabel、JCheckBox等,并向该对象添加了一个事件侦听器。这样地。 object obj=新obj(); obj.listneraddActionListener(){}; 但是,如果侦听器使用其他对象,则必须在侦听器代码之前创建该对象。 我在考虑是应该提前对对象定义进行排序,还是将所有侦听器拉到下面。 我该怎么办 对不起,我没有发布,因为代码太大了。下面是代码的一部分。我从复选框(chkName、chkAddress、chkType、chkComment)获得错误消息Java 我应该将事件侦听器放在哪里?,java,swing,Java,Swing,我制作了许多对象,如JButton、JLabel、JCheckBox等,并向该对象添加了一个事件侦听器。这样地。 object obj=新obj(); obj.listneraddActionListener(){}; 但是,如果侦听器使用其他对象,则必须在侦听器代码之前创建该对象。 我在考虑是应该提前对对象定义进行排序,还是将所有侦听器拉到下面。 我该怎么办 对不起,我没有发布,因为代码太大了。下面是代码的一部分。我从复选框(chkName、chkAddress、chkType、chkComm
JButton btnSearch=newjbutton(“”);
addActionListener(新ActionListener(){
已执行公共无效操作(操作事件arg0){
字符串str=“”;
结果集rsSid,rsNM=null;
整数计数=0;
如果(chkName.isSelected()){str+=“(从“+tableName+”中选择“+tableName+”\u SID,其中“+tableName+”\u NM类似“%””+txtSearch.getText()+“%”)联合”;++count;}
如果(chkAddress.isSelected()){str+=“(从“+tableName+”中选择“+tableName+”\u SID,其中“+”地址类似“%”“+txtSearch.getText()+“%”)联合”;++count;}
如果(chkType.isSelected()){str+=“(从“+tableName+”中选择“+tableName+”_SID,其中“+”类型类似“%””+txtSearch.getText()+“%”UNION”;++count;}
如果(chkComment.isSelected()){str+=“(从“+tableName+”中选择“+tableName+”\u SID,其中“+”注释类似于“%”“+txtSearch.getText()+“%”)UNION”++count;}
如果(计数=0)返回;
if(txtSearch.getText()!=“”)
str=str.substring(0,str.length()-7)+';';
其他的
str=“SELECT*FROM”+表名;
rsSid=jdbc.executeQuery(conn,str);
试一试{
behindList.clear();
lstSRmodel.clear();
TableSummary temp=新的TableSummary();
while(rsSid.next()){
对于(inti=1;i我不确定您是否读过这篇文章,但我将从阅读Java开始™ 关于的教程。当我学习如何正确处理GUI事件时,本教程对我帮助很大。因为要处理的事件太多,Java提供了名为EventListener
的主界面,该界面没有任何方法(它被称为标记界面)。每个JComponent
定义它必须处理的事件类型。例如,JButton
对象与JFrame
对象关注的事件集不同
您所能做的最好的事情是理解为什么需要此API的基本前提。GUI必须是事件驱动的,因为在操作发生时没有有效的方法来捕获用户交互。例如,JButton
对象至少必须侦听“单击”事件。这对您来说应该是显而易见的。但是还有一些您可能没有想到的事件。例如,将鼠标悬停在按钮上以显示工具提示
对你的问题,
如果侦听器使用其他对象,则必须在侦听器代码之前创建该对象。。。
我该怎么办
有几种方法可以解决这个问题。我将向您展示一些非常简单的案例,希望您可以使用这些案例来展开讨论。假设您有一个带有两个按钮的面板,OK和Cancel。显然,您知道这两个按钮在单击时会执行不同的功能。对于这个示例,它们所做的工作是无关的。因此,我只想单击时打印一些消息。下面的代码片段仅显示相关部分。要处理按钮单击,必须在每个按钮上添加ActionListener
public class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
String name = button.getName(); // Assuming you set "OK" and "Cancel" as the names
if (name.equals("OK")
System.out.println("I will comply with your command!");
else
System.out.println("You cancelled your request.");
}
}
然后,您可以向按钮添加一个侦听器,如下所示
MyActionListener listener = new MyActionListener();
cancelBtn.addActionListener(listener);
okBtn.addActionListener(listener);
此解决方案应该可以正常工作,但扩展性不太好。如果要在应用程序中添加更多按钮,使用这样一个侦听器是不好的,因为您的侦听器将变得工作过度。稍微好一点的解决方案是为每个实例提供自己的侦听器。您可以利用匿名类来做到这一点s。以下是方法:
cancelBtn.addActionListener(new MyActionListener(){
public void actionPerformed(ActionEvent e) {
System.out.println("I will comply with your command!");
}
});
okBtn.addActionListener(new MyActionListener(){
public void actionPerformed(ActionEvent e) {
System.out.println("You cancelled your request.");
}
});
有些人不太喜欢匿名类,因为它会影响代码的可读性。我碰巧喜欢这样一个事实,即每个对象的实例都有自己的个性化侦听器,该侦听器正好完成了对象实例在操作发生时需要做的工作
我认为这种方法应该适合您的情况。还有其他方法,但我认为您应该开始使用这种简单的方法,直到您获得更多关于如何处理事件的知识。让我知道您的想法。您应该将ActionListener
和业务代码分开:您不应该执行长时间运行查询ActionListener
,因为它会通过阻止EDT(事件调度线程)冻结应用程序
在处理Swing(或Java FX、SWT等其他框架)时,我最好执行以下操作:
- 创建GUI组件,如字段
- 配置或“初始化”布局,即将组件添加到其父级,依此类推
- 配置任何事件侦听器
这将是(如果愿意,将“init”替换为“configure”):
此外,如果您附加到Swing组件的事件是lambda类或匿名类,则它们应尽可能简单:相反,请创建一个私有方法并使用其引用:
btnSearch.addActionListener(this::searchActionListener);
以及我使用另一个线程(ForkJoinPool.commonPool()
)在EDT(事件调度线程)之外执行长时间运行的工作的方法。否则,接口将被冻结。业务方法在另一个对象(这里称为business
)之外完成
搜索按钮应该被禁用,否则用户(在这种情况下)可能会对该按钮发送垃圾邮件
private JCheckBox checkBox;
MyClass() { // constructor
this.init();
}
void init() {
initComponents();
initEventListeners();
}
void initComponents() {
this.checkBox = new JCheckBox("..."); // or in the constructor if you want final field.
// layout for the parent component
this.add(new JLabel("Label 1"));
this.add(checkBox);
}
void initEventListeners() {
this.checkBox.addActionListener(System.out::println);
}
btnSearch.addActionListener(this::searchActionListener);
private void searchActionListener(ActionEvent event) {
btnSearch.setEnabled(false); // user should not be able to search while it's running
// extract Swing data before running outside the EDT
String query = txtSearch.getText()
boolean useName = chkName.isSelected();
boolean useAddress = chkAddress.isSelected();
// ... and so on
// do work OUTSIDE the EDT
ForkJoinPool.commonPool().execute(() -> {
Result result = business.find(query, useName, useAddress);
SwingUtilities.invokeLater(() -> {
processResult(result); // do whatever is needed
btnSearch.setEnabled(true);
});
});
}
"(SELECT " + tableName + "_SID FROM " + tableName + " WHERE " + tableName + "_NM LIKE '%" + txtSearch.getText() + "%') UNION ";