Java JTextArea尝试打开新的JDialog并刷新时未显示 [英] Java JTextArea Not showing up when trying to open new JDialog and refresh

查看:65
本文介绍了Java JTextArea尝试打开新的JDialog并刷新时未显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当创建一个包含文本区域的新对话框,然后运行输出到文本区域的代码时,直到代码执行完成,文本区域才会显示出来.我希望在执行代码时刷新文本区域.这是一些示例代码,演示了此问题.

When creating a new dialog containing a text area and then running code that outputs to the text area, the text area is not showing up until the code execution finishes. I would like the text area to refresh while the code is executing. Here is some sample code that demonstrates the problem.

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;

}

推荐答案

据我所知,您的代码基于我的

From what I can tell, you code is based on my previous answer

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

The problem is, you're using Thread.sleep from within the context of the Event Dispatching Thread, which is prevent it from processing any new events (including repaint events) until after the jButton1ActionPerformed returns.

例如,您需要使用一个单独的线程,例如SwingWorker或仅使用一个普通的旧线程(如append方法将同步更新同步到UI本身),例如

Instead, you need to be using a separate thread, like SwingWorker or just a plain old thread (seen as the append method synchronises updates to the UI by itself), for example

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

请参见 Swing中的并发 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆