0

I have a Java Swing question. I am currently coding the game checkers as an exercise. I created the checkers pieces as JLabels with an ImageIcon of the checkers piece. I added a MouseListener to update the x and y locations of the label on the frame, and am using an ActionListener to set the label location every 5 milliseconds based on a timer. It works except that the label jumps around the screen when I am dragging it with the mouse (instead of tracking with the mouse).

Does anybody know what is causing this? Is there an easy solution based on the code I currently have?

I am new to swing stuff so I realize I could be taking the wrong approach entirely. I am unable to attach the image, but it is just a 80 x 80 px square with a solid black circle in the foreground and the background is transparent. Thanks a lot!

package checkers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.*;

public class Piece2 extends JLabel implements
    ActionListener, MouseListener, MouseMotionListener{

    ImageIcon checkerIcon;
    String color = null;
    Timer t = new Timer(5, this);
    int x, y, width = 80, height = 80;

    public Piece2(int initX, int initY, String color){

        this.x = initX;
        this.y = initY;
        this.color = color;

        t.start();
        setLocation(x, y);
        setSize(width, height);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        addMouseMotionListener(this);
        addMouseListener(this);

        if(color.equals("Red")){
            checkerIcon = new ImageIcon("/RedChecker.png");
        }
        else if(color.equals("Black")){
            checkerIcon = new ImageIcon("/BlackChecker.png");
        }

        setIcon(checkerIcon);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setLocation(x, y);
    }

    /**
     * Mouse Event Listeners
     * 
     */
    @Override
    public void mouseDragged(MouseEvent e) { 
        this.x = e.getX(); 
        this.y = e.getY(); 
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        x = x - (x % 50);
        y = y - (y % 50);           
    }

    @Override
    public void mouseMoved(MouseEvent e) {}

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    //To test Piece
    public static void main(String[] args){
        Piece2 p1 = new Piece2(0, 0, "Black");
        JFrame frame1 = new JFrame("Test");
        frame1.setSize(800, 800);
        frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame1.add(p1);

        frame1.setVisible(true);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Mike D
  • 41
  • 1
  • 3
  • 7
  • 1
    Why do you need the timer to set the location? Also, mouse events are contextual to the source that generated, that means that the position provided by the mouse event is relative to the source (ie 0x0 is the top/left corner of the component that generated the mouse event)... – MadProgrammer Sep 26 '14 at 02:44
  • Yep, don't poll the position of the JLabel. Rather let the MouseListener and MouseMotionListener call repaint and redraw your icon. – Hovercraft Full Of Eels Sep 26 '14 at 02:44
  • 1
    *"..I added a mouseListener to update the x and y locations of the JLabel on the JFrame.."* That seems complicated! I'd use `JButton` instances for the board places displayed with a `GridLayout` and simply `setIcon(..)` to both button (from/to) when a piece moves. E.G. (of part of that) as seen in this [chess GUI](http://stackoverflow.com/q/21142686/418556). – Andrew Thompson Sep 26 '14 at 02:44
  • 1
    I'd use JLabels, but in a fixed grid that accepts the checker image icon, except that is for the dragged JLabel which would be displayed above the board in the glass pane. Please have a look at [this implementation](http://stackoverflow.com/a/25725573/522444) for an example of how to do this. – Hovercraft Full Of Eels Sep 26 '14 at 02:45
  • Thanks for the info. I'm using the timer to redraw the Checker piece object periodically based on updated coordinates. I am most interested in finding out why the JLabel component is "jumping" around the frame when it it is dragged even though the mouseEvent is returning accurate getX and getY info. Does this have something to do with using setLocation() as the way to update the position when repainting? Any thoughts on this? I already have a solution for placing the pieces on the board. I just want the checker dragging animation to look good. – Mike D Sep 26 '14 at 05:23
  • To get smooth movement you'd need to look at implementing drag and drop if the object doesn't explicitly support the operation. Otherwise, yeah, Swing handles the movement very oddly. I worked around this by just resorting to click to select/click target to instantly move, but that's a bit cheap. http://docs.oracle.com/javase/tutorial/uiswing/dnd/intro.html – Gorbles Sep 26 '14 at 10:19

0 Answers0