14.11 스 레 드 와 Swing
import java.awt.*;
import java.util.*;
import javax.swing.*;
/**
* This program demonstrates that a thread that runs in parallel with the event
* dispatch thread can cause errors in Swing components.
* @version 1.24 2015-06-21
* @author Cay Horstmann
*/
public class SwingThreadTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(() -> {
JFrame frame = new SwingThreadFrame();
frame.setTitle("SwingThreadTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
/**
* This frame has two buttons to fill a combo box from a separate thread. The
* "Good" button uses the event queue, the "Bad" button modifies the combo box
* directly.
*/
class SwingThreadFrame extends JFrame
{
public SwingThreadFrame()
{
final JComboBox<Integer> combo = new JComboBox<>();
combo.insertItemAt(Integer.MAX_VALUE, 0);
combo.setPrototypeDisplayValue(combo.getItemAt(0));
combo.setSelectedIndex(0);
JPanel panel = new JPanel();
JButton goodButton = new JButton("Good");
goodButton.addActionListener(event ->
new Thread(new GoodWorkerRunnable(combo)).start());
panel.add(goodButton);
JButton badButton = new JButton("Bad");
badButton.addActionListener(event ->
new Thread(new BadWorkerRunnable(combo)).start());
panel.add(badButton);
panel.add(combo);
add(panel);
pack();
}
}
/**
* This runnable modifies a combo box by randomly adding and removing numbers.
* This can result in errors because the combo box methods are not synchronized
* and both the worker thread and the event dispatch thread access the combo
* box.
*/
class BadWorkerRunnable implements Runnable
{
private JComboBox<Integer> combo;
private Random generator;
public BadWorkerRunnable(JComboBox aCombo)
{
combo = aCombo;
generator = new Random();
}
public void run()
{
try
{
while (true)
{
int i = Math.abs(generator.nextInt());
if (i % 2 == 0)
combo.insertItemAt(i, 0);
else if (combo.getItemCount() > 0)
combo.removeItemAt(i % combo.getItemCount());
Thread.sleep(1);
}
}
catch (InterruptedException e)
{
}
}
}
/**
* This runnable modifies a combo box by randomly adding and removing numbers.
* In order to ensure that the combo box is not corrupted, the editing
* operations are forwarded to the event dispatch thread.
*/
class GoodWorkerRunnable implements Runnable
{
private JComboBox<Integer> combo;
private Random generator;
public GoodWorkerRunnable(JComboBox aCombo)
{
combo = aCombo;
generator = new Random();
}
public void run()
{
try
{
while (true)
{
EventQueue.invokeLater(() ->
{
int i = Math.abs(generator.nextInt());
if (i % 2 == 0)
combo.insertItemAt(i, 0);
else if (combo.getItemCount() > 0)
combo.removeItemAt(i % combo.getItemCount());
});
Thread.sleep(1);
}
}
catch (InterruptedException e)
{
}
}
}
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
import javax.swing.*;
/**
* This program demonstrates a worker thread that runs a potentially time-consuming task.
* @version 1.11 2015-06-21
* @author Cay Horstmann
*/
public class SwingWorkerTest
{
public static void main(String[] args) throws Exception
{
EventQueue.invokeLater(() -> {
JFrame frame = new SwingWorkerFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
/**
* This frame has a text area to show the contents of a text file, a menu to open a file and
* cancel the opening process, and a status line to show the file loading progress.
*/
class SwingWorkerFrame extends JFrame
{
private JFileChooser chooser;
private JTextArea textArea;
private JLabel statusLine;
private JMenuItem openItem;
private JMenuItem cancelItem;
private SwingWorker<StringBuilder, ProgressData> textReader;
public static final int TEXT_ROWS = 20;
public static final int TEXT_COLUMNS = 60;
public SwingWorkerFrame()
{
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
textArea = new JTextArea(TEXT_ROWS, TEXT_COLUMNS);
add(new JScrollPane(textArea));
statusLine = new JLabel(" ");
add(statusLine, BorderLayout.SOUTH);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu menu = new JMenu("File");
menuBar.add(menu);
openItem = new JMenuItem("Open");
menu.add(openItem);
openItem.addActionListener(event -> {
// show file chooser dialog
int result = chooser.showOpenDialog(null);
// if file selected, set it as icon of the label
if (result == JFileChooser.APPROVE_OPTION)
{
textArea.setText("");
openItem.setEnabled(false);
textReader = new TextReader(chooser.getSelectedFile());
textReader.execute();
cancelItem.setEnabled(true);
}
});
cancelItem = new JMenuItem("Cancel");
menu.add(cancelItem);
cancelItem.setEnabled(false);
cancelItem.addActionListener(event -> textReader.cancel(true));
pack();
}
private class ProgressData
{
public int number;
public String line;
}
private class TextReader extends SwingWorker<StringBuilder, ProgressData>
{
private File file;
private StringBuilder text = new StringBuilder();
public TextReader(File file)
{
this.file = file;
}
// The following method executes in the worker thread; it doesn't touch Swing components.
@Override
public StringBuilder doInBackground() throws IOException, InterruptedException
{
int lineNumber = 0;
try (Scanner in = new Scanner(new FileInputStream(file), "UTF-8"))
{
while (in.hasNextLine())
{
String line = in.nextLine();
lineNumber++;
text.append(line).append("
");
ProgressData data = new ProgressData();
data.number = lineNumber;
data.line = line;
publish(data);
Thread.sleep(1); // to test cancellation; no need to do this in your programs
}
}
return text;
}
// The following methods execute in the event dispatch thread.
@Override
public void process(List data)
{
if (isCancelled()) return;
StringBuilder b = new StringBuilder();
statusLine.setText("" + data.get(data.size() - 1).number);
for (ProgressData d : data) b.append(d.line).append("
");
textArea.append(b.toString());
}
@Override
public void done()
{
try
{
StringBuilder result = get();
textArea.setText(result.toString());
statusLine.setText("Done");
}
catch (InterruptedException ex)
{
}
catch (CancellationException ex)
{
textArea.setText("");
statusLine.setText("Cancelled");
}
catch (ExecutionException ex)
{
statusLine.setText("" + ex.getCause());
}
cancelItem.setEnabled(false);
openItem.setEnabled(true);
}
};
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.