Java JtextArea不更新自身

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

我有一个编译java源文件并运行它的代码。控制台输出显示在应用程序的jtextarea中。问题是,虽然正在编译源文件并创建.class文件,但输出jtextarea不显示任何内容。我尝试在不同的线程上运行冗长的任务,但这也没有帮助。我做错了什么

更新:我更新了自定义输出流类的write方法,以便在swing worker类中包含append方法

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());
    }
}