Лаг при рисовании чего-либо с помощью мышки - PullRequest
2 голосов
/ 30 декабря 2010

У меня возникли проблемы с рисованием прямоугольников в позиции мыши.Окрашенный прямоугольник отстает от курсора мыши при перемещении мыши.Есть ли способ гарантировать, что прямоугольник перемещается точно по мышке и не отстает?

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

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.*;

public class MouseTest {
    JFrame window;
    DrawPanel content;

    public MouseTest(){
        window = new JFrame("Test");
        content = new DrawPanel();
        window.setContentPane(content);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
        window.pack();
    }

    public static void main (String[] args){
        MouseTest test = new MouseTest();
    }

    private class DrawPanel extends JPanel implements MouseMotionListener {
        int mouseX;
        int mouseY;

        private DrawPanel(){
            setBackground(Color.BLUE);
            setPreferredSize(new Dimension(400,400));
            addMouseMotionListener(this);
        }

        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(mouseX, mouseY, 20, 20);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseMoved(MouseEvent e) {
            mouseX = e.getX();
            mouseY = e.getY();
            repaint();

        }
    }

}

Ответы [ 4 ]

2 голосов
/ 30 декабря 2010

Первое, что нужно сделать, это переместить весь код Swing / AWT в EDT. В вашем приложении это может не имеет значения, но это хорошая привычка.

Однако я не смог воспроизвести ваше отставание при любом подходе.

public static void main (String[] args)
{
    SwingUtilities.invokeLater(
        new Runnable()
        {
            public void run()
            {
                MouseTest test = new MouseTest();
            }
        });
}

См. эту статью для получения дополнительной информации о Swing Threading.

1 голос
/ 30 декабря 2010

Может быть, это далеко, но когда вы говорите «отставание», вы имеете в виду, что курсор находится не в центре прямоугольника?Ваш код имеет курсор, указывающий на верхний левый угол прямоугольника, вам нужно сместить его, чтобы отцентрировать.

0 голосов
/ 30 декабря 2010

Прямоугольник запаздывает, потому что ваш класс обрабатывает каждое событие движения. Если бы он обрабатывал только самое последнее событие, прямоугольник был бы обновлен (хотя он мог бы иметь большие скачки в позиции). Один из способов сделать это - запустить отдельный поток, который рисует прямоугольник на основе текущей позиции мыши, который обновляется методом mouseMoved (). Вам придется синхронизировать доступ к переменной положения мыши.

0 голосов
/ 30 декабря 2010

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

Вы увидите большие улучшения.

EDIT

Я сам проверил это на этом примере

    public void mouseMoved(MouseEvent e) {
        repaint(mouseX, mouseY, 20, 20);
        mouseX = e.getX();
        mouseY = e.getY();
        repaint(mouseX, mouseY, 20, 20);
    }

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

EDIT

И еще обман: если вам все еще не нравится несоответствие между тем, где, по вашему мнению, находится курсор, и тем, что думает система, попробуйте отключить курсор (http://www.java2s.com/Code/Java/2D-Graphics-GUI/HidethemousecursoruseatransparentGIFasthecursor.htm), чтобы дать пользователю лучшую обратную связь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...