-1

単一の JTextArea を含む単一の JPanel を含む JFrame があります。System.out を JTextArea にポイントすることに成功しましたが、 Scanner(System.in) を使用して JTextArea からの入力を解析しようとすると、何もロードされないようです。例のように、アプリケーションをビルドして実行すると、何も起こらず、フレームが表示されません。これが私のコードです:

/**
 * Create the frame.
 */
public TerminalForm() {
    setTitle("Terminal");
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setBounds(100, 100, 570, 370);
    contentPane = new JPanel();
    contentPane.setBorder(BorderFactory.createEmptyBorder());
    setContentPane(contentPane);
    contentPane.setLayout(new BorderLayout(0, 0));

    PipedInputStream inPipe = new PipedInputStream();
    PipedInputStream outPipe = new PipedInputStream();

    System.setIn(inPipe);
    try {
        System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    PrintWriter inWriter = null;
    try {
        inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
    } catch (IOException e) {
        e.printStackTrace();
    }

    final JTextArea txtIO = console(outPipe, inWriter);
    txtIO.setFont(new Font("Andale Mono", Font.PLAIN, 12));
    txtIO.setCaretColor(new Color(50, 205, 50));
    txtIO.getCaret().setVisible(true);
    txtIO.getCaret().setSelectionVisible(true);
    txtIO.setLineWrap(true);
    txtIO.setForeground(new Color(50, 205, 50));
    txtIO.setBackground(new Color(0, 0, 0));
    txtIO.setBorder(BorderFactory.createEmptyBorder());
    contentPane.add(txtIO);

    // 5. get some input (from JTextArea)
    Scanner s = new Scanner(System.in);
    System.out.printf("got from input: \"%s\"%n", s.nextLine());
}

public static JTextArea console(final InputStream out, final PrintWriter in) {
    final JTextArea area = new JTextArea();

    // handle "System.out"
    new SwingWorker<Void, String>() {
        @Override protected Void doInBackground() throws Exception {
            Scanner s = new Scanner(out);
            while (s.hasNextLine()) publish(s.nextLine() + "\n");
            s.close();
            return null;
        }
        @Override protected void process(List<String> chunks) {
            for (String line : chunks) area.append(line);
        }
    }.execute();

    // handle "System.in"
    area.addKeyListener(new KeyAdapter() {
        private StringBuffer line = new StringBuffer();
        @Override public void keyTyped(KeyEvent e) {
            char c = e.getKeyChar();
            if (c == KeyEvent.VK_ENTER) {
                in.println(line);
                line.setLength(0); 
            } else if (c == KeyEvent.VK_BACK_SPACE) { 
                line.setLength(line.length() - 1); 
            } else if (!Character.isISOControl(c)) {
                line.append(e.getKeyChar());
            }
        }
    });

    return area;
}
4

2 に答える 2

1

フレームを表示するように設定していません。

于 2016-02-07T22:08:34.093 に答える
1

これが私のコードである場合、ユーザーが JTextArea に直接入力するのではなく、JTextArea のすぐ下にある JTextField に入力します (BorderLayout.SOUTH から JScrollPane に保持されている JTextArea へ、BorderLayout.CENTER)。次に、ActionListener を介して enter を介して入力を受け入れ、ユーザーが JTextArea に入力したものを、ユーザーからのものであることを示す何らかの形で出力し、入力されたテキストを OutputStream または PrintStream を介して送信します。

たとえば、

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Scanner;

import javax.swing.*;
import javax.swing.text.JTextComponent;

@SuppressWarnings("serial")
public class TerminalForm extends JPanel {
   private static final int GAP = 3;
   public static final String PRE_TEXT = "User> ";
   private JTextArea textarea;
   private JTextField textfield;

   public TerminalForm(int rows, int cols, InputStream inStream, PrintStream printStream) {
      textarea = prepareTextArea(rows, cols, inStream);
      textfield = prepareTextField(cols, printStream, textarea);

      setLayout(new BorderLayout(GAP, GAP));
      setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
      add(new JScrollPane(textarea), BorderLayout.CENTER);
      add(textfield, BorderLayout.SOUTH);
   }

   private JTextField prepareTextField(int cols, PrintStream printStream, JTextArea textArea) {
      JTextField textField = new JTextField(cols);
      textField.addActionListener(new TextFieldListener(printStream, textArea));
      return textField;
   }

   private JTextArea prepareTextArea(int rows, int cols, InputStream inStream) {
      JTextArea textArea = new JTextArea(rows, cols);
      textArea.setEditable(false);
      textArea.setFocusable(false);
      InputStreamWorker instreamWorker = new InputStreamWorker(textArea, inStream);
      instreamWorker.execute();
      return textArea;
   }

   private class TextFieldListener implements ActionListener {
      private PrintStream printStream;
      private JTextArea textArea;

      public TextFieldListener(PrintStream printStream, JTextArea textArea) {
         this.printStream = printStream;
         this.textArea = textArea;
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         JTextComponent textComponent = (JTextComponent) evt.getSource();
         String text = textComponent.getText();
         textComponent.setText("");

         printStream.println(text);
         textArea.append(TerminalForm.PRE_TEXT + text + "\n");
      }
   }

   private class InputStreamWorker extends SwingWorker<Void, String> {
      private Scanner scanner;
      private JTextArea textArea;

      private InputStreamWorker(JTextArea textArea, InputStream inStream) {
         this.textArea = textArea;
         scanner = new Scanner(inStream);
      }

      @Override
      protected Void doInBackground() throws Exception {
         while (scanner.hasNextLine()) {
            publish(scanner.nextLine());
         }
         return null;
      }

      @Override
      protected void process(List<String> chunks) {
         for (String chunk : chunks) {
            textArea.append(chunk + "\n");
         }
      }
   }

   private static void createAndShowGui(final InputStream inStream, final PrintStream printStream) {
      int rows = 20;
      int cols = 40;
      TerminalForm mainPanel = new TerminalForm(rows, cols, inStream, printStream);

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

   public static void main(String[] args) {
      final InputStream inStream = System.in;
      final PrintStream printStream = System.out;
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui(inStream, printStream);
         }
      });
   }
}
于 2013-08-24T16:20:00.133 に答える