Я знаю, что многие люди испытывают эту проблему, но решения, которые я нашел в Интернете, похоже, не решают мою проблему. У меня есть композит, который имеет три кнопки. Я хочу следующее: Когда я нажимаю одну кнопку, я хочу, чтобы какая-то другая кнопка была выделена серым цветом (setEnabled (false)), и через некоторое время (после выполнения метода) я хочу, чтобы кнопка была снова включена.SWT update/redraw/layout prοblem
Многие из таких проблем решаются путем вызова метода layout() в родительском контейнере, или this very similar one решается путем вызова Display.getCurrent(). Update();
Просто, мой код можно резюмировать следующим образом:
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
public class app1 {
protected Shell shell;
/**
* Launch the application.
* @param args
*/
public static void main(String[] args) {
try {
app1 window = new app1();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
Button button1 , button2 , button3;
Label label;
protected void createContents() {
shell = new Shell();
shell.setSize(450, 300);
shell.setText("SWT Application");
shell.setLayout(new GridLayout(1,false));
{
final Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new GridLayout(3,false));
GridData gd_composite = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
gd_composite.grabExcessHorizontalSpace = true;
gd_composite.horizontalSpan = 10; //?
gd_composite.verticalIndent = 5;
composite.setLayoutData(gd_composite);
GridData gd_button;
{
button1 = new Button(composite, SWT.NONE);
button1.setText("Button 1");
gd_button = new GridData(SWT.FILL, GridData.BEGINNING, false, false);
gd_button.horizontalSpan = 1;
button1.setLayoutData(gd_button);
button1.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e){
try{
button2.setEnabled(false);
button2.redraw();
button2.update();
//composite.redraw();
//composite.update();
//composite.layout();
shell.redraw();
shell.update();
shell.layout();
Display.getCurrent().update();
} catch (Exception e2) {
System.err.println("exception e : " + e2.toString());
}
System.out.println("basla");
try {
System.out.println("sleep1");
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (Throwable th) {
System.err.println("th: " + th.toString());
}
try {
System.out.println("sleep2");
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (Throwable th) {
System.err.println("th: " + th.toString());
}
try {
System.out.println("sleep3");
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (Throwable th) {
System.err.println("th: " + th.toString());
}
for(int i=0 ; i < 10000 ; i++)
{
System.out.println(i);
}
}
public void widgetDefaultSelected(SelectionEvent e) {
System.err.println("widgetDefault !");
}
});
}
{
button2 = new Button(composite, SWT.NONE);
button2.setText("Button 2");
gd_button = new GridData(SWT.FILL, GridData.CENTER, false, false);
gd_button.horizontalSpan = 1;
button2.setLayoutData(gd_button);
button2.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e){
button1.setEnabled(false);
composite.layout();
for (int i=1; i<=100; i++) {
try {
Thread.sleep(10);
} catch (Throwable th) {}
label.setText(i + " %");
label.update();
}
}
public void widgetDefaultSelected(SelectionEvent e) {}
});
}
{
label = new Label(composite , SWT.NONE);
label.setText("0 %");
label.update();
}
}
}
}
Что происходит, кнопка становится инвалидом после окончания метода widgetSelected() достигается. Тем не менее, ярлык часто обновляется без каких-либо проблем (даже если метода label.update() нет)
Дополнительная информация: Скажем, я отключил кнопку, а затем поместил Thread.sleep(), а затем включил кнопка; он сначала спит, а затем быстро отключает и включает кнопку. Поэтому я считаю, что все такие запросы краски поставлены в очередь и обрабатываются в конце выполнения.
Полезная информация: Я понял, что, когда я создаю и показываю MessageBox сразу после изменения моего дисплея, происходят изменения дисплея. Так что, если я делаю следующее изменение в моем методе widgetSelected:
button2.setEnabled(false)
MessageBox mBox = new MessageBox(Display.getCurrent().getActiveShell(), SWT.ICON_INFORMATION | SWT.OK);
mBox.setText("Information");
mBox.setMessage("Buttons updated!");
mBox.open();
кнопка будет недоступна, как только метод widgetSelected() вызывается. Это заставляет меня полагать, что мое решение лежит в методах Display.getCurrent(). Тем не менее, я пробовал
Display.getCurrent().getActiveShell().redraw() Display.getCurrent().getActiveShell().update() Display.getCurrent().getActiveShell().layout()
методов, и они не решили мою проблему.
Спасибо, Эге
Большое спасибо, он работает. Тем не менее, я все еще не мог получить ваше объяснение на 100%. Я знаю, что выполнение SWT-действий в потоке, отличном от SWT-потока, невозможно. Когда я пишу SelectionAdapter, то сначала отключает все кнопки , затем выполняет спящий режим (в том же потоке, не создавая новый поток) , а затем включает все кнопки , что показывает неопределенное поведение. Иногда он отключает третью кнопку, спит, а затем включает все. Иногда он отключает вторую кнопку, спит, а затем включает в себя все и т. Д. Не могли бы вы объяснить мне это неопределенное поведение? Еще раз спасибо. – 2009-09-16 22:32:38