2017-08-24 27 views
2

我想它打字的東西后JTextField的顏色變爲紅色,再進行第二次返回到默認的白色背景之後。我想這聽者外,和它的工作,但是當談到作爲一個聽者的一部分,它不會(它只是跳過設置紅色)。這是怪異我..兩個設置背景和睡眠線程

public class Test { 
    JFrame frame; 
    JTextField field; 

    public Test() { 
     frame = new JFrame(); 
     field = new JTextField("A"); 
     field.addKeyListener(new KeyBListener()); 
     frame.getContentPane().add(field); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { new Test(); } 

    private class KeyBListener implements KeyListener { 
     @Override 
     public void keyTyped(KeyEvent e) { 

      try { 
       field.setBackground(Color.RED); 
       Thread.sleep(1000); 
       field.setBackground(Color.WHITE); 
      } catch (InterruptedException es) { es.printStackTrace(); } 

     } 

     @Override 
     public void keyPressed(KeyEvent e) { } 

     @Override 
     public void keyReleased(KeyEvent e) { } 
    } 
} 
+0

您需要閱讀事件調度線程(EDT)。對於像這樣的更新,他們必須在EDT之外發生,否則,您會阻止重新繪製顯示。 – Speakjava

回答

3

嘗試創建一個單獨的Thread偵聽色的JTextField變化又換了回來。在這種情況下,至少你不會阻塞主線程,儘管我不確定它是最有效的方法。

public Main() { 
    frame = new JFrame(); 
    frame.setSize(800, 600); 
    field = new JTextField("A"); 
    field.addKeyListener(new KeyBListener()); 
    frame.getContentPane().add(field); 
    frame.pack(); 
    frame.setVisible(true); 

    new Thread(() -> { 
     while(true) { 
      if(field.getBackground().equals(Color.RED)) 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e1) { 
       e1.printStackTrace(); 
      } 
      field.setBackground(Color.WHITE); 
     } 

    }).start(); 
} 
+0

不知道這是最有效的太..'而(真)'這個.. – azro

+0

呀,不知道是否有另一種方法。我想過在''listener''裏面創建線程,但是在每次按鍵上啓動一個線程都是很糟糕的。 –

0

你以前的溶液中工作,因爲它是從AWT本身執行。

keyTyped()方法是在事件調度THEAD(EDT)執行的,所以你必須移動繪畫行動回到AWT。

SwingUtilities.invokeLater()(非阻塞)或SwingUtilities.invokeAndWait()(阻塞)一看,只見 Oracle Doc

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
    try { 
     field.setBackground(Color.RED); 
     Thread.sleep(1000); 
     field.setBackground(Color.WHITE); 
    } catch (InterruptedException es) { 
     es.printStackTrace(); 
    } 
    } 
}); 
0

您可以生成在其中做色彩處理不同的線程。這確保了顏色處理不在EDT內部發生。

import java.awt.Color; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.concurrent.atomic.AtomicBoolean; 

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

public class Test { 
    JFrame frame; 
    JTextField field; 
    AtomicBoolean isColorChangeOn = new AtomicBoolean(); 
    public Test() { 
     frame = new JFrame(); 
     field = new JTextField("A"); 
     field.addKeyListener(new KeyBListener()); 
     frame.getContentPane().add(field); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
     isColorChangeOn.set(false); 
    } 

    public static void main(String[] args) { 
     new Test(); 
    } 

    private class KeyBListener implements KeyListener { 
     @Override 
     public void keyTyped(KeyEvent e) { 
       if(!isColorChangeOn.get()) { 
        isColorChangeOn.set(true); 
        Runnable setcolor =()->{ 
         try { 
          System.out.println("color changing"); 
          field.setBackground(Color.RED); 
          Thread.sleep(1000); 
          field.setBackground(Color.WHITE); 
          isColorChangeOn.set(false); 
         } catch (InterruptedException e1) { 
          e1.printStackTrace(); 
         } 
        }; 
        new Thread(setcolor).start(); 
       } 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
     } 
    } 
}