0

所以我有一个按钮,应该在按下后将新用户(其名称取自另一个类)添加到列表中。当我在构建并运行后通过手动单击它来按下按钮时,它工作正常。问题是,当我通过另一种方法调用 ActionEvent 方法时,它会输出我的 System.out.println 文本,但不会将任何新条目添加到列表中。

有什么建议么?

这是在按下按钮时调用的代码(标有“<--”的行似乎只有在我手动按下按钮时才有效):

public void actionPerformed(ActionEvent e) {

        listModel.insertElementAt(name, index); // <--
        System.out.println("finished running action");
    }

这是我的代码的更完整版本:

public void actionPerformed(ActionEvent e) {
        System.out.println("ran action");

        addAuthor();
        System.out.println("authornamefinalfunc name: " + name);

        //Reset the text field.
        employeeName.requestFocusInWindow();
        //employeeName.setText("");

        //Select the new item and make it visible.
        list.setSelectedIndex(index);
        list.ensureIndexIsVisible(index);
        System.out.println("ran action final");
    }
    private void addAuthor()
    {
        String name = Global.s;

        int index = list.getSelectedIndex(); //get selected index
        if (index == -1) { //no selection, so insert at beginning
            index = 0;
        } else {           //add after the selected item
            index++;
        }

        listModel.insertElementAt(name, index);

    }
4

1 回答 1

0

addAuthor是否总是在事件调度线程上调用该方法?JList(以及 Swing 中的所有内容)不是同步的或线程安全的,因此任何与 Swing 相关的修改/操作都必须在该线程上进行。由于该addAuthor方法与 Swing 组件交互,因此绝不能从除该线程之外的任何线程调用它。这适用于您在该类中拥有的任何其他方法(main如果写得好,可能是一个方法)。

如果您需要addAuthor从不是事件调度线程的线程调用 或任何其他与 Swing 组件直接交互的方法,请使用类似这样的方法来调用该方法(假设您的 Swing 表单名为“myUI”):

SwingUtilities.invokeAndWait(new Runnable() {
  @Override public void run() {
    addAuthor();
  }
});

invokeLater如果您想运行代码而不是等待它完成,您也可以使用。

如果您不确定从哪个线程代码运行,请使用以下经验法则:

  1. 您的方法中的任何代码main,或您的方法调用的任何代码main(无论有多少层深),都由“主”线程运行。
    • 例如,您的main方法调用foo(),而后者又调用bar(),而后者又调用foobar()。所有这些方法中的所有代码都由main线程运行。
  2. 如果您手动创建一个新线程,例如使用类似的东西new Thread(...).start(),该代码以及由它调用的所有方法中的代码都将从该线程运行。
  3. UI 调用的所有侦听器代码(例如您ActionListener按下按钮时的上述代码)都由事件调度线程上的代码调用。

在 Event Dispatch Thread 上运行的代码是唯一可以安全地与 Swing 组件交互的代码。因此,具有与 Swing 组件交互的代码的方法(例如您的方法ActionListener和您的addAuthor方法)只能从 EDT 中运行的代码中调用。

如果您想从任何其他线程(上面的 1 和 2)调用方法,则需要使用我在上面向您展示的方法,因为您不能直接执行此操作。

于 2014-06-17T18:19:31.990 回答