0

我目前有一个程序,可以在不同行的“System.out.println()”语句中将文本行打印到屏幕上。我是 Java、Eclipse 和 WindowBuilder 的新手。

我现在正在向这个程序添加一个 GUI。我能够使用按钮创建 GUI,这些按钮工作正常。我的问题是我想将打印到 Eclipse 控制台(或命令行)的所有内容实时打印到我的 GUI 中的文本框中。我怎样才能轻松做到这一点?

package Onur;


import java.awt.BorderLayout;

public class BehaSendDFGUI extends JFrame {

    private BehaviourSendWithDF1 myAgent; // Reference to the agent class
    private JPanel contentPane;
    private JDesktopPane desktopPane;
    private JButton btnMessage;
    private JButton btnMessage_1;
    private JButton btnMessage_2;
    private JButton btnMessage_3;
    private JTextArea textArea = new JTextArea();

    public void setAgent(BehaviourSendWithDF1 a) {
        myAgent = a; // provide the value of the reference of BehaviourSendWithDF1 class here

    }

    private void updateTextArea(final String text) {
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                textArea.append(text);
            }
          });
        }

        private void redirectSystemStreams() {
          OutputStream out = new OutputStream() {
            @Override
            public void write(int b) throws IOException {
              updateTextArea(String.valueOf((char) b));
            }

            @Override
            public void write(byte[] b, int off, int len) throws IOException {
              updateTextArea(new String(b, off, len));
            }

            @Override
            public void write(byte[] b) throws IOException {
              write(b, 0, b.length);
            }
          };

          System.setOut(new PrintStream(out, true));
          System.setErr(new PrintStream(out, true));
        }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Throwable e) {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    BehaSendDFGUI frame = new BehaSendDFGUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public BehaSendDFGUI() {


        setTitle("Behaviour Sender");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 523, 398);

        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        JMenu mnFile = new JMenu("File");
        menuBar.add(mnFile);

        JMenuItem mntmExit = new JMenuItem("Exit");
        mnFile.add(mntmExit);

        JMenu mnAbout = new JMenu("About");
        menuBar.add(mnAbout);

        JMenuItem mntmAboutThisGui = new JMenuItem("About This GUI");
        mnAbout.add(mntmAboutThisGui);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        contentPane.add(toolBar, BorderLayout.CENTER);

        desktopPane = new JDesktopPane();
        toolBar.add(desktopPane);

        btnMessage = new JButton("Send Message 1");
        btnMessage.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BehaviourSendWithDF1.STEP = "1";
                System.out.println("Button Pressed => STEP = " + BehaviourSendWithDF1.STEP );
                myAgent.behaSend();             
            }

        });
        btnMessage.setBounds(10, 11, 111, 23);
        desktopPane.add(btnMessage);

        btnMessage_1 = new JButton("Send Message 2");
        btnMessage_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BehaviourSendWithDF1.STEP = "2";
                System.out.println("Button Pressed => STEP = " + BehaviourSendWithDF1.STEP );
                myAgent.behaSend(); 
            }
        });
        btnMessage_1.setBounds(131, 11, 111, 23);
        desktopPane.add(btnMessage_1);

        btnMessage_2 = new JButton("Send Message 3");
        btnMessage_2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                BehaviourSendWithDF1.STEP = "3";
                System.out.println("Button Pressed => STEP = " + BehaviourSendWithDF1.STEP );
                myAgent.behaSend(); 
            }
        });
        btnMessage_2.setBounds(252, 11, 111, 23);
        desktopPane.add(btnMessage_2);

        btnMessage_3 = new JButton("Send Message 4");
        btnMessage_3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                BehaviourSendWithDF1.STEP = "4";
                System.out.println("Button Pressed => STEP = " + BehaviourSendWithDF1.STEP );
                myAgent.behaSend(); 
            }
        });
        btnMessage_3.setBounds(373, 11, 111, 23);
        desktopPane.add(btnMessage_3);

        JButton btnExitGui = new JButton("Exit GUI");
        btnExitGui.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });
        btnExitGui.setBounds(189, 293, 130, 23);
        desktopPane.add(btnExitGui);

        JTextPane txtpnConsoleOutput = new JTextPane();
        txtpnConsoleOutput.setText("Console Output:");
        txtpnConsoleOutput.setBounds(10, 45, 101, 20);
        desktopPane.add(txtpnConsoleOutput);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 76, 475, 206);
        desktopPane.add(scrollPane);
        scrollPane.setViewportView(textArea);

        redirectSystemStreams();

    }
}

我在 NetBeans 上看到过这个解决方案,但无法将其应用于 WindowBuilder:

http://unserializableone.blogspot.com/2009/01/redirecting-systemout-and-systemerr-to.html

提前致谢。

编辑:代码的工作版本在问题中进行了编辑。感谢所有的帮助。

4

1 回答 1

1

您的问题包括

  1. 您正在尝试使用不存在的变量 textPane 和
  2. 您的程序没有可以显示文本的文本组件。我建议您至少添加一个 JTextArea,以便您可以将输出重定向到它。如果您愿意,可以将其称为 textPane,但无论您如何称呼它,您至少需要拥有可以显示多行文本的东西。
  3. 同样,您提供的链接中描述的一般技术是正确的——您需要将 System.out 和 System.err 重定向到您创建的 OutputStream,
  4. 但是您必须注意仅在 Swing 事件线程上更新 Swing 组件,因此使用SwingUtilities.invokeLater(new Runnable() {...})...
  5. 因此,正确使用文章的建议起作用。所以坚持下去。

再次,阅读 Swing 教程并把 windows builder 代码生成器放在一边。代码生成器可用于节省您的时间,但如果您在充分了解 Swing 库之前使用它们,那么您可能会遇到大问题,因为您需要的不仅仅是最基本的 GUI 和行为。

编辑
您似乎正在尝试调用append(...)JTextField,并且此类不允许该消息。我建议

  • 你大大简化了你的类,所以它只有最基本的 GUI 来演示 System.out 和 err 的重定向,以及
  • 再次使用 JTextArea,而不是 JTextField。

编辑 2
你问:

我无法解决'textArea.append(text);' 范围错误:无法解析 textArea。

请注意您声明textArea 变量的位置。由于它没有在类中声明,而是在方法或构造函数中声明,因此它在类的其他地方不可见。解决方案是在类中声明它,而不是在其他地方。

编辑 3
例如,

import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.swing.*;

@SuppressWarnings("serial")
public class RedirectOut extends JPanel {
   private static final int BUTTON_COUNT = 4;
   private JTextArea textArea = new JTextArea(20, 20);
   private SomeAgent myAgent;

   public RedirectOut() {
      redirectSystemStreams();

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

      for (int i = 0; i < BUTTON_COUNT; i++) {
         final int count = i + 1;
         JButton button = new JButton(new AbstractAction("Send Message " + count){
            @Override
            public void actionPerformed(ActionEvent e) {
               myAgent.setStep(String.valueOf(count));
               System.out.println("Button Pressed => STEP = "
                     + myAgent.getStep());
               myAgent.behaSend();
            }
         });
         JPanel btnPanel = new JPanel();
         btnPanel.add(button);
         add(btnPanel);
      }
      add(new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
   }

   public void setAgent(SomeAgent agent) {
      this.myAgent = agent;
   }

   public void updateTextArea(final String text) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            textArea.append(text);
         }
      });
   }

   private void redirectSystemStreams() {
      OutputStream out = new OutputStream() {
         @Override
         public void write(int b) throws IOException {
            updateTextArea(String.valueOf((char) b));
         }

         @Override
         public void write(byte[] b, int off, int len) throws IOException {
            updateTextArea(new String(b, off, len));
         }

         @Override
         public void write(byte[] b) throws IOException {
            write(b, 0, b.length);
         }
      };

      System.setOut(new PrintStream(out, true));
      System.setErr(new PrintStream(out, true));
   }

   private static void createAndShowGui() {
      RedirectOut redirectOut = new RedirectOut();
      redirectOut.setAgent(new SomeAgent());

      JFrame frame = new JFrame("RedirectOut");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(redirectOut);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
于 2013-04-02T20:55:43.833 回答