【问题标题】:How to take terminal results and set a JTextArea to read the terminal?如何获取终端结果并设置 JTextArea 来读取终端?
【发布时间】:2014-10-09 12:57:58
【问题描述】:

我最近完成了一个 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(theCriteria); 它返回一个 void 类型 在 textArea 中打印 结果

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

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

但 Java 没有。

TL;DR:

如何将 void 类型的方法调用产生的终端作为字符串类型打印到 GUI 上下文中的 textArea 中?

进一步说明:

我的终端窗口如下所示:

http://imgur.com/wiewXan

我的 GUI 看起来像这样:

http://imgur.com/wdd0ieK

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

感谢您的任何建议/提示!

【问题讨论】:

  • 假设我理解正确this 将允许您捕获打印到System.out 的内容并将其显示在JTextArea 中,这里的问题是,它将捕获发送到的所有内容System.out...

标签: java swing user-interface jtextarea


【解决方案1】:

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

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

不,这永远不会奏效,而且你会倒退。让 HouseList 的 printHouses(...) 方法返回一个字符串要好得多,然后它可以很容易地显示在您的 JTextArea 中,几乎不需要修改,当然也不会出现错误的转换。

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

【讨论】:

  • 您可以通过劫持来捕获通过System.out 传递的内容,但它会捕获所有内容,需要一些巧妙的切换才能使其正常工作...
  • @MadProgrammer:是的。请发表答案!
【解决方案2】:

您可以通过提供自己的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);
        }
    }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 2019-10-14
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多