窗口MouseWheelMotion事件中一片空白 [英] Window going blank during MouseWheelMotion event

查看:195
本文介绍了窗口MouseWheelMotion事件中一片空白的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了这个简单的程序,它显示了一些关键presses,通过颜色,其中的Hello World吸引,其中一个的光标移动(与路径两种方式点击时)这句话的Hello World,也是周期, 被挑出来的时候,鼠标滚轮滚动。然而,有这个问题:当鼠标滚轮滚动整个窗口一片空白(表示从当你第一次做一个组件可见默认的灰色),并会再与颜色变化只重绘(一个非常小的变化到的Hello World,这似乎并没有要求整个帧重绘。

有关该空白发生的时间似乎与与鼠标滚轮滚动的力相关,如果我滚动很轻,只有在不显示一切都非常微小的时刻,但是滚动非常努力可以使窗口一片空白2-3秒。

我试过双缓冲 - 在想这可能是某种屏幕闪烁的 - 但它没有作出任何改变,我在茫然,这可能是导致这种怪异的效果。这是因为如果帧图像加载时车轮运动事件发生。 (有可能是从车轮事件立即退出,从而减少加载时间的方法吗?(这只是我的猜测到可能的解决方案))。

在code如下。任何想法将大大AP preciated。

 包keymouse;    进口java.awt中的*。
    java.awt.event中导入*。
    进口java.awt.image.BufferStrategy;
    进口java.util.LinkedList中;
    进口javax.swing.JFrame中;    公共类KeyMouse实现的KeyListener,
            的MouseMotionListener,MouseListener的,MouseWheelListener的,可运行{        布尔trailMode = FALSE;
        布尔存在= FALSE;
        显示窗口;
        LinkedList的单词表;
        LinkedList的trailList;
        LinkedList的colorList;
        点mousePoint;
        INT TRAIL_SIZE = 10;
        布尔的init = TRUE;
        INT FONT_SIZE = 32;
        INT mouseY的;
        INT mouseX;
        诠释Ÿ;
        INT colorCount = 0;        公共静态无效的主要(字串[] args){
            KeyM​​ouse K =新KeyMouse();
            k.run();
        }        公共KeyMouse(){
            窗口=新的显示();
            window.addKeyListener(本);
            window.addMouseMotionListener(本);
            window.addMouseListener(本);
            window.addMouseWheelListener(本);
            window.setBackground(Color.WHITE);
            window.setForeground(Color.BLACK);
            单词表=新的LinkedList();
            trailList =新的LinkedList();
            colorList =新的LinkedList();
            colorList.add(Color.BLACK);
            colorList.add(Color.BLUE);
            colorList.add(Color.YELLOW);
            colorList.add(Color.GREEN);
            colorList.add(Color.PINK);        }        @覆盖
        公共无效的keyTyped(KeyEvent的E){
            // 没做什么
        }        @覆盖
        公共无效键pressed(KeyEvent的E){
            INT键code;
            如果(e.getKey code()== KeyEvent.VK_ESCAPE){
                停止();
            }            关键code = e.getKey code();
            方法addMessage(pressed:+ e.getKeyText(键code));
        }        @覆盖
        公共无效调用keyReleased(KeyEvent的E){
            //没做什么
        }        @覆盖
        公共无效的mouseDragged(的MouseEvent E){
            点p =新点(e.getX(),e.​​getY());
            addLocation(P);
        }        @覆盖
        公共无效的mouseMoved(的MouseEvent E){
            点p =新点(e.getX(),e.​​getY());
            addLocation(P);
        }        @覆盖
        公共无效的mouseClicked(的MouseEvent E){
        }        @覆盖
        公共无效鼠标pressed(的MouseEvent E){
            trailMode = TRUE;        }        @覆盖
        公共无效的mouseReleased(的MouseEvent E){
            trailMode = FALSE;
        }        @覆盖
        公共无效的mouseEntered(的MouseEvent E){
            //没做什么
        }        @覆盖
        公共无效的mouseExited(的MouseEvent E){
            //没做什么
        }        @覆盖
        公共无效mouseWheelMoved(的MouseWheelEvent E){
            的System.out.println(e.getWheelRotation());
            colorCount ++;
            如果(colorCount→4){
                colorCount = 0;
            }
            window.setForeground((彩色)colorList.get(colorCount));        }        @覆盖
        公共无效的run(){
            window.createBufferStrategy(2);
            BufferStrategy中的策略= window.getBufferStrategy();            而(真){
                画(strategy.getDrawGraphics());
                strategy.show();
                尝试{
                    视频下载(20);
                }赶上(例外前){
                }
            }
        }        公共无效抽奖(图形G){
            //绘制背景            g.setColor(window.getBackground());
            g.fillRect(0,0,window.getWidth(),window.getHeight());            //绘制文本
            g.setColor(window.getForeground());
            g.setFont(新字体(无衬线,Font.BOLD,32));            诠释计数= trailList.size();
            如果(trailList.size()→1&放大器;&放大器; trailMode ==假){
                数= 1;
            }            如果(存在==真){
                的for(int i = 0; I<计数;我++){
                    点p =(点)trailList.get(ⅰ);
                    g.drawString(Hello World的,p.x,p.y);
                }
            }            g.setColor(Color.BLACK);
            Y = 56;
            的for(int i = 0; I< wordList.size();我++){
                串字=(串)wordList.get(ⅰ);
                g.drawString((字符串)wordList.get(ⅰ),100,y)基
                Y + = 32;
            }
        }        公共无效方法addMessage(字符串消息){
            如果(γ&GT = window.getHeight()){
                wordList.remove(0);
            }
            wordList.add(消息);
        }        公共无效addLocation(点h){
            存在= TRUE;
            trailList.addFirst(H);
            如果(trailList.size()> TRAIL_SIZE){
                trailList.removeLast();            }
        }        公共无效printMessages(){
            的for(int i = 0; I< wordList.size();我++){
                的System.out.println(wordList.get(I));
            }
        }        私人无效停止(){
            System.exit(0);
        }


解决方案

缺席一个完整的例子,我无法重现您所描述的效果。你可能你的code比较这个例子中,它表现出没有明显的消隐。

在一般情况下,


  • 的JP​​anel 是双默认缓冲;这是不寻常的需要不同的缓冲策略。

  • AnimationTest 说明一个Swing 定时器以及如何显示你的平均油漆期。

  • MouseAdapter 便于覆盖少量的方法。

  • 如果可能的话,使用类型安全泛型参数。

 进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.event.MouseAdapter;
进口java.awt.event.MouseWheelEvent;
进口java.util.LinkedList中;
进口java.util.Queue中;
进口javax.swing.JFrame中;
进口javax.swing.JLabel中;
进口javax.swing.JPanel中;/ **
* @see http://stackoverflow.com/a/10970892/230513
* /
公共类ColorWheel继承JPanel {    私有静态最终诠释N = 32;
    私人最终队列<颜色和GT; CLUT =新的LinkedList<颜色>();
    私人最终的JLabel标签=新的JLabel();    公共ColorWheel(){
        的for(int i = 0; I< N;我++){
            clut.add(Color.getHSBColor((浮点)I / N,1,1));
        }
        this.setBackground(clut.peek());
        label.setText(的getBackground()的toString());
        this.add(标签);
        this.addMouseWheelListener(新MouseAdapter(){            @覆盖
            公共无效mouseWheelMoved(的MouseWheelEvent E){
                的setBackground(clut.peek());
                label.setText(的getBackground()的toString());
                clut.add(clut.remove());
            }
        });
    }    @覆盖
    公共尺寸的get preferredSize(){
        返回新尺寸(320,240);
    }    私人无效显示(){
        JFrame的F =新的JFrame(ColorWheel);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(本);
        f.pack();
        f.setLocationRelativeTo(NULL);
        f.setVisible(真);
    }    公共静态无效的主要(字串[] args){
        EventQueue.invokeLater(新的Runnable(){            @覆盖
            公共无效的run(){
                新ColorWheel()显示()。
            }
        });
    }
}

I've written this simple program which displays key presses, draws the phrase "Hello World," where one's cursor moves (with a trail mode when clicked) and also cycles through the Colors in which "Hello World," is picked out when the mouse wheel is scrolled. However there is a problem with this: When the mouse wheel scrolls the entire window goes blank (showing the default grey color from when you first make a component visible) and will then be redrawn with the color change (a very small change only to the "Hello World," which doesn't seem to require that the whole frame be redrawn.

The time for which the blankness occurs seems to correlate with the force with which the mouse wheel is scrolled, if I scroll very lightly there is only a very tiny moment where everything is not displayed, however scrolling very hard can make the window go blank for 2-3 seconds.

I've tried double buffering - thinking that this might be some sort of screen flicker - but it has made no change and I'm at a loss as to what could be causing this weird effect. It's as if the frame image is loading while the Wheel motion event is happening. (Is there perhaps a way to exit from the wheel event immediately so as to reduce loading time? (This is just my guesses as to possible solutions)).

The code is below. Any ideas would be greatly appreciated.

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

解决方案

Absent a complete example, I can't reproduce the effect you describe. You might compare your code to this example, which exhibits no apparent blanking.

In general,

  • JPanel is double buffered by default; it's unusual to need a different buffer strategy.
  • AnimationTest illustrates a Swing Timer and how to display your average paint period.
  • MouseAdapter is convenient for overriding a small number of methods.
  • When possible, use generic parameters for type safety.

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 http://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();
            }
        });
    }
}

这篇关于窗口MouseWheelMotion事件中一片空白的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆