Java JtextArea不更新自身
我有一个编译java源文件并运行它的代码。控制台输出显示在应用程序的jtextarea中。问题是,虽然正在编译源文件并创建.class文件,但输出jtextarea不显示任何内容。我尝试在不同的线程上运行冗长的任务,但这也没有帮助。我做错了什么 更新:我更新了自定义输出流类的write方法,以便在swing worker类中包含append方法Java JtextArea不更新自身,java,swing,concurrency,Java,Swing,Concurrency,我有一个编译java源文件并运行它的代码。控制台输出显示在应用程序的jtextarea中。问题是,虽然正在编译源文件并创建.class文件,但输出jtextarea不显示任何内容。我尝试在不同的线程上运行冗长的任务,但这也没有帮助。我做错了什么 更新:我更新了自定义输出流类的write方法,以便在swing worker类中包含append方法 import javax.swing.*; import java.awt.*; import java.awt.event.*; import jav
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
class test extends JFrame
{
JTextArea content,compiler;
JSplitPane pane;
JMenuBar jmb = new JMenuBar();
JMenu menu = new JMenu("Options");
JMenuItem item = new JMenuItem("Compile") , item1 = new JMenuItem("Run") , item2 = new JMenuItem("Save");
test()
{
setTitle("Testing Window");
setSize(700,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content = new JTextArea();
compiler = new JTextArea();
PrintStream stream = new PrintStream(new cos(compiler));
System.setOut(stream);
System.setErr(stream);
pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,new JScrollPane(content),new JScrollPane(compiler));
pane.setResizeWeight(0.8);
add(pane);
menu.add(item);
menu.add(item1);
menu.add(item2);
jmb.add(menu);
setJMenuBar(jmb);
ActionListener listener = (ActionEvent ae) -> {
try(FileWriter file = new FileWriter("hello.java");
BufferedWriter bw = new BufferedWriter(file))
{
Scanner sc = new Scanner(content.getText());
while( sc.hasNext())
{
bw.write(sc.nextLine());
bw.newLine();
}
}catch(Exception e){e.printStackTrace();}
};
item2.addActionListener(listener);
ActionListener listener1 = (ActionEvent ae)->{
Runnable runnable = ()->{
try
{
Process p = Runtime.getRuntime().exec("javac hello.java");
p.waitFor();
System.out.print("Compiled Successfully \n");
}catch(Exception e){e.printStackTrace();}
};
Thread newThread = new Thread(runnable);
newThread.start();
};
item.addActionListener(listener1);
ActionListener listener2 = (ActionEvent ae)->{
Runnable runnable = ()->{
try
{
Process p = Runtime.getRuntime().exec("java hello");
p.waitFor();
}catch(Exception e){e.printStackTrace();}
};
Thread newThread = new Thread(runnable);
newThread.start();
};
item1.addActionListener(listener2);
setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater( ()->{new test();} );
}
}
class cos extends OutputStream
{
JTextArea textarea;
SwingWorker worker;
cos(JTextArea textarea)
{
this.textarea = textarea;
}
public void write(int b)throws IOException
{
worker = new SwingWorker()
{
protected Object doInBackground()
{
publish(String.valueOf( (char)b ));
return null;
}
protected void process(ArrayList<String> list)
{
textarea.append(list.get(list.size()-1))//to get latest string
}
};
worker.execute();
}
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.*;
导入java.io.*;
导入java.util.*;
类测试扩展了JFrame
{
JTextArea内容,编译器;
JSplitPane窗格玻璃;
JMenuBar jmb=新JMenuBar();
JMenu菜单=新JMenu(“选项”);
JMenuItem item=newjmenuItem(“编译”),item1=newjmenuItem(“运行”),item2=newjmenuItem(“保存”);
测试()
{
setTitle(“测试窗口”);
设置大小(700700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content=新的JTextArea();
编译器=新的JTextArea();
PrintStream=新的PrintStream(新的cos(编译器));
系统放线(溪流);
系统设置错误(流);
pane=new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,new JScrollPane(content),new JScrollPane(compiler));
窗格。设置大小权重(0.8);
添加(窗格);
菜单。添加(项目);
菜单。添加(第1项);
菜单。添加(第2项);
添加(菜单);
setJMenuBar(jmb);
ActionListener侦听器=(ActionEvent ae)->{
try(FileWriter file=newfilewriter(“hello.java”);
BufferedWriter bw=新的BufferedWriter(文件))
{
Scanner sc=新扫描仪(content.getText());
while(sc.hasNext())
{
write(sc.nextLine());
换行符();
}
}catch(异常e){e.printStackTrace();}
};
项目2.addActionListener(listener);
ActionListener listener1=(ActionEvent ae)->{
Runnable Runnable=()->{
尝试
{
进程p=Runtime.getRuntime().exec(“javac hello.java”);
p、 waitFor();
System.out.print(“编译成功\n”);
}catch(异常e){e.printStackTrace();}
};
线程newThread=新线程(可运行);
newThread.start();
};
item.addActionListener(listener1);
ActionListener监听器2=(ActionEvent ae)->{
Runnable Runnable=()->{
尝试
{
进程p=Runtime.getRuntime().exec(“java hello”);
p、 waitFor();
}catch(异常e){e.printStackTrace();}
};
线程newThread=新线程(可运行);
newThread.start();
};
项目1.addActionListener(listener2);
setVisible(真);
}
公共静态void main(字符串参数[])
{
调用器(()->{newtest();});
}
}
类cos扩展了OutputStream
{
JTextArea textarea;
摇摆工人;
cos(JTextArea textarea)
{
this.textarea=textarea;
}
公共无效写入(int b)引发IOException
{
工人=新的SwingWorker()
{
受保护对象doInBackground()
{
发布(String.valueOf((char)b));
返回null;
}
受保护的无效进程(ArrayList列表)
{
textarea.append(list.get(list.size()-1))//获取最新字符串
}
};
worker.execute();
}
}
假设您有一个简单的Java程序,它只是延迟地将一些字符串打印到控制台输出,例如:
package foo1;
import java.util.concurrent.TimeUnit;
public class StringProducer {
private static final int MAX = 10;
private static final long SLEEP_TIME = 400;
public static void main(String[] args) {
System.out.println("Start");
for (int i = 0; i < MAX; i++) {
try {
TimeUnit.MILLISECONDS.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("At index: " + i);
try {
TimeUnit.MILLISECONDS.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("End");
}
}
您的Swing线程设置完全错误,包括试图从后台线程中直接写入JTextArea。使用SwingWorker,使用SwingWorker的发布/处理方法对将在worker的后台线程中获得的字符串数据发送到Swing GUI,您的问题应该会得到解决。好的,我会试试。谢谢兄弟:)还有其他问题吗?在编辑问题之前,您可以先查看相关内容,以显示修改后的方法。有人可以指导我如何在代码中添加swing worker吗。似乎找不到出路。谢谢你的回答。不过我有个问题。在我的原始代码中,编译和运行操作是否发生在不同的进程中?这就是textarea不更新的原因吗?
package foo1;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
@SuppressWarnings("serial")
public class WorkerTester extends JPanel {
private static final int ROWS = 30;
private static final int COLS = 60;
// name of the Java program to run in its own process
public static final String CLASS_TO_RUN = "StringProducer";
// our JTextArea
private JTextArea textArea = new JTextArea(ROWS, COLS);
public WorkerTester() {
// make jtextarea non-editable/focusable and put into jscrollpane
textArea.setFocusable(false);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// this button will start the process and the worker
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new WorkerAction("Start Action")));
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
// Our JButton's Action
private class WorkerAction extends AbstractAction {
public WorkerAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
final MyWorker myWorker = new MyWorker();
myWorker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
// you always want to check for exceptions by calling
// get on the worker when done
try {
myWorker.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
});
myWorker.execute(); // run the worker
}
}
private class MyWorker extends SwingWorker<Void, String> {
private PrintStream out;
private Scanner scanner;
@Override
protected Void doInBackground() throws Exception {
@SuppressWarnings("unused")
String separator = System.getProperty("file.separator"); // in case needed
String classpath = "\"" + System.getProperty("java.class.path") + "\"";
Package packageValue = WorkerTester.this.getClass().getPackage();
String packageName = packageValue.getName() + ".";
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe");
processBuilder.redirectErrorStream(true); // combine error and input streams
Process process = processBuilder.start();
InputStream is = process.getInputStream();
OutputStream os = process.getOutputStream();
out = new PrintStream(os);
scanner = new Scanner(is);
new Thread(new ScannerGobbler(scanner)).start();
out.println("dir"); // just to test out and see where we are
out.println("java -cp .;" + classpath + " " + packageName + CLASS_TO_RUN);
out.println("exit");
out.close();
int exitValue = process.waitFor();
publish("Process Exited with exitValue of: " + exitValue);
return null;
}
@Override
protected void process(List<String> chunks) {
for (String chunk : chunks) {
textArea.append(chunk + "\n");
}
}
private class ScannerGobbler implements Runnable {
private Scanner scanner;
public ScannerGobbler(Scanner scanner) {
this.scanner = scanner;
}
@Override
public void run() {
while (scanner.hasNextLine()) {
publish(scanner.nextLine());
}
if (scanner != null) {
scanner.close();
}
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("WorkerTester");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new WorkerTester());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}