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

时间:2014-10-09 04:32:27

标签: java swing user-interface 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(theCriteria); 返回一个类型void 要在textArea中打印     结果

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

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

但是Java没有那个。

TL; DR:

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

进一步澄清:

我的终端窗口如下所示:

http://imgur.com/wiewXan

我的GUI看起来像这样:

http://imgur.com/wdd0ieK

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

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

2 个答案:

答案 0 :(得分:3)

  

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

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

不,这永远不会奏效,你会倒退它。让HouseList的printHouses(...)方法返回一个字符串会更好,然后很容易在你的JTextArea中显示很少或没有修改,当然也没有错误的演员。

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

答案 1 :(得分:3)

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

我已将此作为调试窗口用于没有调试语句到日志文件的应用程序,以及过滤和停止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);
        }
    }
}

现在,说了这么多,我会修复你的方法,以便它返回一个结果,因为它会更清洁......