Java Swing GlassPane Drag Performance
I'm trying to do a visual drag and drop in my Swing application using a GlassPane, but am running into the problem that the drag image lags behind the mouse pointer, sometimes considerably. How do I solve this? My GlassPane code is below. Thanks!
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);
}
}
According to the Javadoc,
A subclass that just wants to specialize the UI (look and feel) delegate's paint method should just override paintComponent.
And this is because paint(...)
actually delegates the work of painting to three protected methods: paintComponent
, paintBorder
, and paintChildren
. That being said, try replacing paint(...)
with this
@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();
}
}
perhaps you should not creating a new Color(0.0f, 0.25f, 1.0f)
on every repaint.
For me the performance is quiet nice.
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 );
}
});
}
}
精彩评论