我创建了一个按钮..我希望每当我点击按钮时它首先禁用其他两个按钮,然后执行我编程的其他任务..但是它会在最后禁用按钮
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");
}
});
现在上面的程序在显示消息框后禁用了按钮。 任何人都可以弄清楚这里有什么问题...提前谢谢
答案 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)
查看来自AbstractButton
,JComponent
和RepaintManager
的代码,我得出结论: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");
}
});
}
});