2015-02-02 6 views
0

내가 할 노력하고있어 재미있는 JFrame 마우스가 창을 떠날 때 그래서, 그것은 어떤 임의의 색상 (사용자의 관심을 얻기 위해)에 패널 Background 색상을 변경 :변경 구성 요소의 배경 색상

wnd.addMouseListener(new MouseAdapter(){ 
     @Override 
     public synchronized void mouseExited(MouseEvent e){ 
      cond = true; 
      while(cond){ 
       try{ 
        wnd.getContentPane().setBackground(Color.getHSBColor((cont+=0.05), 1, 1)); 
        wnd.setTitle("Num: "+cont); 
        wnd.getContentPane().repaint(); //With or without it doesn't work either 
        wait(100); 
        } 
        catch(InterruptedException ex){ Thread.currentThread().interrupt(); } 
       } 
      } 
    }); 

문제는 Background 색깔이 변하지 않는다는 것입니다 ... 그것은 창 제목에 cont 값을 표시하지만 색상은 변하지 않습니다. 주기를 제거하고 패널 안팎으로 마우스를 움직이면 바뀝니다 ...하지만 마우스가 창을 떠날 때 마우스가 다시 돌아올 때까지 색상을 자동으로 변경합니다. 어떤 종류의 간질 (?)

나는 왜주기를하고 wait()으로 지연 시키면 작동하지 않는지 모르겠다.

+2

당신은에서 방지, 이벤트 파견 스레드를 차단하고 대한 Concurrency in SwingHow to use Swing Timers를 살펴 보자 UI를 업데이트 할 수 없었다. – MadProgrammer

+0

'wait()'에 대한 문서를 읽었습니까? 그것은 아마도 당신이 전혀 사용하고 싶지 않을 것입니다. –

답변

2

스윙은 단일 스레드 프레임 워크이므로 Event Dispatching Thread를 차단할 수있는 모든 요소가 이벤트 큐 (다시 칠하기 요청 포함)를 처리하지 못하게하고 응용 프로그램이 중단 된 것처럼 나타나게합니다.

EDT의 컨텍스트 내에서 장기 실행 또는 차단 작업을 수행해서는 안됩니다.

대신이 경우 스윙 Timer을 사용하여 일반 콜백을 예약해야합니다. 이것의 이점은 콜백이 EDT 컨텍스트 내에서 실행되므로 UI를 업데이트하는 데 안전하게 사용할 수 있다는 것입니다 (스윙은 스레드로부터 안전하지 않기 때문에).

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

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

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Timer updateTimer; 

     public TestPane() { 
      updateTimer = new Timer(100, new ActionListener() { 
       private float cont = 0; 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        setBackground(Color.getHSBColor((cont += 0.05), 1, 1)); 
       } 
      }); 

      addMouseListener(new MouseAdapter() { 

       @Override 
       public void mouseExited(MouseEvent e) { 
        updateTimer.start(); 
       } 

       @Override 
       public void mouseEntered(MouseEvent e) { 
        updateTimer.stop(); 
       } 

      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 

은 자세한 내용

+0

감사합니다. 예 ... .NET에서 java로 바꿨습니다 ... C#에서와 같이'async void'와'await Task.Delay (int) '를 똑같이 사용할 수는 없다고 생각합니다.하지만 고마워요! 난 그냥이 타이머와 작동 테스트 :) 감사합니다 대단히 : P –

+0

다행스럽게도 ... – MadProgrammer