我正在尝试播放幻灯片,gif等。我列出了从文件夹中读取的图像,并使它们成为在 SWT 对话框中显示的序列。现在我遇到线程访问问题。在SWT中制作幻灯片的方式是什么?感谢任何建议和纠正。
这是实施:
public class ImageShowDialog extends Dialog {
Shell dialog;
private Label labelImage;
private Canvas canvas;
int numberImage = 0;
private volatile boolean running = true;
ImageShowDialog(Shell parent) {
super(parent);
}
public String open() {
Shell parent = getParent();
dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
dialog.setSize(600, 400);
dialog.setText("Show Begins!!!");
dialog.setLayout(new FillLayout());
this.func();
dialog.open();
Display display = parent.getDisplay();
while (!dialog.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return "After Dialog";
}
public void func() {
final List<byte[]> imageCollection = new ArrayList<byte[]>();
File path = new File("..\\folder");
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) { // this line weeds out other
// directories/folders
try {
imageCollection.add(loadImage(files[i]));
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
new Thread(new Runnable() {
@Override
public void run() {
while (running) {
ImageData imageData = new ImageData(
new ByteArrayInputStream(
imageCollection.get(numberImage)));
final Image image = new Image(Display.getDefault(),
imageData);
canvas = new Canvas(dialog, SWT.NONE);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setAlpha(255);
e.gc.drawImage(image, 0, 0);
}
});
numberImage++;
if (numberImage == imageCollection.size())
try {
running = false;
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public byte[] loadImage(File file) throws IOException {
BufferedImage image = ImageIO.read(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", bos);
return bos.toByteArray();
}
和例外:
Exception in thread "Thread-45" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:4282)
at org.eclipse.swt.SWT.error(SWT.java:4197)
at org.eclipse.swt.SWT.error(SWT.java:4168)
at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:359)
at org.eclipse.swt.widgets.Widget.checkParent(Widget.java:279)
at org.eclipse.swt.widgets.Widget.<init>(Widget.java:149)
at org.eclipse.swt.widgets.Control.<init>(Control.java:110)
at org.eclipse.swt.widgets.Scrollable.<init>(Scrollable.java:75)
at org.eclipse.swt.widgets.Composite.<init>(Composite.java:95)
at org.eclipse.swt.widgets.Canvas.<init>(Canvas.java:79)
答案 0 :(得分:1)
您只能在主UI线程中创建和访问SWT控件,任何在其他线程中执行此操作的尝试都将使“无效线程访问”无法访问。你得到的错误。
您可以在后台线程中使用asyncExec
或syncExec
方法在主线程中运行代码:
Display
(使用lambda的Java 8/9代码,对旧Java使用Display.getDefault().asyncExec(() ->
{
... code accessing the UI
});
。)
Runnable
以异步方式运行代码,asyncExec
等待UI线程在返回之前运行代码。
答案 1 :(得分:1)
SWT是单线程的,正如Riduidel在本文中所述:Updating SWT objects from another thread
所以,不要做你做的事,试试下面的事情:
SELECT f.userId, f.following, p.postId, p.content, p.file, p.type
FROM follow f
JOIN post p ON p.userId = f.userId
WHERE f.userId = '$userId'
LIMIT 0 , 30