Я скопировал и изменил код ответа, размещенный здесь: Печать вывода процесса на JTextArea через клиентский сервер Сеть в java
Проблема с моим кодом состоит в том, что он работает только один раз когда код запускается. Любые последующие звонки на запись просто ничего не сделают.
Вот мой код:
Класс MainFrame
public class MainFrame extends JFrame {
private JTextArea Output;
private JScrollPane outputScrollPane;
private JButton clickMe;
private ProcessThread processThread;
private ExecutorService execService;
public MainFrame() {
setTitle("StackOverflow");
setSize(700, 850);
setMinimumSize(new Dimension(650,800));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
Output = new JTextArea();
Output.setEditable(false);
outputScrollPane = new JScrollPane(Output);
outputScrollPane.setPreferredSize(new Dimension(100, 150));
outputScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
add(outputScrollPane, BorderLayout.CENTER);
clickMe = new JButton("click Me");
add(clickMe, BorderLayout.SOUTH);
execService = Executors.newSingleThreadExecutor();
processThread = new ProcessThread(Output);
execService.submit(processThread);
clickMe.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
processThread.write("some command\n"); //does nothing (doesn't update JTextArea with the process' response)
}
});
}
});
setVisible(true);
}
}
Класс Process Thread:
public class ProcessThread implements Runnable {
private JTextArea ta;
private WriteWorker writeWorker;
private ReadWorker readWorker;
private CountDownLatch shutDownLatch;
public ProcessThread(JTextArea ta) {
this.ta = ta;
}
public void write(String text) {
if (writeWorker != null) {
if (writeWorker.getState() == SwingWorker.StateValue.STARTED) {
writeWorker.write(text);
} else {
throw new IllegalStateException("Write worker is not running");
}
} else {
throw new NullPointerException("Write worker is null");
}
}
public void close() {
if (writeWorker != null) {
writeWorker.cancel(true);
}
if (readWorker != null) {
readWorker.cancel(true);
}
// Force the CountDownLatch to release
if (shutDownLatch != null) {
shutDownLatch.countDown();
shutDownLatch.countDown();
}
}
@Override
public void run() {
try {
Process myProcess;
myProcess = new ProcessBuilder("C:\\Folder\\executable.exe").start();
InputStream processInputStream = myProcess.getInputStream();
OutputStream processOutputStream = myProcess.getOutputStream();
writeWorker = new WriteWorker(processOutputStream);
readWorker = new ReadWorker(processInputStream, ta);
writeWorker.addPropertyChangeListener(new PropertyChangeHandler());
readWorker.addPropertyChangeListener(new PropertyChangeHandler());
writeWorker.execute();
readWorker.execute();
shutDownLatch = new CountDownLatch(2);
shutDownLatch.await();
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected class PropertyChangeHandler implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
SwingWorker worker = (SwingWorker) evt.getSource();
if (worker.getState() == SwingWorker.StateValue.DONE) {
shutDownLatch.countDown();
// Not interested in the return value, only interested in the
// exception if one was thrown...
try {
worker.get();
} catch (InterruptedException | ExecutionException ex) {
// Resync the error with the UI, probably using SwingUtilities.invokeLater
// and call some error handling method
ex.printStackTrace();
}
}
}
}
}
Класс ReadWorker:
public class ReadWorker extends SwingWorker<Void,String> {
private InputStream is;
private JTextArea ta;
public ReadWorker(InputStream is, JTextArea ta) {
this.is = is;
this.ta = ta;
}
@Override
protected Void doInBackground() throws Exception {
byte[] buffer = new byte[4096];
int bytesRead = -1;
while (!isCancelled() && (bytesRead = is.read(buffer)) != -1) {
String text = new String(buffer, 0, bytesRead);
publish(text);
}
return null;
}
@Override
protected void process(List<String> chunks) {
for (String text : chunks) {
ta.append(text);
}
}
}
Рабочий класс записи:
public class WriteWorker extends SwingWorker {
private OutputStream os;
private List<String> queue = new ArrayList<String>(25);
private ReentrantLock queueLock = new ReentrantLock();
private Condition queueCondition = queueLock.newCondition();
@Override
protected Object doInBackground() throws Exception {
while (!isCancelled()) {
String text = null;
while (text == null && !isCancelled()) {
queueLock.lock();
try {
if (queue.isEmpty()) {
queueCondition.await();
}
if (!queue.isEmpty()) {
text = queue.remove(0);
}
} finally {
queueLock.unlock();
}
if (text != null) {
os.write(text.getBytes());
}
}
}
return null;
}
public WriteWorker(OutputStream os) {
this.os = os;
}
public void write(String text) {
queueLock.lock();
try {
queue.add(text);
queueCondition.signal();
} finally {
queueLock.unlock();
}
}
}
И, наконец, Главный класс:
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MainFrame frame = new MainFrame();
}
});
}
}
Что я сделал не так и почему?