Что я пытаюсь сделать?
По щелчку Start JButton
будет выполняться SwingWorker
. Внутри метода doInBackground()
я передаю каждый индекс arrNames
методу publish()
, чтобы его можно было отобразить внутри JTextArea
.
Что случилось?
Если я не оставлю строку System.out.format("Counter : %d%n", counter);
в качестве комментария в моем методе doInBackground()
метода SwingWorker
, тогда SwingWorker
работает, как ожидалось. Хотя если я закомментирую, то SwingWorker
перестанет отвечать.
Я делаю что-то не так?
Версия Java:
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b16)
Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode, sharing)
Вот код, который я использую:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SwingWorkerExample1
{
private JLabel statusLabel;
private JTextArea tArea;
private JButton startButton;
private JButton stopButton;
private BackgroundTask backgroundTask;
private ActionListener buttonActions =
new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
JButton source = (JButton) ae.getSource();
if (source == startButton)
{
startButton.setEnabled(false);
stopButton.setEnabled(true);
backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
else if (source == stopButton)
{
backgroundTask.cancel(true);
stopButton.setEnabled(false);
startButton.setEnabled(true);
}
}
};
private void displayGUI()
{
JFrame frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(5, 5));
statusLabel = new JLabel("Status Bar", JLabel.CENTER);
tArea = new JTextArea(20, 20);
tArea.setWrapStyleWord(true);
tArea.setLineWrap(true);
JScrollPane textScroller = new JScrollPane();
textScroller.setBorder(
BorderFactory.createTitledBorder("Textual OUTPUT : "));
textScroller.setViewportView(tArea);
startButton = new JButton("Start");
startButton.addActionListener(buttonActions);
stopButton = new JButton("Stop");
stopButton.setEnabled(false);
stopButton.addActionListener(buttonActions);
JPanel buttonPanel = new JPanel();
buttonPanel.add(startButton);
buttonPanel.add(stopButton);
contentPane.add(statusLabel, BorderLayout.PAGE_START);
contentPane.add(textScroller, BorderLayout.CENTER);
contentPane.add(buttonPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private class BackgroundTask extends SwingWorker<Void, String>
{
private int counter = 0;
private String[] arrNames = { "US Rates Strategy Cash",
"Pavan Wadhwa(1-212) 844-4597", "Srini Ramaswamy(1-212) 844-4983",
"Meera Chandan(1-212) 855-4555", "Kimberly Harano(1-212) 823-4996",
"Feng Deng(1-212) 855-2555", "US Rates Strategy Derivatives",
"Srini Ramaswamy(1-212) 811-4999",
"Alberto Iglesias(1-212) 898-5442",
"Praveen Korapaty(1-212) 812-3444", "Feng Deng(1-212) 812-2456",
"US Rates Strategy Derivatives", "Srini Ramaswamy(1-212) 822-4999",
"Alberto Iglesias(1-212) 822-5098",
"Praveen Korapaty(1-212) 812-3655", "Feng Deng(1-212) 899-2222" };
public BackgroundTask()
{
statusLabel.setText((this.getState()).toString());
System.out.println(this.getState());
}
@Override
protected Void doInBackground()
{
statusLabel.setText((this.getState()).toString());
System.out.println(this.getState());
while (!isCancelled())
{
counter %= arrNames.length;
//System.out.format("Counter : %d%n", counter);
publish(arrNames[counter]);
counter++;
}
statusLabel.setText((this.getState()).toString());
System.out.println(this.getState());
return null;
}
@Override
protected void process(java.util.List<String> messages)
{
for (String message : messages)
tArea.append(String.format(message + "%n"));
}
}
public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
new SwingWorkerExample1().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
ИЗМЕНИТЬ 1:
Как было предложено, если я добавлю Thread.sleep(...)
, это действительно сработает, но выдаст InterruptedException
, как показано ниже. Так что трюк работает. Но является ли это законным способом?
C:\Mine\JAVA\J2SE\classes>java SwingWorkerExample1
PENDING
STARTED
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at SwingWorkerExample1$BackgroundTask.doInBackground(SwingWorkerExample1.java:108)
at SwingWorkerExample1$BackgroundTask.doInBackground(SwingWorkerExample1.java:76)
at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at javax.swing.SwingWorker.run(SwingWorker.java:335)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
DONE
ИЗМЕНИТЬ 2:
Изменено только doInBackground()
, что вызвало указанное выше исключение:
@Override
protected Void doInBackground()
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
statusLabel.setText((BackgroundTask.this.getState()).toString());
}
};
EventQueue.invokeLater(runnable);
System.out.println(this.getState());
while (!isCancelled())
{
counter %= arrNames.length;
//System.out.format("Counter : %d%n", counter);
publish(arrNames[counter]);
try
{Thread.sleep(30);}
catch(InterruptedException ie)
{ie.printStackTrace();}
counter++;
}
runnable = new Runnable()
{
@Override
public void run()
{
statusLabel.setText((BackgroundTask.this.getState()).toString());
}
};
EventQueue.invokeLater(runnable);
System.out.println(this.getState());
return null;
}
setText()
упоминается как связанный сJLabel
в моем вопросе :-) ХотяThread.sleep(...)
работает, но выдает InterruptedException, что снова вызывает опасения :( - person nIcE cOw   schedule 20.07.2013wait()
иnotify()
могут проделать этот трюк для меня, хотя мне просто интересно, как заставить его работать. Хотя он показывает мне одну строку, хотя мне нужно снова запуститьSwingWorker
, чтобы увидеть другую строку. Но этаwait()/notify()
стратегия действительно работает, все еще работает над ней, чтобы действительно найти выход :-) - person nIcE cOw   schedule 20.07.2013wait/notify
я надеялся реализовать какие-то методыgetter/setter
, так что, когдаvalue
установлен, поток возьмет его и уведомит другой, чтобы он поместил другое значение на его место, и наоборот -наоборот для другого потока, что-то в строках этого примера Sync.java . :-) - person nIcE cOw   schedule 20.07.2013Thread.sleep(1000)
. И при завершении ни один из них не выбрасывает никаких исключений, а здесь почти то же самое, хотя это исключение вызывается :( - person nIcE cOw   schedule 20.07.2013cancel(false)
сработала. Пожалуйста, опубликуйте этот комментарий в качестве ответа, я буду признателен за это :-) - person nIcE cOw   schedule 20.07.2013