Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.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 带有ComponentListener的JPanel_Java_Swing_Events_Jpanel_Swingworker - Fatal编程技术网

Java 带有ComponentListener的JPanel

Java 带有ComponentListener的JPanel,java,swing,events,jpanel,swingworker,Java,Swing,Events,Jpanel,Swingworker,我有一个主JPanel,它的布局设置为CardLayout 主JPanel有4张卡:Card1JPanel、Card2JPanel、Card3JPanel、Card4JPanel 我还有一个名为“MySwingy”的SwingWorker类,它在循环标志设置为true时永远执行某些操作 当Card1JPanel可见/显示时,我希望执行MySwingy worker 当Card1JPanel不可见/隐藏时,我想停止MySwingy worker 下面是我目前拥有的代码,我想知道是否有更好/更干净的

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

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

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

当Card1JPanel可见/显示时,我希望执行MySwingy worker

当Card1JPanel不可见/隐藏时,我想停止MySwingy worker

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

多谢各位

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上,并使用SwingUtilities.InvokeLater在MySwingy的EDT上更新。在我的应用程序中,我有许多带有JTables的卡(JPanel)和Swingworker,它们在EDT上更新JTables。现在,我确信如果所有这些JTables都从Swingworker在EDT上不断更新,GUI将会冻结。因此,当JTable的JPanel不可见时,如何阻止SwingWorker更新JTable?这是我的问题

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;

    }
}
公共类MySwingy扩展SwingWorker{
专用JTable数据库;
私有布尔执行;
私有布尔值isDatabaseDataChanged;
公共MySwingy(JTable表数据库){
this.tableDatabase=tableDatabase
isStopExecuting=false;
isDatabaseDataChanged=false;
}
公共无效停止执行(){
isStopExecuting=true;
}
@凌驾
公共无效doInBackground(){
while(isStopExecuting==false){
//下面是解析SQL数据库中的一些数据的代码,如果SQL数据库中的数据
//已更改isDatabaseDataChanged boolean标志设置为true,
//else isDatabaseDataChanged布尔标志设置为false;
如果(isDatabaseDataChanged==true){
isDatabaseDataChanged=false;
SwingUtilities.InvokeLater(新的Runnable(){
@凌驾
公开募捐{
//使用新数据更新tableDatabase行
}
});
}
}
返回null;
}
}

不要切换工作者;让它跑吧。相反,只有当视图
可见时才有条件地更新它()
,可以直接通过
过程()
或通过属性更改间接更新

附录:一些有用的评论值得仔细研究

  • 正如@Andrew所指出的,这在很大程度上取决于工人的任务。可以在后台线程上演化模拟的模型,但任何渲染都必须在后台线程上进行

  • 我和@mKorbel一样困惑;您要求对解决方案进行批判性评估,但没有说明它要解决什么问题

  • @克利奥帕特拉指出,SwingWorker的设计初衷是。从另一个线程控制
    doInBackground()
    循环的任何尝试都将难以同步。还要检查任务的预期延迟,如上所述。
    javax.swing.Timer
    的一个实例,它公开了
    start()
    stop()
    方法,可能是一种替代方法

  • :如果工作人员需要轮询具有可变延迟的数据源,请在后台线程中使用
    java.util.Timer
    ,以可持续的速度执行触发器查询


“不要切换工作程序;让它运行”如果工作程序正在运行2D shooter的进程,则不会特别有用在这一阶段有帮助的是OP中关于“Swingy thingy”做什么的更多细节。请我不理解这两个描述,回答和评论:-),更强调不要切换,请:根据api文档,这是明确禁止的:-)优秀的评论;我已经在上面详细阐述了,你不需要这些。让工人在
过程()中更新每个模型。
;该表将在显示时更新。在后台线程中使用
java.util.Timer
以可持续的速度执行触发器查询。我确信GUI会冻结-您是如何得出这个结论的?你试过了吗?如果没有(或者换句话说,如果你实际上是在猜测),那么在你真正看到性能损失之前不要操心,然后找到瓶颈并修复它。我没有测量它,也没有在这个项目中尝试过它,我只是在做一个有根据的猜测。此外,如果可能的话,我更喜欢在一开始就消除这些类型的问题,而不是在以后上几百节课。只有通过测量验证才能将猜测转换为有根据的猜测:-)