首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有JPanel的ComponentListener

带有JPanel的ComponentListener
EN

Stack Overflow用户
提问于 2012-09-08 01:14:22
回答 1查看 1.5K关注 0票数 4

我有一个主JPanel,它的布局设置为CardLayout。

主JPanel有4张卡: Card1JPanel、Card2JPanel、Card3JPanel、Card4JPanel。

我还有一个名为“SwingWorker”的MySwingy类,它在其循环标志设置为true时将执行一些永久的操作。

当Card1JPanel可见/显示时,我希望执行MySwingy工作者。

当Card1JPanel不可见/隐藏时,我要停止MySwingy工作人员;

下面是我目前的代码,我想知道是否有更好/更干净的方法来解决上面的问题。在下面的代码示例中,您将看到我使用ComponentListener for Card1JPanel来检测它是显示的还是隐藏的,但是如果我有很多很多卡片,每个卡都有自己的ComponentListener事件,这些事件侦听器会减慢我的应用程序吗?

非常感谢

代码语言:javascript
复制
public class Card1JPanel extends JPanel{

    private MySwingy mySwingy;
    private JTable tableDatabase;

    public Card1JPanel(){
        initComponents();//tableDatabase is drawn here among other things
        this.addComponentListener(new myListener());
    }

    class myListener implements ComponentListener {

        @Override
        public void componentHidden(ComponentEvent e) {
            try{
                mySwingy.stopExecuting();//A flag inside of the worker gets set to false that terminates the while(true) loop.
            }catch(NullPointerException ex){
            }
        }

        @Override
        public void componentMoved(ComponentEvent e) {
        }

        @Override
        public void componentResized(ComponentEvent e) {
        }

        @Override
        public void componentShown(ComponentEvent e) {
            mySwingy = new MySwingy(tableDatabase);
            mySwingy.execute();
        }
    }
}

编辑:显示mySwingy所做的工作:

MySwingy用于解析来自SQL数据库的数据,并在数据库中的数据发生更改时更新tableDatabase。tableDatabase位于Card1JPanel上,并在EDT上使用SwingUtilities.InvokeLater从MySwingy更新。在我的应用程序中,我有许多带有JPanels和JTables的卡片,它们可以在EDT上更新它们的JTables。现在,我确信,如果所有这些JTables都是通过SwingWorkers在EDT上不断更新的话,GUI就会冻结。因此,当SwingWorker的JTable不可见时,如何阻止其更新?这就是我的问题。

代码语言:javascript
复制
public class MySwingy extends SwingWorker<Void,Void>{

    private JTable tableDatabase;
    private boolean isStopExecuting;
    private boolean isDatabaseDataChanged;

    public MySwingy(JTable tableDatabase){
        this.tableDatabase = tableDatabase
        isStopExecuting = false;
        isDatabaseDataChanged = false;
    }

    public void stopExecuting(){
        isStopExecuting = true;
    }

    @Override
    public Void doInBackground(){

        while(isStopExecuting == false){

            //Here is the code that parses some data from an SQL database and if the data in the SQL database
            //has changed the isDatabaseDataChanged boolean flag is set to true,
            //else isDatabaseDataChanged boolean flag is set to false;

            if(isDatabaseDataChanged == true){

                isDatabaseDataChanged = false;

                SwingUtilities.InvokeLater(new Runnable(){

                    @Override
                    public void run(){

                    //Update tableDatabase rows with new data

                    }
                });
            }
        }

    return null;

    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-08 01:46:07

不要摆弄工人,让它跑吧。相反,只在视图isVisible() (直接通过process() )或通过属性更改间接更新视图时,才有条件地更新视图。

增编:一些有益的评论值得更仔细的审查。

  • 正如安德鲁指出的,这在很大程度上取决于工人的任务。可以在后台线程上发展仿真模型,但任何呈现都必须在事件调度线程上进行。
  • 我的困惑不亚于@mKorbel;您要求对解决方案进行批判性评估,而没有说明它将解决什么问题。
  • @kleopatra指出,SwingWorker被设计为只执行一次。从另一个线程控制doInBackground()循环的任何尝试都将很难同步。还检查了任务的预期延迟,提到了这里javax.swing.Timer的一个实例,它公开start()stop()方法,可能是另一种选择。
  • 更新问题:如果您的工作人员需要轮询具有可变延迟的数据源,请使用后台线程中的java.util.Timer以可持续的速度执行触发器查询。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12327254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档