プログラムのGUIパネルを作成しようとしていますが、通常はコマンドプロンプトに出力されるすべてのものを、TextAreaオブジェクトに出力したいと思います。ほとんどの部分でGUIパネルをフォーマットしていますが、テキストをTextAreaに印刷することはできませんが、ファイルは次のとおりです。
package guipanel;
import javax.swing.*;
import Java.awt.*;
import Java.io.*;
/**
*
* @author Dan
*/
public class GUIPanel extends JFrame {
public GUIPanel() {
initComponents();
}
private void setOutputStream(boolean catchErrors) {
System.setOut(aPrintStream);
setVisible(true);
requestFocus();
if (catchErrors) {
System.setErr(aPrintStream);
}
}
private void addTabs(JTabbedPane jTabbedPane1) {
JPanel jPanel1 = new JPanel();
JPanel jPanel2 = new JPanel();
JPanel jPanel3 = new JPanel();
JPanel jPanel4 = new JPanel();
jTabbedPane1.add("Main", textArea1);
jTabbedPane1.add("Commands", jPanel);
jTabbedPane1.add("Rules", jPanel1);
jTabbedPane1.add("Links", jPanel2);
jTabbedPane1.add("Information", jPanel3);
jTabbedPane1.add("Shutdown", jPanel4);
setOutputStream(true);
}
@SuppressWarnings("unchecked")
private void initComponents() {
textArea1 = new Java.awt.TextArea();
jTabbedPane1 = new javax.swing.JTabbedPane();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenu2 = new javax.swing.JMenu();
textArea1.setPreferredSize(new Java.awt.Dimension(432, 343));
textArea1.getAccessibleContext().setAccessibleParent(jTabbedPane1);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Evolution-X 639");
setBounds(new Java.awt.Rectangle(0, 0, 400, 450));
setResizable(false);
getContentPane().setLayout(new Java.awt.FlowLayout());
addTabs(jTabbedPane1);
getContentPane().add(jTabbedPane1);
jMenu1.setText("File");
jMenuBar1.add(jMenu1);
jMenu2.setText("Edit");
jMenuBar1.add(jMenu2);
setJMenuBar(jMenuBar1);
pack();
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
}
Java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUIPanel().setVisible(true);
}
});
}
private JMenu jMenu1;
private JMenu jMenu2;
private JMenuBar jMenuBar1;
private JTabbedPane jTabbedPane1;
private TextArea textArea1;
private JPanel jPanel = new JPanel();
private PrintStream aPrintStream =
new PrintStream(
new FilterOutputStream(
new ByteArrayOutputStream()));
}
印刷ストリームを、制御可能な出力ストリームにリダイレクトする必要があります...
これは、私が仕事のために取り組んでいるアプリケーションのために開発した概念の例です。これを使用して、ユーザーサイトで実行されているときに出力コンソールを表示し、標準出力に送信されているものを確認できるようにします...ログを修正するまで;)
基本的に、カスタムOutputStream
を印刷ストリームとコンソールの間に配置して出力をキャプチャしますが、それでもコンテンツをコンソールに印刷できます。これは、コマンドラインまたはIDEからプログラムを実行している場合に役立ちます。必要に応じて、これを停止するスイッチを配置できます...
public class TestRedirect {
public static void main(String[] args) {
new TestRedirect();
}
public TestRedirect() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
CapturePane capturePane = new CapturePane();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(capturePane);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
PrintStream ps = System.out;
System.setOut(new PrintStream(new StreamCapturer("STDOUT", capturePane, ps)));
System.out.println("Hello, this is a test");
System.out.println("Wave if you can see me");
}
});
}
public class CapturePane extends JPanel implements Consumer {
private JTextArea output;
public CapturePane() {
setLayout(new BorderLayout());
output = new JTextArea();
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 String prefix;
private Consumer consumer;
private PrintStream old;
public StreamCapturer(String prefix, Consumer consumer, PrintStream old) {
this.prefix = prefix;
buffer = new StringBuilder(128);
buffer.append("[").append(prefix).append("] ");
this.old = old;
this.consumer = consumer;
}
@Override
public void write(int b) throws IOException {
char c = (char) b;
String value = Character.toString(c);
buffer.append(value);
if (value.equals("\n")) {
consumer.appendText(buffer.toString());
buffer.delete(0, buffer.length());
buffer.append("[").append(prefix).append("] ");
}
old.print(c);
}
}
}
実例で更新。 Windows 7、Java 6およびMacOS Lion Java 7
MadProgrammerのソリューションは本当に素晴らしいです、そして私は彼に基づいています。ただし、Loopkinが指摘しているように、特殊文字は処理しません(正確には、すべての非ASCII文字で失敗します)。
Loopkinのソリューションは私にはうまくいきませんでしたが、私はついにその仕事をする2つのソリューションを思いつきました。
この単純なソリューションは、U + 00FFまでのすべての文字(すべての1バイト文字)を処理します。次のように定義されるwrite()
を除いて、すべてがMadProgrammerと同じです。
_@Override
public void write(int b) throws IOException {
buffer.append(Character.toChars((b + 256) % 256));
if ((char) b == '\n') {
textArea.append(str);
textArea.setCaretPosition(textArea.getDocument().getLength());
buffer.delete(0, buffer.length());
}
old.write(b);
}
_
私はそれを必要としなかったので、私は接頭辞のものを入れていません。
結局、すべての文字を含めることにしたので、PrintStream
を直接拡張し、プレフィックス/インデントを元に戻しました。問題は、プライベートメソッドwrite(String s)
をオーバーライドできなかったため、すべてのprint()
メソッドをオーバーライドしたことです。
_public class PrintStreamCapturer extends PrintStream {
private JTextArea text;
private boolean atLineStart;
private String indent;
public PrintStreamCapturer(JTextArea textArea, PrintStream capturedStream, String indent) {
super(capturedStream);
this.text = textArea;
this.indent = indent;
this.atLineStart = true;
}
public PrintStreamCapturer(JTextArea textArea, PrintStream capturedStream) {
this(textArea, capturedStream, "");
}
private void writeToTextArea(String str) {
if (text != null) {
synchronized (text) {
text.setCaretPosition(text.getDocument().getLength());
text.append(str);
}
}
}
private void write(String str) {
String[] s = str.split("\n", -1);
if (s.length == 0)
return;
for (int i = 0; i < s.length - 1; i++) {
writeWithPotentialIndent(s[i]);
writeWithPotentialIndent("\n");
atLineStart = true;
}
String last = s[s.length - 1];
if (!last.equals("")) {
writeWithPotentialIndent(last);
}
}
private void writeWithPotentialIndent(String s) {
if (atLineStart) {
writeToTextArea(indent + s);
atLineStart = false;
} else {
writeToTextArea(s);
}
}
private void newLine() {
write("\n");
}
@Override
public void print(boolean b) {
synchronized (this) {
super.print(b);
write(String.valueOf(b));
}
}
@Override
public void print(char c) {
synchronized (this) {
super.print(c);
write(String.valueOf(c));
}
}
@Override
public void print(char[] s) {
synchronized (this) {
super.print(s);
write(String.valueOf(s));
}
}
@Override
public void print(double d) {
synchronized (this) {
super.print(d);
write(String.valueOf(d));
}
}
@Override
public void print(float f) {
synchronized (this) {
super.print(f);
write(String.valueOf(f));
}
}
@Override
public void print(int i) {
synchronized (this) {
super.print(i);
write(String.valueOf(i));
}
}
@Override
public void print(long l) {
synchronized (this) {
super.print(l);
write(String.valueOf(l));
}
}
@Override
public void print(Object o) {
synchronized (this) {
super.print(o);
write(String.valueOf(o));
}
}
@Override
public void print(String s) {
synchronized (this) {
super.print(s);
if (s == null) {
write("null");
} else {
write(s);
}
}
}
@Override
public void println() {
synchronized (this) {
newLine();
super.println();
}
}
@Override
public void println(boolean x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(char x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(int x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(long x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(float x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(double x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(char x[]) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(String x) {
synchronized (this) {
print(x);
newLine();
super.println();
}
}
@Override
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
super.println();
}
}
}
_
シンプルにするためにConsumer
アスペクトを削除しましたが、実際に必要なものはすべてここにあります。このクラスの使用方法は次のとおりです。
_System.setOut(new PrintStreamCapturer(logTextArea, System.out));
System.setErr(new PrintStreamCapturer(logTextArea, System.err, "[ERROR] "));
_
MadProgrammerからの回答は気に入っていますが、UTF-8文字では機能しないと思います。
代わりに、StreamCapturerにByteArrayOutputStreamを拡張させ、これを書き込み実装として使用します。
@Override
public void write(int b){
if ('\n' == (char) b) {
consumer.appendText(toString());
reset();
}
else {
super.write(b);
}
old.write(b);
}
実装ではプレフィックス部分が必要ないため、プレフィックス部分をスキップしています。コードをありがとう、それは大きな助けになりました!
NOOBS用の元のMadProgrammerのコードを更新するだけです-JTextAreaパラメーターをコンストラクターに渡します。
new RedirectText(Main.window.textArea1);