有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java Swing GlassPane拖动性能

我试图使用GlassPane在Swing应用程序中进行可视化拖放,但遇到了一个问题,即拖动图像滞后于鼠标指针,有时甚至相当大。我该如何解决这个问题?我的玻璃窗格代码如下。谢谢

package dragui;

import java.awt.*;
import javax.swing.*;
import java.awt.event.MouseEvent;
import javax.swing.event.MouseInputAdapter;

public class GlassPane extends JComponent {
    private int x=0, y=0, k=25,z=1;
    private boolean showDot;
    private MouseInputAdapter mia = new MouseInputAdapter(){

        @Override
        public void mouseDragged(MouseEvent me) {
            setPos(me.getX(), me.getY());
        }

        @Override
        public void mousePressed(MouseEvent me) {
            setShow(true);
            setPos(me.getX(), me.getY());   
        }

        @Override
        public void mouseReleased(MouseEvent me){
            setShow(false);
            setVisible(false);
        }
    };

    public void setShow(boolean b){ this.showDot = b; }

    public void paint(Graphics g) {
        if (showDot) {
            g.setColor(new Color(0.0f, 0.25f, 1.0f));
            g.fillOval(x - k, y - k, 2*k, 2*k);
        }
    }

    public void setPos(int x, int y) {
        int tmpX = this.x, tmpY = this.y; 
        this.x = x; this.y = y;
        repaint(tmpX - k , tmpY-k, 2*k+5, 2*k+5);
        repaint(this.x-k, this.y-k, 2*k+5, 2*k+5);        
    }

    public GlassPane() {
        addMouseListener(mia); 
        addMouseMotionListener(mia);
        setOpaque(false);
    }
}

共 (2) 个答案

  1. # 1 楼答案

    也许您不应该在每次重新绘制时创建new Color(0.0f, 0.25f, 1.0f)

    对我来说,这场演出相当不错

    public class Example {
        static public void main( String[] s ) {
            EventQueue.invokeLater( new Runnable() {
                public void run() {
                    JFrame frame = new JFrame();
                    frame.setBounds( 50, 50, 600, 600 );
                    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                    frame.setGlassPane( new JComponent() {
                        {
                            MouseInputAdapter mia = new MouseInputAdapter(){
                                public void mouseDragged(MouseEvent me) {
                                    setPos(me.getX(), me.getY());
                                }
                                public void mousePressed(MouseEvent me) {
                                    setShow(true);
                                    setPos(me.getX(), me.getY());   
                                }
                                public void mouseReleased(MouseEvent me){
                                    setShow(false);
                                    setVisible(false);
                                }
                            };
                            addMouseListener(mia); 
                            addMouseMotionListener(mia);
                            setOpaque(false);
                        }
                        private int x=0, y=0, k=25,z=1;
                        private boolean showDot;
                        public void setShow(boolean b){ this.showDot = b; }
                        private Color color = new Color(0.0f, 0.25f, 1.0f);
                        public void paintComponent(Graphics g) {
                            if (showDot) {
                                g.setColor(color);
                                g.fillOval(x - k, y - k, 2*k, 2*k);
                            }
                        }
                        public void setPos(int x, int y) {
                            int tmpX = this.x, tmpY = this.y; 
                            this.x = x; this.y = y;
                            repaint(tmpX - k , tmpY-k, 2*k+5, 2*k+5);
                            repaint(this.x-k, this.y-k, 2*k+5, 2*k+5);        
                        }
                    } );
                    frame.getGlassPane().setVisible( true );
                    frame.setVisible( true );
                }
            });
        }
    }
    
  2. # 2 楼答案

    根据Javadoc报告

    A subclass that just wants to specialize the UI (look and feel) delegate's paint method should just override paintComponent.

    这是因为paint(...)实际上将绘画工作委托给了三种受保护的方法:paintComponentpaintBorderpaintChildren。也就是说,试着用这个替换paint(...)

    @Override
    protected void paintComponent(Graphics g) {
        if (showDot) {
            Graphics gCopy = g.create();
    
            gCopy.setColor(new Color(0.0f, 0.25f, 1.0f));
            gCopy.fillOval(x - k, y - k, 2*k, 2*k);
    
            gCopy.dispose();
        }
    }