【发布时间】:2012-12-12 13:55:33
【问题描述】:
我正在尝试设置在 Jlabels 网格上拖动图像。 它工作正常,但图像“令人耳目一新”,有时会落后于鼠标。
有没有办法改进这一点并获得完美“平滑”的图像移动?
编辑:好的,感谢 Andrew Thompson 的建议,我将 paint() 方法更新为 paintComponent()。但是现在为什么我拖动它时我的组件消失了?我可能在这里遗漏了一些东西......
EDIT2:为什么会出现以下行为:使用 paint() 方法时,组件显示在 JLabels 之上。但是当使用 paintComponent() 时,组件会被不透明的 Jlabels 掩盖而消失?
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class DragNDrop {
public static void main(String[] args)
{
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new DragPanel());
f.pack();
f.setLocation(200,200);
f.setVisible(true);
}
}
class DragPanel extends JPanel {
JLabel[][] labels;
SelectableAction action;
Image image;
Point p;
public DragPanel()
{
p = new Point();
setOpaque(true);
createLabels();
action = new SelectableAction(this);
addMouseListener(action);
addMouseMotionListener(action);
}
private void createLabels() {
labels = new JLabel[8][8];
Dimension dim50 = new Dimension(50,50);
GridBagConstraints gbc = new GridBagConstraints();
this.setLayout(new GridBagLayout());
for (int x=0;x<8;x++){
for (int y=0;y<8;y++){
labels[x][y] = new JLabel();
labels[x][y].setOpaque(true);
labels[x][y].setPreferredSize(dim50);
String str = new String("("+x+","+y+")");
labels[x][y].setText(str);
if ((x+y) % 2 == 0){
labels[x][y].setBackground(Color.lightGray);
} else
{
labels[x][y].setBackground(Color.white);
}
gbc.gridx = x;
gbc.gridy = 7-y;
this.add(labels[x][y],gbc);
}
URL url = getClass().getResource("images/50px-Knight.pgn");
Image img;
try {
img = ImageIO.read(url);
labels[0][0].setIcon(new ImageIcon(img));
} catch (IOException e) {
e.printStackTrace();
}
}
}
public JLabel[][] getLabels()
{
return labels;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(action.dragging)
g.drawImage(image, p.x, p.y, this);
}
public void setImage(Image i)
{
image = i;
}
public void setOrigin(Point p)
{
this.p = p;
repaint();
}
}
/**
* Mouse code to enable image dragging
*/
class SelectableAction extends MouseInputAdapter
{
DragPanel MyPanel;
Image selectedImage;
boolean dragging;
Rectangle r;
Point offset;
public SelectableAction(DragPanel dp)
{
MyPanel = dp;
dragging = false;
offset = new Point();
}
public void mousePressed(MouseEvent e)
{
Point p = e.getPoint();
JLabel[][] labels = MyPanel.getLabels();
for(int i = 0; i < labels.length; i++)
{
for (int j=0;j<labels[0].length;j++){
r = labels[i][j].getBounds();
if(r.contains(p))
{
if ( ((ImageIcon)labels[i][j].getIcon()).getImage() != null) {
selectedImage = ((ImageIcon)labels[i][j].getIcon()).getImage();
MyPanel.setImage(selectedImage);
labels[i][j].setIcon(null);
offset.x = p.x - r.x;
offset.y = p.y - r.y;
dragging = true;
MyPanel.setOrigin(new Point(r.x, r.y));
break;
}
}
}
}
}
public void mouseReleased(MouseEvent e)
{
Point p = e.getPoint();
JLabel[][] labels = MyPanel.getLabels();
for(int i = 0; i < labels.length; i++)
{
for (int j=0;j<labels[0].length; j++){
r = labels[i][j].getBounds();
if(r.contains(p)) {
ImageIcon tmpIcon = new ImageIcon(selectedImage);
labels[i][j].setIcon(tmpIcon);
MyPanel.repaint();
dragging = false;
}
}
}
}
public void mouseDragged(MouseEvent e)
{
if(dragging)
{
r.x = e.getX() - offset.x;
r.y = e.getY() - offset.y;
MyPanel.setOrigin(new Point(r.x, r.y));
}
}
}
【问题讨论】:
-
将
public void paint(Graphics g)更改为public void paintComponent(Graphics g)(并将呼叫更改为super)。 -
谢谢。我已经尝试过了,但是它会导致组件在拖动过程中消失...
-
它消失了,因为你有不透明的子组件在上面绘制自己。否则,它会在我的计算机上正确流畅地运行。我试过这张图片:“
http://i1195.photobucket.com/albums/aa398/EricMMann/Design1/Knight.png”,没问题。 -
为什么这段代码没有从
java.awt.dnd导入任何东西? -
抱歉,但是当我尝试使用此代码时: public void paintcomponent(Graphics g) { super.paintComponent(g); if(action.dragging) g.drawImage(image, p.x, p.y, this); },组件消失了,我不明白为什么。我应该遗漏一些东西......