【问题标题】:Java no UI update after Thread线程后Java没有UI更新
【发布时间】:2017-02-21 11:10:39
【问题描述】:

所以,我在我的 Java Swing 项目中遇到了这个问题,我正在制作一个自动运行 whileloop 并输出用户可以在文本字段中定义的文本的机器人。

在这里您可以看到我的代码,用于将文本行添加到我的框架中的 jlabel 中:

btnAddTalking = new JButton("Add");
    btnAddTalking.setBounds(144, 211, 146, 23);
    btnAddTalking.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            if(!txtTalk.getText().equals("")) {


            JLabel newLabel = new JLabel(txtTalk.getText());
            newLabel.addMouseListener(new MouseAdapter() {

            public void mouseClicked(MouseEvent arg0) {

                    frame.remove(newLabel);
                    frame.repaint();

                }
            });             

            newLabel.setHorizontalAlignment(SwingConstants.CENTER);

            newLabel.setBounds(159, yLabel, 101, 20);

            frame.getContentPane().add(newLabel);

            yLabel = yLabel + 20;

            frame.getContentPane().setLayout(null);

            frame.repaint();
            Talk.addTalk(txtTalk.getText());

        }
        }
    });

    frame.getContentPane().add(btnAddTalking);
    frame.getContentPane().add(lblNewLabel);
    frame.getContentPane().add(lblDelayInMs);

之后我按下以下按钮启动我的机器人:

btnStartTalking = new JButton("Start AutoTalk");
    btnStartTalking.setBounds(144, 143, 146, 23);
    btnStartTalking.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            int robotDelay = Integer.parseInt(timeTalk.getText());

            Talk.action = "start"; 

            robotTalk = txtTalk.getText();

            if (rdbtnRed.isSelected() == true) {

                robotTalk = "red:" + txtTalk.getText();

            } else if (rdbtnFlash.isSelected() == true) {

                robotTalk = "flash1:" + txtTalk.getText();

            } else if (rdbtnGlow.isSelected() == true) {

                robotTalk = "glow1:" + txtTalk.getText();

            } 

            autoTalkStart = new Runnable() {
                public void run() {
                    try {

                        btnStartTalking.setEnabled(false);
                        btnStopTalking.setEnabled(true);
                        btnAddTalking.setEnabled(false);
                        Talk test = new Talk(robotDelay);
                    } catch (AWTException | InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
            new Thread(autoTalkStart).start();




        }
    });

通过该按钮,我启动了一个线程,该线程通过输出字符串的代码运行。但是在我运行了那个线程之后,我的框架不再显示新添加的 jlabels,在你通过单击 btnStartTalking 按钮运行线程之后,你通过单击 btnAddTalking 按钮添加了这些标签!所以,我的问题是:现在有没有人怎么可能(为什么我的 UI 在我运行线程后不再更新)?

问候,

亚诺夫

在这里你可以看到我的两个类(第 1 类)的完整代码:

import java.awt.EventQueue;
import java.awt.event.InputEvent;

import javax.swing.JFrame;
import javax.swing.JTextField;

import com.sun.glass.events.KeyEvent;
import com.sun.glass.ui.Robot;

import java.awt.AWTException;
import java.awt.BorderLayout;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.GroupLayout.Alignment;
import javax.swing.SpringLayout;
import javax.swing.SwingConstants;
import javax.swing.JRadioButton;

public class AutoTalker {

private static JFrame frame;
private JTextField txtTalk;
private JTextField timeTalk;
public String robotTalk;
private JButton btnStopTalking;
private JButton btnAddTalking;
private JButton btnStartTalking;
private int yLabel = 266;
private Runnable autoTalkStart;


/**
 * Launch the application.
 */


public static void NewFrame() {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                AutoTalker window = new AutoTalker();
                window.frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 * @return 
 */


public AutoTalker() {
    initialize();
}




/**
 * Initialize the contents of the frame.
 */
private void initialize()  {



    frame = new JFrame();
    frame.setBounds(100, 100, 450, 415);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("AutoTalker");
    frame.getContentPane().setLayout(null);


    JRadioButton rdbtnGlow = new JRadioButton("Glow");
    rdbtnGlow.setBounds(6, 113, 64, 23);
    rdbtnGlow.setActionCommand("glow");
    frame.getContentPane().add(rdbtnGlow);


    JRadioButton rdbtnFlash = new JRadioButton("Flash");
    rdbtnFlash.setBounds(182, 113, 69, 23);
    rdbtnGlow.setActionCommand("flash");
    frame.getContentPane().add(rdbtnFlash);


    JRadioButton rdbtnRed = new JRadioButton("Red");
    rdbtnRed.setBounds(364, 113, 64, 23);
    rdbtnGlow.setActionCommand("red");
    frame.getContentPane().add(rdbtnRed);


    final ButtonGroup rdbtnPressed = new ButtonGroup();
    rdbtnPressed.add(rdbtnRed);
    rdbtnPressed.add(rdbtnFlash);
    rdbtnPressed.add(rdbtnGlow);

    txtTalk = new JTextField();
    txtTalk.setBounds(130, 28, 173, 20);
    txtTalk.setColumns(10);

    btnStopTalking = new JButton("Stop AutoTalk");
    btnStopTalking.setBounds(144, 177, 146, 23);
    btnStopTalking.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Talk.action = "stop";
            btnStartTalking.setEnabled(true);
            btnStopTalking.setEnabled(false);
            btnAddTalking.setEnabled(true);
            frame.repaint();

        }
    });





    btnStartTalking = new JButton("Start AutoTalk");
    btnStartTalking.setBounds(144, 143, 146, 23);
    btnStartTalking.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            int robotDelay = Integer.parseInt(timeTalk.getText());

            Talk.action = "start"; 

            robotTalk = txtTalk.getText();

            if (rdbtnRed.isSelected() == true) {

                robotTalk = "red:" + txtTalk.getText();

            } else if (rdbtnFlash.isSelected() == true) {

                robotTalk = "flash1:" + txtTalk.getText();

            } else if (rdbtnGlow.isSelected() == true) {

                robotTalk = "glow1:" + txtTalk.getText();

            } 

            autoTalkStart = new Runnable() {
                public void run() {
                    try {

                        btnStartTalking.setEnabled(false);
                        btnStopTalking.setEnabled(true);
                        btnAddTalking.setEnabled(false);
                        Talk test = new Talk(robotDelay);
                    } catch (AWTException | InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
            new Thread(autoTalkStart).start();
            frame.repaint();




        }
    });

    timeTalk = new JTextField();
    timeTalk.setBounds(174, 71, 86, 20);
    timeTalk.setColumns(10);

    JLabel lblNewLabel = new JLabel("Text:");
    lblNewLabel.setBounds(24, 28, 46, 20);

    JLabel lblDelayInMs = new JLabel("Delay in ms:");
    lblDelayInMs.setBounds(24, 71, 101, 20);
    frame.getContentPane().add(txtTalk);
    frame.getContentPane().add(btnStartTalking);
    frame.getContentPane().add(btnStopTalking);
    frame.getContentPane().add(timeTalk);

    btnAddTalking = new JButton("Add");
    btnAddTalking.setBounds(144, 211, 146, 23);
    btnAddTalking.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            if(!txtTalk.getText().equals("")) {

            JLabel newLabel = new JLabel(txtTalk.getText());
            newLabel.addMouseListener(new MouseAdapter() {

            public void mouseClicked(MouseEvent arg0) {

                    frame.remove(newLabel);
                    frame.repaint();

                }
            });             

            newLabel.setHorizontalAlignment(SwingConstants.CENTER);

            newLabel.setBounds(159, yLabel, 101, 20);

            frame.getContentPane().add(newLabel);

            yLabel = yLabel + 20;

            frame.getContentPane().setLayout(null);

            frame.repaint();
            Talk.addTalk(txtTalk.getText());

        }
        }
    });

    frame.getContentPane().add(btnAddTalking);
    frame.getContentPane().add(lblNewLabel);
    frame.getContentPane().add(lblDelayInMs);
    btnStopTalking.setEnabled(false);








}
}

第 2 类:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.ArrayList;

public class Talk extends AutoTalker {

Robot robot = new Robot();
public static String action;
public static ArrayList<String> Talks = new ArrayList<String>();

public Talk(int wait) throws AWTException, InterruptedException {     

robot.delay(5000);
while(action == "start") {  
for(int i = 0; i < Talks.size();i++) {  


String text = Talks.get(i);



    type(text);
    robot.delay(wait);  



}
}




}  

public static void addTalk(String text) {

Talks.add(text);

}


private void type(String s)

{
for (int i = 0; i < s.length(); i++){

        char c = s.charAt(i);  
switch(c) {

case '!':
 robot.keyPress(KeyEvent.VK_SHIFT);
    robot.keyPress(KeyEvent.VK_1);
    robot.keyRelease(KeyEvent.VK_SHIFT);
    robot.keyRelease(KeyEvent.VK_1); 



 break;  
 case ':':
 robot.keyPress(KeyEvent.VK_SHIFT);
 robot.keyPress(KeyEvent.VK_SEMICOLON);
 robot.keyRelease(KeyEvent.VK_SEMICOLON);
 robot.keyRelease(KeyEvent.VK_SHIFT);   





 break;
 default:           

robot.keyPress(Character.toUpperCase(c));


break; 




}
robot.delay(10);

}

robot.keyPress(KeyEvent.VK_ENTER);  
robot.keyRelease(KeyEvent.VK_ENTER);
robot.delay(10);


}



}

【问题讨论】:

  • 您在问题文本中提到了 JavaFX,但这不是 JavaFX 代码。此外,不建议使用 com.sun.glass 类,因为它们不是公开导出的 JRE API 的一部分,并且它们的接口可能会在未来的 Java 版本中更改或删除。
  • 感谢您的回复。我以为是 JavaFX 代码,但我可能错了 :)。你知道我实际上做错了什么吗?
  • 我不是 Swing 开发方面的专家,所以我不会回答这个问题。我编辑了您的问题以删除 JavaFX 引用并添加了一个 Swing 标记,这可能会帮助您找到一些愿意查看它的 Swing 专家。如果您提供mcve(请注意,必须是minimalcomplete,因为它可以被编译并执行运行)。此外,使用正确的缩进格式化代码并删除无用的空格。

标签: java multithreading swing frame windowbuilder


【解决方案1】:

改为使用

invalidate();
validate();

【讨论】:

    猜你喜欢
    • 2018-07-16
    • 1970-01-01
    • 2012-04-24
    • 2014-01-14
    • 2015-06-29
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 2015-11-16
    相关资源
    最近更新 更多