我通过使用Executor玩SwingWorker的多线程,我在那里错误地从Vector中识别出错误的元素,看起来像这个代码相当忽略了Vector中的元素不存在
我的问题 - >如何/有可能以某种方式捕获此异常
简单的输出
run:
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
BUILD SUCCESSFUL (total time: 11 seconds)
Run Code Online (Sandbox Code Playgroud)
通过取消注释
//changeTableValues1(); // un-comment for get ArrayIndexOutOfBoundsException
Run Code Online (Sandbox Code Playgroud)
一切都正确,我得到ArrayIndexOutOfBoundsException并输出
run:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: …Run Code Online (Sandbox Code Playgroud) 实现java.awt.event.ActionListener界面的最佳方法是什么?
让您的类实现ActionListener并将其添加为ActionListener:
class Foo implements ActionListener{
public Foo() {
JButton button = new JButton();
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
}
}
Run Code Online (Sandbox Code Playgroud)
或者添加匿名ActionListener类的对象:
class Foo{
public Foo() {
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
}
}
Run Code Online (Sandbox Code Playgroud) 我有两个SwingWorker类:FileLineCounterThread和FileDivisionThread
我将执行两个线程.当计数线程完成时,它会将结果传递给File Division线程.
我不知道如何将结果传递给已启动的线程.
我已经知道Event Dispatch线程是如何工作的.如果事件调度线程中存在短事件和长事件,则应用程序无法响应.
对于Swing中的响应性,Event Dispatch线程仅应用于短事件.而应该在SwingWorkers上执行长事件.
想象一下,有很多短暂的事件.
事件应该在Event Dispatch线程中执行,并且您有一个特殊事件,您希望在Event Dispatch Thread队列中存在的其他事件之前执行该事件.但是,默认情况下,事件将排队到队列的末尾,甚至也InvokeLater会这样做.
那么,是否有任何解决方案将事件排入事件调度线程的开头?
我正在使用这个练习作为教学工具来帮助我学习一些Java GUI编程概念.我正在寻找的是一般性的理解,而不是一个特定问题的详细解决方案.我希望编码这个"正确"将教会我如何处理未来的多线程问题.如果这对于这个论坛来说太笼统了,那么它可能属于程序员吗?
我正在模拟读卡器.它有一个GUI,允许我们将卡加载到料斗中并按下Start等,但它的主要"客户端"是CPU,在单独的线程上运行并请求卡.
读卡器保持单个缓冲区.如果卡片请求进入且缓冲区为空,读卡器必须从料斗读取卡片(需要1/4秒,这是1962年).在将卡读入缓冲区后,读卡器将缓冲区发送到CPU,并在下一个请求之前立即启动另一个缓冲区加载操作.
如果不仅缓冲器是空的,而且料斗中没有卡,那么我们必须等到操作员将料斗放入料斗并按下Start(它始终启动缓冲加载操作).
在我的实现中,卡请求以invokeLater() Runnables在EDT上排队的形式发送到读卡器.在myRunnable.run()时间,无论是一个缓冲器将可用(在这种情况下,我们可以将其发送到CPU和开球另一个缓冲器负载操作),或缓冲区将是空的.如果它是空的怎么办?
两种可能性:(a)飞行中已经有缓冲加载操作,或(b)卡漏斗是空的(或尚未启动).在任何一种情况下,让EDT等待是不可接受的.工作(和等待)必须在后台线程上完成.
为了简单起见,我尝试生成一个SwingWorker来响应每个卡请求,而不管缓冲区的状态如何.伪代码是:
SwingWorker worker = new SwingWorker<Void, Void>() {
public Void doInBackground() throws Exception {
if (buffer.isEmpty()) {
/*
* fill() takes 1/4 second (simulated by Thread.sleep)
* or possibly minutes if we need to have another
* card deck mounted by operator.
*/
buffer.fill();
}
Card card = buffer.get(); // empties buffer
/*
* Send card to CPU
*/
CPU.sendMessage(card); // <== (A) put card in msg queue …Run Code Online (Sandbox Code Playgroud) 似乎当我实例化12个Swing Worker线程时,前六个开始完成它的任务,它完成AND然后最后六个开始并完成.我正在寻找的行为是所有12个线程同时开始工作并同时完成.
我有以下内容:
for (int i = 0; i < 12; i++ )
{
myTask m = new Mytask(i, START);
m.execute();
}
Run Code Online (Sandbox Code Playgroud)
myTask m将以0到100递增一个进度条,增量为25.我发现前六个线程开始递增的异常行为,它们以100结束,然后最后六个线程从0开始递增,然后结束.
是否存在可能具有的Swing Worker线程数量的限制因素?
我怎么写一个?
从评论到我的回复,以下是:
"我们过去所拥有的东西 - 小程序和应用程序 - 已不再可用."
反驳:
垃圾.它[一个Applet和应用程序]被称为混合,并且活得很好.如果您想澄清,请在单独的问题上询问.
我想问一下这个Java Hybrid是什么?
我搜索过但由于某种原因找不到任何有用的信息,因为这些信息"活得很好".我使用的关键字可能稍微偏离,这可能是一个原因.
我有一个Gui应用程序,可以在串行热敏打印机上打印票据.当我点击启动此操作的按钮时,我的GUI被冻结.我认为那是因为代码是在EDT上执行的.我使用jstack确定但我不理解下面的结果:
Full thread dump Java HotSpot(TM) Client VM (23.3-b01 mixed mode, sharing):
"Thread-12" prio=6 tid=0x03012000 nid=0xd04 runnable [0x038ef000]
java.lang.Thread.State: RUNNABLE
at gnu.io.RXTXPort.eventLoop(Native Method)
at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)
"Thread-6" prio=6 tid=0x0302c400 nid=0x1b0 waiting on condition [0x039ef000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at posO2.Threads.ThreadHorloge.run(ThreadHorloge.java:46)
"Thread-5" prio=6 tid=0x03511c00 nid=0x9e4 waiting on condition [0x0399f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at posO2.Threads.ThreadIgor.run(ThreadIgor.java:29)
"Thread-7" prio=6 tid=0x034b9800 nid=0xb40 waiting on condition [0x0394f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at posO2.Threads.ThreadHorloge.run(ThreadHorloge.java:46)
at java.lang.Thread.run(Unknown Source)
"Thread-4" prio=6 tid=0x0318ec00 nid=0xa08 …Run Code Online (Sandbox Code Playgroud) 问题:在运行方法之前,图形不会重新绘制.
单击按钮时会调用两个方法.每个方法内部都是代码,用于更改与此方法关联的图形的颜色(在UI中); 当方法开始时,图形从黑色变为绿色; 当方法完成时,颜色从绿色变为红色.然后调用下一个方法,其图形应变为绿色(方法正在运行),当方法完成时,其图形应填充红色(方法完成).
我创建了一个简单的状态圆图形(带有填充颜色的30像素圆圈),有3种颜色状态:黑色表示准备好; 绿色的跑步; 红色完成.
我认为这个问题与repaint()单独的线程有关并且计划在能够运行时运行?我尝试将更新图形的代码放在自己的thread-runnable中,然后使用线程.join()确保代码已经完成运行但是没有用.
编辑:删除我用于演示的代码,并根据注释替换单个可运行的代码示例.如果运行代码,您将看到的是在单击每个方法启动和停止时图形不更新的按钮后,它会等待两个方法都运行然后重新绘制图形.
package graphicsUpdateDemo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.beans.Transient;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* Application entry
*/
public class App{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame();
}
}); …Run Code Online (Sandbox Code Playgroud) 我有一个按钮执行一个很长的功能,我想在用户点击它之后禁用此按钮,以防止他多次再次点击它
该按钮被禁用,但问题是在功能完成后按钮再次启用
我试图放入button.setEnabled(false);一个新的线程,但它没有工作
用于测试此代码示例
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
button.setEnabled(false);
for (int i = 0; i < Integer.MAX_VALUE; i++) {
for (int j = 0; j < Integer.MAX_VALUE; j++) {
for (int ii = 0; ii < Integer.MAX_VALUE; ii++) {
}
}
}
}
});
Run Code Online (Sandbox Code Playgroud) 我有SwingWorker如下:
public class MainWorker extends SwingWorker(Void, MyObject) {
:
:
}
Run Code Online (Sandbox Code Playgroud)
我Swing Worker从EDT 调用了上述内容:
MainWorker mainWorker = new MainWorker();
mainWorker.execute();
Run Code Online (Sandbox Code Playgroud)
现在,mainWorker创建一个MyTask类的10个实例,以便每个实例都在自己的线程上运行,以便更快地完成工作.
但问题是我想在任务运行时不时更新gui.我知道如果任务是由mainWorker自己执行的,我可以使用publish()和process()方法来更新gui.
但是由于任务是由与线程不同的Swingworker线程执行的,我如何从执行任务的线程生成的中间结果更新gui.
问题已解决!!!!!! 非常感谢trashgod和HoverCraftFullOfEels!我终于通过使用下面的例子并略微改变它来获得这个概念.更改允许缩放进度条(默认为100个单位).再次感谢您的耐心和愿意为此而努力.意味着很多人,~Kyte
ps - + 1全部'围绕:)
/** @see http://stackoverflow.com/questions/4637215 */
public class Threading_01 extends JFrame {
private static final String s = "0.00";
private JProgressBar progressBar = new JProgressBar(0, 100);
private JLabel label = new JLabel(s, JLabel.CENTER);
public Threading_01() {
this.setLayout(new GridLayout(0, 1));
this.setTitle("?2");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(progressBar);
this.add(label);
this.setSize(161, 100);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void runCalc() {
// progressBar.setIndeterminate(true);
TwoWorker task = new TwoWorker();
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if ("progress".equals(e.getPropertyName())) {
progressBar.setIndeterminate(false);
progressBar.setValue((Integer) e.getNewValue());
System.out.println("**: " …Run Code Online (Sandbox Code Playgroud) 我想要一个在不同线程中运行2个或更多方法的方法.我想确保在完成所有线程之前该方法不会完成.
java ×13
swing ×10
swingworker ×6
concurrency ×2
applet ×1
buffering ×1
function ×1
graphics ×1
jbutton ×1
jpanel ×1
jprogressbar ×1
jstack ×1
repaint ×1
vector ×1