我有一个模态对话框,用线程制作任务。 这很好用,除了主窗口不再可聚焦,在操作系统任务栏中点击我的应用程序图标没有效果,这种类型的事件被冻结,当其他窗口结束并且我想显示时它是一个问题再一次。
(我只使用SWT,没有JFace)
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
public class ProgressBox extends Dialog {
protected Shell dialog;
protected ProgressBar bar;
public ProgressBox(Shell parent, final String name) {
super(parent);
dialog = new Shell(parent, SWT.APPLICATION_MODAL | SWT.TITLE);
dialog.setSize(400,64);
dialog.setText(name);
dialog.setLayout(new FillLayout());
bar = new ProgressBar(dialog, SWT.SMOOTH);
}
public void playScript() {
this.bar.setMaximum(10);
this.dialog.open();
final Display display = dialog.getDisplay();
display.asyncExec(new Runnable() { //asyncExec syncExec
@Override
public void run() {
try {
for (int i=0; i<10; i++) {
try {
Thread.sleep(1000); // To simulate a task execution
} catch (InterruptedException e) {}
bar.setSelection(i+1);
display.sleep();
}
} finally {
dialog.close();
}
}
});
while (!dialog.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
主要班级:
import org.eclipse.swt.widgets.Display;
public class MainWindow {
protected Shell shell;
public static void main(String[] args) {
try {
MainWindow window = new MainWindow();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
public void open() {
Display display = Display.getDefault();
shell = new Shell();
shell.setSize(450, 300);
shell.open();
shell.layout();
ProgressBox progressBox = new ProgressBox(shell, "Test");
progressBox.playScript();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
有什么想法吗?
答案 0 :(得分:0)
我认为你的问题是这两者的结合:
while (!X.isDisposed())
部分)Thread.sleep()
阻止了用户界面。第2点会导致您的应用在显示进度条时无法响应用户互动,例如用户无法再关注窗口。
另请注意,(至少对于您目前为止的代码而言)Dialog
并非必要。我附上了一个代码示例,展示了如何做两件事:
Display#timerExec(int, Runnable)
的
protected ProgressBar bar;
protected Shell shell;
public ProgressBox(Shell parent, final String name)
{
this.shell = new Shell(parent, SWT.APPLICATION_MODAL | SWT.TITLE);
shell.setLayout(new FillLayout());
bar = new ProgressBar(shell, SWT.SMOOTH);
shell.setText(name);
shell.pack();
shell.open();
}
public void open()
{
final int max = 10;
this.bar.setMaximum(max);
new Thread(new Runnable()
{
@Override
public void run()
{
for (int i = 1; i <= max; i++)
{
if (bar == null || bar.isDisposed())
{
closeShell();
return;
}
else
{
final int index = i;
shell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
bar.setSelection(index);
}
});
}
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
closeShell();
e.printStackTrace();
}
}
closeShell();
}
private void closeShell()
{
shell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
shell.close();
}
});
}
}).start();
}
public static void main(String[] args)
{
Display display = Display.getDefault();
Shell shell = new Shell();
shell.setSize(450, 300);
shell.open();
new ProgressBox(shell, "Progress").open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
}