2017-02-21 2 views
0

Итак, у меня есть эта проблема в моем проекте Java Swing, где я создаю бота, который автоматически запускается через whileloop и выводит текст, который пользователь может определить в текстовом поле.Java no UI update после Thread

Здесь вы можете увидеть мой код для добавления TextLine в 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, которые вы добавили, нажав кнопку btnAddTalking после того, как вы запустили Thread, нажав кнопку btnStartTalking! Итак, мой вопрос: кто-нибудь теперь, как это возможно (почему мой пользовательский интерфейс больше не обновляется после того, как я запустил поток)?

Greetz,

Jarnov

Здесь вы можете увидеть весь мой код для двух классов (класс 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); 


} 



} 
+0

Вы упомянули JavaFX в тексте вопроса, но это не код JavaFX. Кроме того, использование классов 'com.sun.glass' не рекомендуется, поскольку они не являются частью публично экспортированного JRE API, и их интерфейс может быть изменен или удален в будущих версиях Java. – jewelsea

+0

Спасибо за ваш ответ. Я думал, что это код JavaFX, но я могу ошибаться :). Вы знаете, что я на самом деле делаю неправильно? –

+0

Я не эксперт в разработке Swing, поэтому я не буду отвечать на это. Я отредактировал ваш вопрос, чтобы удалить ссылку JavaFX и добавить тэг Swing, который может помочь вам подобрать некоторых экспертов Swing, желающих посмотреть на них. Вместо того, чтобы сбрасывать весь код, вы можете получить больше шансов на ответы, если вы предоставите [mcve] (http://stackoverflow.com/help/mcve) (обратите внимание, что это должно быть как минимальное *, так и * полное *, в что его можно скомпилировать и выполнить для запуска). Кроме того, отформатируйте код с правильным отступом и удалением бесполезных пробелов. – jewelsea

ответ

0

Используйте вместо

invalidate(); 
validate();