0

我正在开发一个程序,并且在运行时在 TextArea 上打印我的结果时遇到问题(类似于您可以使用 System.out.print("") 执行的操作),并且需要将它们附加到文本区域。我想将其用作流程步进器窗口。

我试图调用新线程和其他一些东西,但没有成功。我真的被困在这里了。

任何帮助将非常感激。

这是示例代码。在 StdOut 中,您可以看到代码何时执行,那时它应该在 TextArea 中也可见,但是当方法完成时它会出现在上面。它应该在执行 stdout 的同时将文本附加到 TextArea 上。


public class Start {
public static void main(String[] args) {
    Manager.getInstance();
}
}

public class Manager {

public static Manager instance;
private MyFrame mainFrame;

private Manager(){
    mainFrame = MyFrame.newInstance();
    mainFrame.setVisible(true);
}

public static Manager getInstance() {
    if(instance == null){
        instance = new Manager();
    }
    return instance;
}

public void startMethod() {
    for(int i = 0; i < 5000; i++){
        doSmething();
        if(i == 0){
            sendMsg("Start");
        }

    }
    sendMsg("End");

}

private void doSmething() {
    try{
        Thread.sleep(1);
    }
    catch (InterruptedException e){
    }
}

private void sendMsg(String str){
    (new Thread(new MyFrameMsg(mainFrame,str))).start();
    mainFrame.setTextArea(str);
    System.out.println(str);
}

}

class MyFrameMsg implements Runnable{

private MyFrame mainFrame;
private String str;

public MyFrameMsg(MyFrame _mainComander, String _str) {
    mainFrame = _mainComander;
    str = _str;
}

@Override
public void run() {
    System.out.println(str + " in thread");
    mainFrame.setTextArea(str);
}
}


使用 Netbeans 构建

public class MyFrame extends javax.swing.JFrame {

private static MyFrame instance;

public MyFrame(){
    initComponents();
    instance = this;
}


public static MyFrame newInstance() {
    if(instance == null){
        new MyFrame();
    }
    return instance;
}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    textArea = new javax.swing.JTextArea();
    startButton = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    textArea.setEditable(false);
    textArea.setColumns(20);
    textArea.setRows(5);
    jScrollPane1.setViewportView(textArea);

    startButton.setText("Start");
    startButton.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(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jScrollPane1)
            .addContainerGap())
        .addGroup(layout.createSequentialGroup()
            .addGap(162, 162, 162)
            .addComponent(startButton)
            .addContainerGap(181, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(98, Short.MAX_VALUE)
            .addComponent(startButton)
            .addGap(39, 39, 39)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap())
    );

    pack();
}// </editor-fold>                        



// Variables declaration - do not modify                     
private javax.swing.JButton startButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea textArea;
// End of variables declaration  


private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
    Manager.getInstance().startMethod();
}


public void setTextArea(String str) {
    textArea.append(str + System.getProperty("line.separator"));
} 
}
4

1 回答 1

2

您必须像这样对您的 startMethod() 进行线程化:

public void startMethod() {
    new Thread() {
        public void run() {
            for (int i = 0; i < 5000; i++) {
                doSmething();
                if (i == 0) {
                    sendMsg("Start");
                }

            }
            sendMsg("End");
        }
    }.start();
}

您的设计问题如下:AWT-EventQueue 触发您的 ButtonEvent,然后创建 5000 个线程对象。这些将运行并更新您的 TextArea,但 TextArea 只会在 AWT-Eventqueue-Thread 被释放后重新绘制(在创建所有 5000 个对象之后)

而且你不应该再需要线程你的 MyFrameMsg 类了(除了他们应该做的不仅仅是未来的简短更新)

于 2013-11-09T15:59:22.970 回答