Java JTextArea尝试打开新的JDialog并刷新时不显示

时间:2016-03-17 18:46:22

标签: java swing jtextarea

创建包含文本区域的新对话框,然后运行输出到文本区域的代码时,在代码执行完成之前,文本区域不会显示。我想在代码执行时刷新文本区域。以下是一些演示此问题的示例代码。

package textareatester;

import java.io.PrintStream;
import javax.swing.JOptionPane;


public class NewJFrame extends javax.swing.JFrame
{

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame()
    {
        initComponents();
    }


    @SuppressWarnings("unchecked")
  private void initComponents()
  {

    jButton1 = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jButton1.setText("Test Me");
    jButton1.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        jButton1ActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
        .addContainerGap(175, Short.MAX_VALUE)
        .addComponent(jButton1)
        .addGap(154, 154, 154))
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addGap(113, 113, 113)
        .addComponent(jButton1)
        .addContainerGap(164, Short.MAX_VALUE))
    );

    pack();
  }                    

  private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)                                         
  {                                             

        NewJDialog dialog = new NewJDialog(this, "Output", false );
        dialog.setVisible(true);
        PrintStream ps = System.out;
        System.setOut(new PrintStream(new StreamCapturer("STDOUT", dialog, ps)));
        OutputMaker oMaker = new OutputMaker(); 
        oMaker.makeOutput();
        JOptionPane.showMessageDialog(this,"OUtput ran successfully!", "Success!", JOptionPane.INFORMATION_MESSAGE);
  }                                        

    /**
     * @param args the command line arguments
     */
    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(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex)
        {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex)
        {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex)
        {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }


        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                new NewJFrame().setVisible(true);
            }
        });
    }


  private javax.swing.JButton jButton1;

}


package textareatester;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;


public class StreamCapturer extends OutputStream
{

    private StringBuilder buffer;
    private String prefix;
    private NewJDialog consumer;
    private PrintStream old;

    public StreamCapturer(String prefix, NewJDialog 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);
    }

}

package textareatester;

import java.util.logging.Level;
import java.util.logging.Logger;


public class OutputMaker
{
    public void makeOutput()
    {
        try
        {
            System.out.println("Output for line 1.");
            Thread.sleep(2000);
            System.out.println("Output for line 2.");
            Thread.sleep(2000);
            System.out.println("Output for line 3.");
            Thread.sleep(2000);
            System.out.println("Output for line 4.");
            Thread.sleep(2000);
            System.out.println("Output for line 5.");
        } catch (InterruptedException ex)
        {
            Logger.getLogger(OutputMaker.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

package textareatester;

import java.awt.EventQueue;


public class NewJDialog extends javax.swing.JDialog
{

    /**
     * Creates new form NewJDialog
     */
    public NewJDialog(java.awt.Frame parent, boolean modal)
    {
        this(parent, "", modal);
    }
    public NewJDialog(java.awt.Frame parent, String title, boolean modal)
    {
        super(parent, title, modal);
        initComponents();
    }

    @SuppressWarnings("unchecked")

  private void initComponents()
  {

    jScrollPane2 = new javax.swing.JScrollPane();
    jTextArea1 = new javax.swing.JTextArea();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

    jTextArea1.setColumns(20);
    jTextArea1.setRows(5);
    jScrollPane2.setViewportView(jTextArea1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
    );

    pack();
  }               

    public void appendText(final String text)
    {
        if (EventQueue.isDispatchThread())
        {
            jTextArea1.append(text);
            jTextArea1.setCaretPosition(jTextArea1.getText().length());
        } else
        {

            EventQueue.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    appendText(text);
                }
            });

        }
    }


  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JTextArea jTextArea1;

}

1 个答案:

答案 0 :(得分:2)

据我所知,您的代码基于我的Can I iterate through all Outlook emails in a folder including sub-folders?

问题是,您在事件调度线程的上下文中使用Thread.sleep,这阻止它在jButton1ActionPerformed之后处理任何新事件(包括重绘事件)回报。

相反,你需要使用一个单独的线程,比如SwingWorker或者只是一个普通的旧线程(看作append方法自己同步对UI的更新),例如

previous answer

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.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

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)));
            }
        });
    }

    public class CapturePane extends JPanel implements Consumer {

        private JTextArea output;

        public CapturePane() {
            setLayout(new BorderLayout());
            output = new JTextArea();
            add(new JScrollPane(output));

            JButton test = new JButton("Test");
            test.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SwingWorker worker = new SwingWorker() {
                        @Override
                        protected Object doInBackground() throws Exception {
                            System.out.println("Hello world");
                            Thread.sleep(1000);
                            System.out.println("I'm calling you from another thread");
                            Thread.sleep(1000);
                            System.out.println("But you can still see the updates as they occur");
                            return null;
                        }

                        @Override
                        protected void done() {
                            test.setEnabled(true);  
                        }

                    };
                    test.setEnabled(false);
                    worker.execute();
                }
            });
            add(test, BorderLayout.SOUTH);
        }

        @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);
        }
    }
}

有关详细信息,请参阅Clickity ClackConcurrency in Swing