为什么拖动此jpanel会产生屏幕撕裂效果?

时间:2019-03-29 14:54:40

标签: java swing jpanel

将这些作为jPanel对象的“瓦片”彼此或另一个Jpanel拖动时,它们会留下通过该对象的路径的轮廓。

我尝试在每次由eventListener拖动或单击面板时使用面板上的repaint功能,但这似乎无法解决问题。

/// tile class
import javax.swing.*;
import java.awt.*;

public class Tile extends JPanel {
 private static final long serialVersionUID = 1L;
 /** Tile objects to be added to the game board.
  * The constructor should eventually create the maze pattern
  * and determine the tiles initial location. 
  */
 DragListener drag;
 public int ID;
 Tile()
 {
  drag = new DragListener();

  this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
  this.addMouseListener( drag );
  this.addMouseMotionListener( drag );
 }

 public void paint(Graphics t)
 {
  t.setFont(new Font("Ariel",0,18));
  FontMetrics fm = getFontMetrics(new Font("Ariel",0,18));
  String id = Integer.toString(ID);
  t.setColor(Color.white);
  t.fillRect(0, 0, 80, 80);
  t.drawRect(0, 0, 80, 80);
  t.setColor(Color.black);
  t.drawString(id,5,20);
 }
}


// my drag listener class

import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;

import javax.swing.event.MouseInputAdapter;

public class DragListener extends MouseInputAdapter {

        Point location;
        MouseEvent pressed;
        int tileID;
        int [] gridPos;
        int  initialX, initialY;
        boolean moved = false;
        int buffer =20;

        int [] gridMidX = {327,327,327,327,407,407,407,407,488,488,488,488,568,568,568,568};
        int [] gridMidY = {260,341,421,501,260,341,421,501,260,341,421,501,260,341,421,501};
        public void mousePressed(MouseEvent me)
        {
            pressed = me;
            Component component = me.getComponent();
            location = component.getLocation(location);
            if (!moved) {
            initialX = location.x;
            initialY = location.y; 
            moved = true;
            }
        }

        public void mouseDragged(MouseEvent me)
        {

            Component component = me.getComponent();
            location = component.getLocation(location);
            int x = location.x - pressed.getX() + me.getX();
            int y = location.y - pressed.getY() + me.getY();
            component.setLocation(x, y);

         }
       public void mouseReleased(MouseEvent me) {
           Component component = me.getComponent();
           location = component.getLocation(location);
           int x = location.x;
           int y = location.y;
           int p[] = findSnap(x,y);
           int z = p[0];
           int a = p[1];

            component.setLocation(z, a);
        }
        public int[] findSnap(int x, int y )
        {

         int xp=initialX, yp=initialY;
         int buff =50;
         int pos[] = new int[2];
         if(y>(gridPos[1]+buff) || y < (gridPos[0]-buff)|| x< (gridPos[2] - buff)|| x>(gridPos[3]+buff))
         {
            xp = initialX;
            yp = initialY;

         }
         else{
             //setGrid();
             for(int i=0; i<16; i++) {
                int a = gridMidX[i];
                int b = gridMidY[i];
                int hold [] =  {x,y};
                 if(check(a,b,hold )) {

                    pos[0] = a;
                    pos[1]= b;
                     return pos;
                 }
             }

         }
         pos[0] = xp;
         pos[1] = yp;
         return pos;
        }

        // we need to call in tile

        public boolean check (int e, int f, int [] grid) {

            int nearY,nearX;
            nearX = Math.abs(e-grid[0]);
            nearY = Math.abs(f-grid[1]);            
            if (nearX <=70 && nearY <= 70) {

                return true;
                }

            return false;
        }
}

应该可以将图块拖动到另一个jPanel上,而不会留下拖动它们的痕迹。他们只有在跨JFrame时跨另一个Jpanel时才这样做,似乎没有这个问题。

1 个答案:

答案 0 :(得分:0)

public void paint(Graphics t)

不要覆盖paint()。

通过覆盖paintComponent(...)方法来完成自定义绘画。

然后方法中的第一条语句应该是:

super.paintComponent(...);

确保每次都绘制背景以防止出现伪影。