当ActionEvent的是通过另一种方法执行未执行部分的JList行动..? - Java的 [英] Some JList actions not being executed when ActionEvent is run via another method..? - Java

查看:249
本文介绍了当ActionEvent的是通过另一种方法执行未执行部分的JList行动..? - Java的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个应该添加一个新用户(其名称是从另一个类所),以列表被pressed后的按钮。当我preSS按钮,通过建立并运行后手动点击它,它工作正常。问题是,当我打电话通过其他方法ActionEvent的方法,它输出我的System.out.println文本,但犯规添加任何新的条目到列表中。

有什么建议?

这里的code,它是在一个按钮preSS称为(用标线< - 是,似乎只有工作,如果我手动preSS按钮的):

 公共无效的actionPerformed(ActionEvent的五){        listModel.insertElementAt(名,索引); //<  - 
        的System.out.println(运行完毕行动);
    }

下面是我的code更完整的版本:

 公共无效的actionPerformed(ActionEvent的五){
        的System.out.println(跑行动);        addAuthor();
        的System.out.println(authornamefinalfunc名称:+姓名);        //重置文本字段。
        employeeName.requestFocusInWindow();
        //employeeName.setText();        //选择新的项目,并使其可见。
        list.setSelectedIndex(索引);
        list.ensureIndexIsVisible(索引);
        的System.out.println(跑最后行动);
    }
    私人无效addAuthor()
    {
        字符串名称= Global.s;        INT指数= list.getSelectedIndex(); //获取选定的索引
        如果(指数== -1){//没有选择,那么在插入开始
            索引= 0;
        }其他{//选定项目之后添加
            指数++;
        }        listModel.insertElementAt(名,索引);    }


解决方案

addAuthor 方法总是被调用的事件调度线程上? JList的(和Swing中的所有内容)的不可以同步或线程安全的,所以任何的Swing相关的修改/动作必须举行在该线程。因为 addAuthor 法Swing组件进行交互,它必须绝不会从比一个其他任何线程调用。这也同样适用于该类您有任何其他的方法(可能除了一个方法,如果它写得很好)。

如果您需要调用 addAuthor ,或直接与Swing组件交互,从一个线程这不是事件调度线程,使用这样的调用任何其他方法方法(这里假设你的挥杆形式被命名为myUI):

  SwingUtilities.invokeAndWait(新的Runnable(){
  @覆盖公共无效的run(){
    addAuthor();
  }
});

您还可以,如果你想运行code,而不是等待它完成使用的invokeLater

如果你不知道哪些线程code都在运行,使用经验规则:


  1. 任何code,它是在你的的方法,或者通过你的办法(无论叫多少级深),由主线程上运行。

    • 例如,你的的方法调用富(),这反过来又调用巴(),这反过来又调用 foobar的()。总而言之,这些方法的code是由线程中运行。


  2. 如果您手动创建一个新的线程,例如喜欢的东西,新的Thread(...)。启动(),即code,和在所有被它调用的方法,code从这个线程中运行。

  3. 所有监听器code。通过用户界面调用(比如你的的ActionListener 当你PSS按钮$ P $以上)是由code呼吁事件调度线程。

$ C在事件指派线程$ C运行是在 code,可以与Swing组件交互的安全。与code的方法与Swing组件因此交互(如您的的ActionListener 和您的 addAuthor 方法)必须只从美国东部时间code运行调用。

如果你想调用任何其他线程(1及以上2)的方法,您需要使用我展示了上面的方法,因为你不能直接这样做。

So I have a button that is supposed to add a new user (whose name is taken from another class) to a list after being pressed. When I press the button by manually clicking on it after building and running, it works fine. The thing is that when I call the ActionEvent method through another method, it outputs my System.out.println text but doesnt add any new entries to the list.

Any suggestions?

Here's the code that is called in a button press (the line marked by an "<--" is the one that only seems to work if I manually press the button) :

public void actionPerformed(ActionEvent e) {

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

Here's a more complete version of my code:

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

    }

解决方案

Is the addAuthor method always being called on the event dispatch thread? JList (and everything in Swing) is not synchronized or thread safe so any Swing related modifications/actions must take place on that thread. Since the addAuthor method interacts with Swing components, it must never be called from any thread other than that one. This goes for any other method you have in that class (except possibly a main method if it's well written).

If you need to call addAuthor, or any other method that directly interacts with Swing components, from a thread that's not the event dispatch thread, use something like this to call the method (this assumes your Swing form is named "myUI"):

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

You can also use invokeLater if you want to run the code and not wait for it to finish.

If you're not sure what threads code is running from, use these rules of thumb:

  1. Any code that is in your main method, or called by your main method (no matter how many levels deep), is run by the "main" thread.
    • For example, your main method calls foo(), which in turn calls bar(), which in turn calls foobar(). All of the code in all of these methods is run by the main thread.
  2. If you manually create a new Thread, for example with something like, new Thread(...).start(), that code, and the code in all methods called by it, are run from this thread.
  3. All Listener code invoked by the UI (for example your ActionListener above when you press the button) is called by code on the Event Dispatch Thread.

Code run on the Event Dispatch Thread is the only code that can safely interact with Swing components. Methods with code that interacts with Swing components (like your ActionListener and your addAuthor methods) therefore must only be called from code running in the EDT.

If you want invoke the methods from any other thread (1 and 2 above), you need to use the method I've shown you above, since you can't do it directly.

这篇关于当ActionEvent的是通过另一种方法执行未执行部分的JList行动..? - Java的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆