2015-02-02 5 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

Вы блокирующих событие Диспетчерская тему, препятствуя не удалось обновить пользовательский интерфейс. – MadProgrammer

+0

Вы прочитали документацию для 'wait()'? Вероятно, это не то, что вы хотите использовать. –

ответ

2

Swing - это однопоточный фреймворк, это означает, что все, что блокирует поток Dispatching Event, предотвратит его обработку очереди событий (включая запросы перерисовки) и приведет к появлению приложения, поскольку оно зависло, потому что оно имеет.

Вы не должны выполнять длительные операции или блокировать операции в контексте EDT.

Вместо этого в этом случае вы должны использовать Swing Timer, чтобы запланировать регулярный обратный вызов. Преимущество этого заключается в том, что обратный вызов выполняется из контекста EDT, что делает его безопасным для использования для обновления пользовательского интерфейса (поскольку Swing также не является потокобезопасным).

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); 
     } 

    } 

} 

Посмотрите на Concurrency in Swing и How to use Swing Timers для более подробной информации

+0

Спасибо! Да ... Я переключился с .NET на java ... Я думаю, что не могу использовать то же самое для 'async void' и' await Task.Delay (int) 'как C# делает ... Но спасибо! Я только что проверил это с таймером и работал :) Спасибо большое: P –

+0

Рад, что это помогло ... – MadProgrammer

Смежные вопросы