SWT application crashes in Windows 7
I have a java SWT application that works OK with Windows XP and Windows Vista. But when I run it on Windows 7, weird errors occure, and it crashes.
For example, in a method where I call Table.removeAll()
I get a java.lang.ArrayIndexOutOfBoundsException: 0
. The table has SWT.VIRTUAL
in style.
Another problem is when I write something in a text box (there's a ModifyListener which filters something) - after 2 characters, the cursor moves at the beginning (before first character).
The SWT version is 3.5, but I tried with the latest from the eclipse website(3.6M3) and the result is the same.
Are there any known issues? Has anybody encountered this?
Here is a snippet that doesn't work in Windows 7:
import java.util.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class TableCheck {
Shell shell;
Button button1, button2, button3;
UltraTable ut;
public TableCheck() {
Display display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout(4, false));
Text text = new Text(shell, SWT.SINGLE | SWT.LEAD | SWT.READ_ONLY | SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
text.setText("SWT " + SWT.getPlatform() + " " + SWT.getVersion() + "; "
+ System.getProperty("os.name") + " " + System.getProperty("os.version") + " "
+ System.getProperty("os.arch"));
SelectionAdapter listener = new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (e.widget == button1) {
ut.setContent(Arrays.asList("01", "34", "test", "test2", "123", "1test", "test2"));
} else if (e.widget == button2) {
ut.setContent(Arrays.asList("Str1", "Str2", "Str3"));
} else {
ut.setContent(Collections.emptyList());
}
}
};
button1 = new Button(shell, SWT.PUSH);
button1.setText("Data 1");
button1.addSelectionListener(listener);
button2 = new Button(shell, SWT.PUSH);
button2.setText("Data 2");
button2.addSelectionListener(listener);
button3 = new Button(shell, SWT.PUSH);
button3.setText("Data 3");
button3.addSelectionListener(listener);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1);
gd.widthHint = gd.heightHint = 320;
ut = new UltraTable(shell, SWT.MULTI | SWT.BORDER | SWT.VIRTUAL | SWT.FULL_SELECTION);
ut.table.setLayoutData(gd);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
class UltraTable {
private Table table;
private static final String DATA_COLLECTION = "<<CC>>", DATA_LISTENER = "<<VL>>";
public UltraTable(Composite parent, int style) {
table = new Table(parent, style);
table.setLinesVisible(true);
table.setHeaderVisible(true);
TableColumn tableColumn = new TableColumn(table, SWT.NONE);
tableColumn.setText("Column");
tableColumn.setWidth(64);
}
void setContent(Collection<?> collection) {
if ((table.getStyle() & SWT.VIRTUAL) != 0) {
table.setData(DATA_COLLECTION, collection);
开发者_运维知识库table.clearAll();
table.setItemCount(collection.size());
if (table.getData(DATA_LISTENER) == null) {
Listener listenerSD = new Listener() {
public void handleEvent(Event event) {
Collection<?> collectionW = (Collection<?>) event.widget.getData(DATA_COLLECTION);
Object object = collectionW.toArray(new Object[collectionW.size()])[event.index];
((TableItem) event.item).setText(0, object.toString());
}
};
table.setData(DATA_LISTENER, listenerSD);
table.addListener(SWT.SetData, listenerSD);
}
}
}
}
public static void main(String[] args) {
new TableCheck();
}
}
The SWT versions I checked is (as shown in the text in the shell):
SWT win32 3550; Windows 7 6.1 x86
SWT win32 3617; Windows 7 6.1 x86
I have resolved this problem after asking the same question.
You must either remove SWT.VIRTUAL
or update to the SVN build of SWT. I've posted a bug report on the SWT bug page.
Edit: your code snippet has a bug in it that is causing the ArrayIndexOutOfBoundsException
. You can resolve it by changing lines containing listenerSD
:
public void handleEvent(Event event) {
Collection<?> collectionW = (Collection<?>) event.widget
.getData(DATA_COLLECTION);
if (collectionW.size() > event.index) {
Object object = collectionW
.toArray(new Object[collectionW.size()])[event.index];
((TableItem) event.item).setText(0, object
.toString());
}
}
On Windows 7, the table updates the visible items immediately when clearAll()
is called. So
table.clearAll();
must be after the line
table.setItemCount(collection.size());
精彩评论