如何获取终端结果并设置一个JTextArea来读取终端



我最近完成了一个GUI,用户可以在其中输入标准,并根据所述条件获得结果。该程序按结果运行,但我在GUI中获取textField以读取终端窗口结果时遇到了问题。我的GUI代码如下:

package project205;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class HouseListGUI extends JFrame
{
//GUI Components
HouseList availableHouses = new HouseList("src/houses.txt");
 JLabel  cLab   = new JLabel("Criteria");
 JLabel  minLab   = new JLabel("Min");
 JLabel  maxLab   = new JLabel("Max");
 JLabel  pLab   = new JLabel("Price");
 JLabel  aLab   = new JLabel("Area");
 JLabel  bLab   = new JLabel("Bedrooms");
 JTextField  pMin   = new JTextField(10);
 JTextField  pMax   = new JTextField(10);
 JTextField  aMin   = new JTextField(10);
 JTextField  aMax   = new JTextField(10);
 JTextField  bMin   = new JTextField(10);
 JTextField  bMax   = new JTextField(10);
 JTextArea  results    = new JTextArea(20, 40);
 JButton sButton   = new JButton("Search");
 JButton qButton   = new JButton("Quit");
public HouseListGUI()
{

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,300);
        setVisible(true);  


Container c = getContentPane();
c.setLayout(new GridLayout(5,3,10,10));
c.add(cLab);
c.add(minLab);
c.add(maxLab);
c.add(pLab);
c.add(pMin);
c.add(pMax);
c.add(aLab);
c.add(aMin);
c.add(aMax);
c.add(bLab);
c.add(bMin);
c.add(bMax);
c.add(sButton);
c.add(results);
c.add(qButton);
sButton.addActionListener(
  new ActionListener()
  {
    public void actionPerformed(ActionEvent e)
    {
    String pmn = pMin.getText();
    String pmx = pMax.getText();
    String amn = aMin.getText();
    String amx = aMax.getText();
    String bmn = bMin.getText();
    String bmx = bMax.getText();
    int pmn1 = Integer.parseInt(pmn);
    int pmx1 = Integer.parseInt(pmx);
    int amn1 = Integer.parseInt(amn);
    int amx1 = Integer.parseInt(amx);
    int bmn1 = Integer.parseInt(bmn);
    int bmx1 = Integer.parseInt(bmx);

    Criteria theCriteria = new Criteria(pmn1, pmx1, amn1, amx1, bmn1, bmx1);
    availableHouses.printHouses(theCriteria);
    results.setText("");
    }
  });

qButton.addActionListener(
        new ActionListener()
        {
             public void actionPerformed(ActionEvent e)
             {
                 System.exit(0);
             }
        }
        );
}
public static void main(String[] args)
{
    //HouseList availableHouses = new HouseList("src/houses.txt");
    HouseListGUI g1 = new HouseListGUI();
    g1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    g1.setSize(1000,500);
    g1.show();
}
}

我想要代码行的结果availableHouses.printHouses(标准);返回类型void要在文本区域中打印结果

我尝试过使用类型转换将void转换为字符串,并将其放入结果中,即:

   results.setText((String)availableHouses.printHouses(theCriteria);

但Java没有。

TL;DR:

如何获取void类型的方法调用产生的终端,并将其作为String类型打印到GUI上下文中的textArea中?

进一步澄清:

我的终端窗口是这样的:

https://i.stack.imgur.com/ZTZFC.jpg

我的GUI看起来是这样的:

https://i.stack.imgur.com/dCxbZ.jpg

并且我希望我的终端位于最后一行的中间框中。

谢谢你的任何建议/提示!

我尝试过使用类型转换将void转换为字符串,并将其放入结果中,即:

results.setText((String)availableHouses.printHouses(theCriteria);

不,这永远不会奏效,而且你正在倒退。最好让HouseList的printHouses(...)方法返回一个String,然后它可以很容易地显示在JTextArea中,只需很少或根本不需要修改,当然也不会出现错误的强制转换。

否则,如果您绝对必须从另一个控制台程序获得无法以任何方式更改的标准输出,则必须使用ProcessBuilder在单独的进程中调用它(如果是Java程序,则在作为进程运行的单独JVM中),然后捕获进程中的InputStream,并将其输出到JTextArea中。它是可行的,但需要使用后台线程和异常捕获,我不建议初学者深入研究。

您可以通过提供自己的OutputStream来捕获和重定向发送到System.out的内容。毫无疑问,这是一个万无一失的解决方案,因为任何打印到标准输出的东西都会被捕获,但你可以根据需要打开和关闭。。。

我在没有日志文件调试语句的应用程序中使用了这个调试窗口,并过滤和阻止System.out生成任何输出。。。

在这个例子中,我使用。。。

PrintStream ps = System.out;
System.setOut(new PrintStream(new StreamCapturer(capturePane, ps)));
doSomeProcessing();
System.setOut(ps);

要开始和停止捕获System.out,可以在StreamCapturer中放置一个标志,打开和关闭回显功能,这可能是解决问题的更好方法。。。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class RediretStdOutTest {
    public static void main(String[] args) {
        new RediretStdOutTest();
    }
    public RediretStdOutTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                final CapturePane capturePane = new CapturePane();
                JButton processButton = new JButton("Process");
                processButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("Look at me, I'm not in your UI");
                        PrintStream ps = System.out;
                        System.setOut(new PrintStream(new StreamCapturer(capturePane, ps)));
                        doSomeProcessing();
                        System.setOut(ps);
                        System.out.println("Neither am I");
                    }
                });
                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(capturePane);
                frame.add(processButton, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
    protected void doSomeProcessing() {
        for (int index = 0; index < 10; index++) {
            System.out.println("--> " + index);
        }
    }
    public class CapturePane extends JPanel implements Consumer {
        private JTextArea output;
        public CapturePane() {
            setLayout(new BorderLayout());
            output = new JTextArea(10, 20);
            add(new JScrollPane(output));
        }
        @Override
        public void appendText(final String text) {
            if (EventQueue.isDispatchThread()) {
                output.append(text);
                output.setCaretPosition(output.getText().length());
            } else {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        appendText(text);
                    }
                });
            }
        }
    }
    public interface Consumer {
        public void appendText(String text);
    }
    public class StreamCapturer extends OutputStream {
        private StringBuilder buffer;
        private Consumer consumer;
        private PrintStream old;
        public StreamCapturer(Consumer consumer, PrintStream old) {
            buffer = new StringBuilder(128);
            this.old = old;
            this.consumer = consumer;
        }
        @Override
        public void write(int b) throws IOException {
            char c = (char) b;
            consumer.appendText(Character.toString(c));
            old.print(c);
        }
    }
}

现在,说了这么多,我会修复你的方法,这样它就会返回一个结果,因为它会更干净。。。

最新更新