2012-06-10 4 views
4

Я написал эту простую программу, которая отображает нажатия клавиш, рисует фразу «Hello World», где движется курсор (с режимом трейла при нажатии), а также циклически проходит через Цвета, Hello World ", выбирается при прокрутке колеса мыши. Однако есть проблема с этим: когда колесико мыши прокручивается, все окно становится пустым (показывает серый цвет по умолчанию с момента первого появления компонента) и затем будет перерисовываться с изменением цвета (очень небольшое изменение только для «Hello World», который, кажется, не требует, чтобы весь кадр был перерисован.Окно во время события MouseWheelMotion

Время, за которое возникает пустота, похоже, коррелирует с силой, с которой прокручивается колесико мыши, если я прокручиваю очень легко там это очень крошечный момент, когда все не отображается, однако прокрутка очень сильно может сделать окно пустым в течение 2-3 секунд.

Я пробовал двойную буферизацию - думая, что это может быть какой-то экранный мерцание - но он не изменился, и я не понимаю, что может вызвать этот странный эффект. Это похоже на то, что изображение кадра загружается во время события движения колеса. (Возможно, есть возможность немедленно выйти из события колеса, чтобы уменьшить время загрузки? (Это только мои догадки относительно возможных решений)).

Код приведен ниже. Любые идеи очень приветствуются.

package keymouse; 

    import java.awt.*; 
    import java.awt.event.*; 
    import java.awt.image.BufferStrategy; 
    import java.util.LinkedList; 
    import javax.swing.JFrame; 

    public class KeyMouse implements KeyListener, 
      MouseMotionListener, MouseListener, MouseWheelListener, Runnable { 

     boolean trailMode = false; 
     boolean exists = false; 
     display window; 
     LinkedList wordList; 
     LinkedList trailList; 
     LinkedList colorList; 
     Point mousePoint; 
     int TRAIL_SIZE = 10; 
     boolean init = true; 
     int FONT_SIZE = 32; 
     int mouseY; 
     int mouseX; 
     int y; 
     int colorCount = 0; 

     public static void main(String[] args) { 
      KeyMouse k = new KeyMouse(); 
      k.run(); 
     } 

     public KeyMouse() { 
      window = new display(); 
      window.addKeyListener(this); 
      window.addMouseMotionListener(this); 
      window.addMouseListener(this); 
      window.addMouseWheelListener(this); 
      window.setBackground(Color.WHITE); 
      window.setForeground(Color.BLACK); 
      wordList = new LinkedList(); 
      trailList = new LinkedList(); 
      colorList = new LinkedList(); 
      colorList.add(Color.BLACK); 
      colorList.add(Color.BLUE); 
      colorList.add(Color.YELLOW); 
      colorList.add(Color.GREEN); 
      colorList.add(Color.PINK); 

     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
      // do nothing 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
      int keyCode; 
      if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 
       stop(); 
      } 

      keyCode = e.getKeyCode(); 
      addMessage("Pressed:" + e.getKeyText(keyCode)); 
     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      //do nothing 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      Point p = new Point(e.getX(), e.getY()); 
      addLocation(p); 
     } 

     @Override 
     public void mouseMoved(MouseEvent e) { 
      Point p = new Point(e.getX(), e.getY()); 
      addLocation(p); 
     } 

     @Override 
     public void mouseClicked(MouseEvent e) { 
     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
      trailMode = true; 

     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      trailMode = false; 
     } 

     @Override 
     public void mouseEntered(MouseEvent e) { 
      //do nothing 
     } 

     @Override 
     public void mouseExited(MouseEvent e) { 
      //do nothing 
     } 

     @Override 
     public void mouseWheelMoved(MouseWheelEvent e) { 


      System.out.println(e.getWheelRotation()); 
      colorCount++; 
      if (colorCount > 4) { 
       colorCount = 0; 
      } 


      window.setForeground((Color) colorList.get(colorCount)); 

     } 

     @Override 
     public void run() { 
      window.createBufferStrategy(2); 
      BufferStrategy strategy = window.getBufferStrategy(); 

      while (true) { 
       draw(strategy.getDrawGraphics()); 
       strategy.show(); 
       try { 
        Thread.sleep(20); 
       } catch (Exception ex) { 
       } 
      } 
     } 

     public void draw(Graphics g) { 
      //draw background 

      g.setColor(window.getBackground()); 
      g.fillRect(0, 0, window.getWidth(), window.getHeight()); 

      //draw Text 
      g.setColor(window.getForeground()); 
      g.setFont(new Font("sansserif", Font.BOLD, 32)); 

      int count = trailList.size(); 
      if (trailList.size() > 1 && trailMode == false) { 
       count = 1; 
      } 

      if (exists == true) { 
       for (int i = 0; i < count; i++) { 
        Point p = (Point) trailList.get(i); 
        g.drawString("Hello World", p.x, p.y); 
       } 
      } 

      g.setColor(Color.BLACK); 
      y = 56; 
      for (int i = 0; i < wordList.size(); i++) { 
       String word = (String) wordList.get(i); 
       g.drawString((String) wordList.get(i), 100, y); 
       y += 32; 
      } 


     } 

     public void addMessage(String message) { 
      if (y >= window.getHeight()) { 
       wordList.remove(0); 
      } 
      wordList.add(message); 
     } 

     public void addLocation(Point h) { 
      exists = true; 
      trailList.addFirst(h); 
      if (trailList.size() > TRAIL_SIZE) { 
       trailList.removeLast(); 

      } 
     } 

     public void printMessages() { 
      for (int i = 0; i < wordList.size(); i++) { 
       System.out.println(wordList.get(i)); 
      } 
     } 

     private void stop() { 
      System.exit(0); 
     } 
+1

'в то время как (истинно) {.. Thread.sleep (20);' Используйте качание 'Timer' вместо этого. –

+1

Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

+1

Вы реализуете 'Runnable', вы намеревались запустить метод' run() 'в фоновом потоке? Это не так, вы называете это напрямую. –

ответ

3

Отсутствие полного примера, я не могу воспроизвести описанный вами эффект. Вы можете сравнить свой код с этим примером, который не имеет явного гашения.

В общем,

  • JPanel является двойной буферизации по умолчанию; Необычно нужна другая стратегия буфера.
  • AnimationTest иллюстрирует поворот Timer и как отображать средний период окраски.
  • MouseAdapter удобен для переопределения небольшого числа методов.
  • Если возможно, используйте общие параметры безопасности типа.

ColorWheel image

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseWheelEvent; 
import java.util.LinkedList; 
import java.util.Queue; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

/** 
* @see https://stackoverflow.com/a/10970892/230513 
*/ 
public class ColorWheel extends JPanel { 

    private static final int N = 32; 
    private final Queue<Color> clut = new LinkedList<Color>(); 
    private final JLabel label = new JLabel(); 

    public ColorWheel() { 
     for (int i = 0; i < N; i++) { 
      clut.add(Color.getHSBColor((float) i/N, 1, 1)); 
     } 
     this.setBackground(clut.peek()); 
     label.setText(getBackground().toString()); 
     this.add(label); 
     this.addMouseWheelListener(new MouseAdapter() { 

      @Override 
      public void mouseWheelMoved(MouseWheelEvent e) { 
       setBackground(clut.peek()); 
       label.setText(getBackground().toString()); 
       clut.add(clut.remove()); 
      } 
     }); 
    } 

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

    private void display() { 
     JFrame f = new JFrame("ColorWheel"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ColorWheel().display(); 
      } 
     }); 
    } 
} 
Смежные вопросы