Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该将事件侦听器放在哪里?_Java_Swing - Fatal编程技术网

Java 我应该将事件侦听器放在哪里?

Java 我应该将事件侦听器放在哪里?,java,swing,Java,Swing,我制作了许多对象,如JButton、JLabel、JCheckBox等,并向该对象添加了一个事件侦听器。这样地。 object obj=新obj(); obj.listneraddActionListener(){}; 但是,如果侦听器使用其他对象,则必须在侦听器代码之前创建该对象。 我在考虑是应该提前对对象定义进行排序,还是将所有侦听器拉到下面。 我该怎么办 对不起,我没有发布,因为代码太大了。下面是代码的一部分。我从复选框(chkName、chkAddress、chkType、chkComm

我制作了许多对象,如JButton、JLabel、JCheckBox等,并向该对象添加了一个事件侦听器。这样地。 object obj=新obj(); obj.listneraddActionListener(){}; 但是,如果侦听器使用其他对象,则必须在侦听器代码之前创建该对象。 我在考虑是应该提前对对象定义进行排序,还是将所有侦听器拉到下面。 我该怎么办

对不起,我没有发布,因为代码太大了。下面是代码的一部分。我从复选框(chkName、chkAddress、chkType、chkComment)获得错误消息

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 ";