按钮不会在java中被禁用

时间:2013-09-11 13:09:26

标签: java swing actionlistener

我创建了一个按钮..我希望每当我点击按钮时它首先禁用其他两个按钮,然后执行我编程的其他任务..但是它会在最后禁用按钮

Extract.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

Button1.setEnabled(false);

Button2.setEnabled(false);

obj.showData(); 

obj.extractClassesPackagesImports();

obj.inheritanceRelation();

obj.doubleinheritanceRelation();

JOptionPane.showMessageDialog(null, "Done");

}

});

现在上面的程序在显示消息框后禁用了按钮。 任何人都可以弄清楚这里有什么问题...提前谢谢

3 个答案:

答案 0 :(得分:1)

正如@vikingsteve所说,你最有可能不允许GUI线程时间来更新对话框。

如果您添加Thread.Sleep(1000);,您肯定会在停用和消息框之间看到延迟。

我不明白为什么它在对话之前或之后是否禁用按钮会有所不同。

<强>更新

我添加了一个额外的线程,以便能够利用Thread.sleep(5000),而不会完全冻结事件调度线程(GUI)。

但是,既然现在我的代码是从一个新的Thread调用showMessageDialog,我应该使用invokeLater。

此外,由于原始代码将允许用户单击按钮,即使我们正在等待活动完成,我相信所有操作都应该移动到这样的单独线程:

Extract.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                //Disable Buttons since we are in Event Dispatching Thread
                Button1.setEnabled(false);
                Button2.setEnabled(false);

                //Tasks moved to separate Thread
                 new Thread(new Runnable() {
                        public void run() {
                            try {
                                //Perform Tasks
                                obj.showData();
                                obj.extractClassesPackagesImports();
                                obj.inheritanceRelation();
                                obj.doubleinheritanceRelation();

                                //Delay before calling message (we are delaying in separate thread to not freeze GUI completely)
                                Thread.sleep(5000); 
                                //Wait 5 seconds before showing dialog

                                //Show the GUI - since GUI interaction from new Thread using invokeLater
                                SwingUtilities.invokeLater(new Runnable() {
                                    public void run() {
                                        JOptionPane.showMessageDialog(null, "Done");
                                    }
                                });

                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }                         
                        }
                    }).start();     

            }
        });

上述代码在显示消息之前会增加延迟,同时也不会冻结GUI。

答案 1 :(得分:1)

你可以试试这个:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        JOptionPane.showMessageDialog(null, "Done");
    }
});

答案 2 :(得分:0)

查看来自AbstractButtonJComponentRepaintManager的代码,我得出结论:setEnabled()在事件队列上发布了一个新事件,以显示已禁用的按钮。<登记/> 因此,查看代码时,会发生以下事件,如您所述:

EventQueue:
    Event1: {
        setEnabled(false) // queues Event2
        showMessageDialog(null, "Done")
    },
    Event2: {
        repaint() // to display the disabled button
    }

相关代码如下:

<强> AbstractButton中

public void setEnabled(boolean b) {
    // ...
    super.setEnabled(b);
    // ...
}

<强>的JComponent

public void setEnabled(boolean enabled) {
    // ...
    if (enabled != oldEnabled) {
        repaint();
    }
}

public void repaint(long tm, int x, int y, int width, int height) {
    RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
}

<强>的RepaintManager

public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
{
    // ...
    addDirtyRegion0(c, x, y, w, h);
}

private void addDirtyRegion0(Container c, int x, int y, int w, int h) {
    // ...

    // Queue a Runnable to invoke paintDirtyRegions and
    // validateInvalidComponents.
    scheduleProcessingRunnable();
}

如果您想要在显示对话框之前将按钮显示为已禁用的 ,则@ vikingsteve指出的解决方案是使用SwingUtilities.invokeLater()

extract.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        button1.setEnabled(false);
        button2.setEnabled(false);
        obj.showData(); 
        obj.extractClassesPackagesImports();
        obj.inheritanceRelation();
        obj.doubleinheritanceRelation();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JOptionPane.showMessageDialog(null, "Done");
            }
        });
    }
});