好吧,这个真的很奇怪.每次我的应用程序第一次打开JFileChooser时,它都会抛出IOException,然后某些图标无法正常显示.
java.io.IOException
at sun.awt.image.GifImageDecoder.readHeader(GifImageDecoder.java:265)
at sun.awt.image.GifImageDecoder.produceImage(GifImageDecoder.java:102)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:246)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
Run Code Online (Sandbox Code Playgroud)
现在,当我深入研究错误时,它似乎在尝试读取标题时在一个图标上,它只检索前8个字节,这是不够的.我已经检查了图标文件,它们似乎都没问题.我试图用另一个在此错误之前正确加载的图标文件覆盖图标文件,但同样的事情.
打破这个错误时,这是我的堆栈:
Daemon Thread [Image Fetcher 0] (Suspended (exception IOException))
GifImageDecoder.readHeader() line: 265 [local variables unavailable]
GifImageDecoder.produceImage() line: 102 [local variables unavailable]
ByteArrayImageSource(InputStreamImageSource).doFetch() line: 246
ImageFetcher.fetchloop() line: 172
ImageFetcher.run() line: 136 [local variables unavailable]
Run Code Online (Sandbox Code Playgroud)
这是挖掘GifImageDecoder实例时的变量值.
source ByteArrayImageSource (id=272)
awaitingFetch false
consumers null
decoder GifImageDecoder (id=271)
decoders GifImageDecoder (id=271)
imagedata (id=307)
[0] 71
[1] 73
[2] 70
[3] 56
[4] 57
[5] 97
[6] 16
[7] 13
[8] 10 …Run Code Online (Sandbox Code Playgroud) 可能这是微不足道的,我很难理解SwingWorker上的简单文档.
这是复制粘贴的内容
工作流程
SwingWorker的生命周期涉及三个线程:
当前线程:在此线程上调用execute()方法.它安排SwingWorker在工作线程上执行并立即返回.可以等待SwingWorker使用get方法完成.
工作线程:在此线程上调用doInBackground()方法.这是所有背景活动应该发生的地方.要通知PropertyChangeListeners有关绑定属性的更改,请使用firePropertyChange和getPropertyChangeSupport()方法.默认情况下,有两个绑定属性:状态和进度.
事件调度线程:此线程上发生所有与Swing相关的活动.SwingWorker调用process和done()方法并通知此线程上的任何PropertyChangeListeners.
通常,Current线程是Event Dispatch Thread.
-
工作线程不是EDT,因此doInBackground()中的代码不能访问GUI元素.我的理解是否正确?
背景:我们有使用SwingWorker的小代码,但有doInBackground()创建FileChooser并调用setCurrentDirectory().我怀疑这导致我异常几乎与 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6637181(11-Closed,not a defect)相同
我对签名感到困惑SwingUtilities.invokeLater.它需要一个Runnable对象.这个Runnable对象是否被移交给Event Dispatch Thread?为什么我不能直接调用createAndShowGUI的run方法EDT(如果可能的话)?
我已经阅读过有关EDT和invokeLater如何工作的文章,但我对Runnable传递的对象感到困惑.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
Run Code Online (Sandbox Code Playgroud)
如果我在电话SwingUtilities.invokeLater下面再次打电话会怎么样?
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run() {
doSomethingOnTopOfGUI();
}
});
Run Code Online (Sandbox Code Playgroud) 我试图看看今天早些时候是否可以回答这个问题.我意识到我并不完全理解Event Dispatch Thread(EDT).谷歌搜索确认并帮助了这一点,并澄清了为什么我没有.(这也可能与理解有关.)
代码设置GUI,稍后(如前面的问题中所述)更新文本字段,直到取消设置标志.
我有几个问题/要求.
请解释为什么如果两个调用(to swingInit和doIt)都在invokeLater块之外(如图所示),下面的代码运行正常,因为这两个调用都影响或查询GUI但是它们都没有在EDT上执行(是吗?).这不是诱人的失败吗?
如果呼叫在swingInit内部和doIt外部,代码也会运行invokeLater.所以swingInit在EDT上执行,但不应该doIt在EDT上执行是一个问题吗?(我觉得这很有效.我应该去过吗?)
我想我明白为什么它会挂起,如果doIt它在里面invokeLater而不管它在哪里swingInit:目的invokeLater只是初始化 GUI(对吧?).
如果doIt只启动(可能发生的事件)在美国东部时间,但肯定不是里面invokeLater块?
(EDT概念的历史很有意思.它并不总是如此.请参阅上面的链接"我为什么不"理解它.)
import static java.awt.EventQueue.invokeLater;
import java.awt.event.*;
import javax.swing.*;
public class Whatever
{
static boolean flag = true;
static JTextField tf = new JTextField("Hi",20);
static JPanel …Run Code Online (Sandbox Code Playgroud) 我有一个简单的groovy脚本,从它的主要执行线程需要向用户显示一些对话框.
我的挥杆知识是有限的和生锈的,但我记得读到需要小心保持事件派发线程(EDT)上的GUI东西.
如果我只是JOptionPane.showMessageDialog从我的主线程中调用静态方法我是否正确地假设这会违反在EDT上保留GUI内容的正确做法?
我应该实际使用swing.utils.invokeAndWait方法,例如在下面的示例代码中?
void showHelloThereDialog()
throws Exception {
Runnable showModalDialog = new
Runnable() {
public void run() {
JOptionPane.showMessageDialog(
myMainFrame, "Hello There");
}
};
SwingUtilities.invokeAndWait
(showModalDialog);
}
Run Code Online (Sandbox Code Playgroud)
现在,上面没有做任何事情来在invokeAndWait完成后从消息对话框以外的其他内容中创建值.
据推测,groovy'闭包'实现Runnable将使代码比上面更简单.
需要invokeAndWait吗?如果是这样,有人请举一个正确实现的例子,以获得像使用groovy的confirmDialog之类的结果?
我是Java Swing的新手,我的问题与Event Queues和Dispatch threads有关.
我读到每个AppContext实例可以有多个事件队列.同样,这意味着每个AppContext事件队列都有自己的事件派发线程.
我有一个JComboBox,其值通过网络检索.
我正在寻找一种向用户指示该事实的方法,当用户想要查看列表时,展开下拉列表,然后才检索数据.
基本要求包括:
请注意,在用户想要查看组合的值(即展开下拉列表)之前,不会检索数据.
我使用了一个SwingWorker来保持UI响应.组合框使用JIDE's覆盖Overlayable,JIDE InfiniteProgressPanel聆听工作人员.
我正在开发一个应用程序,其中在ASINetworkQueue中添加了许多操作.操作基本上用于从服务器获取图像,然后成功完成在表视图单元格中设置图像.
一切都很好.我有一个按钮,一个表视图单元格,另一个视图控制器打开.
在另一个视图上有一个十字按钮,我可以在其上弹出该视图控制器.现在,当单击交叉按钮时,应用程序会在那里崩溃,有时当返回到上一个视图并滚动我的表视图时它会崩溃.
当我看到崩溃日志时,我发现无论线程崩溃,下面的代码都会出现.有时它是崩溃的thread2,有时它是崩溃的线程12,有时它是崩溃的线程6但是该线程内的代码是相同的,如下所示.
Thread 11 name: Dispatch queue: com.apple.root.default-overcommit-priority
Thread 11 Crashed:
0 Foundation 0x357320b2 0x3569e000 + 606386
1 Foundation 0x356add56 0x3569e000 + 64854
2 Foundation 0x356adb94 0x3569e000 + 64404
3 Foundation 0x35731f48 0x3569e000 + 606024
4 Foundation 0x356add56 0x3569e000 + 64854
5 Foundation 0x356adb94 0x3569e000 + 64404
6 Foundation 0x35731ebc 0x3569e000 + 605884
7 libdispatch.dylib 0x3698c9f6 0x36981000 + 47606
8 libdispatch.dylib 0x3698f21e 0x36981000 + 57886
9 libdispatch.dylib 0x3698cb70 0x36981000 + 47984
10 libdispatch.dylib 0x3698d76c 0x36981000 + 51052
11 …Run Code Online (Sandbox Code Playgroud) objective-c crash-reports asihttprequest event-dispatch-thread ios
我有一个SwingWorker类,如下所示:
class RemotePlayersWorker extends SwingWorker<String[][], Object> {
PlayerCanvas parent;
RemoteHandler remote;
String[][] players;
int maximumConnections;
public RemotePlayersWorker(PlayerCanvas parentCanvas, RemoteHandler remoteHandle) {
this.parent = parentCanvas;
this.remote = remoteHandle;
}
@Override
protected String[][] doInBackground() throws Exception {
System.out.println("TEST 1");
players = remote.getConnectedPlayers();
publish(players);
return players;
}
@Override
protected void process(List<String[][]> chunks) {
for (String[][] chunk : chunks) {
// no need for the c variable
System.out.println(chunk.toString());
}
}
@Override
protected void done() {
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我在覆盖进程(List chunks)方法时遇到错误.Eclipse告诉我这个:
The method process(List) of type …Run Code Online (Sandbox Code Playgroud) 我制作了很多不同的 Swing 应用程序,它们的加载时间通常在几秒到几分钟之间变化,具体取决于应用程序 UI/数据大小。此外,在某些情况下,应用程序数据加载与 UI 加载混合。
几秒钟的加载时间不是问题,但是当它超过 10 秒时 - 很明显应该显示某种加载屏幕,直到 UI/数据完全初始化。
您通常会做什么 - 首先创建某种加载屏幕(例如,带有徽标的窗口和一些在应用程序加载时正在更新的标签),然后从应用程序中的各种加载“点”更新它。
问题是 - 应用程序通常在排队进入 EDT 的单个调用中加载,并且很难将其分成对 EDT 的多次调用而不会使应用程序的代码复杂化。因此,由于应用程序加载是在排队到 EDT 的单个调用中执行的,因此您根本无法正确更新加载屏幕 - 由于 EDT 忙于加载应用程序,因此在应用程序初始化之前不会显示更新。
因此,为了在某些情况下实现加载屏幕,我已将应用程序 UI 初始化移到 EDT 之外,并将它们设计为在执行加载时不会执行任何 UI 更新内容。应用程序的框架显示和所有应用程序 UI 操作仍将在 EDT 中执行。这通常不太好,但经过大量测试和查看 Swing 代码后,我确信即使在大型应用程序中它也不会导致任何问题。尽管如此,即使它不会引起任何问题,这通常也不是一件好事。
所以问题是:在 EDT 中保持应用程序初始化的同时,可以使用哪些方法来正确显示和更新应用程序加载屏幕?
希望它不是太宽泛。
这是一个展示“坏”方法的“虚拟”应用程序:
import javax.swing.*;
import java.awt.*;
public class DummyApplication extends JFrame
{
private static JDialog loadingDialog;
private static JLabel loadingProgress;
public DummyApplication ()
{
super ( "Dummy application" );
dummyProgressUpdate ( "Loading content...", 3000 ); …Run Code Online (Sandbox Code Playgroud) java ×9
swing ×8
awt ×2
swingworker ×2
exception ×1
groovy ×1
invokelater ×1
ios ×1
jcombobox ×1
jfilechooser ×1
jide ×1
objective-c ×1