I have code here that displays a swing window with four jacks on it. I would like to be able to click and move the jacks around the window. I know they need to be redrawn but I'm not sure how to go about that.
How can I make it so a user could click and move the cards?
package p2test;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.awt.*;
public class main
{
public static final int PERIMETER_BEVEL = 20; //space between panel border and perimeter cards
public static final int LEFT_PERIMETER_BEVEL = 98;
public static final int INTERIOR_BEVEL = 5; //space between cards
public static final int CARD_HEIGHT = 97;
public static final int CARD_WIDTH = 73;
public static final int PANEL_HEIGHT = (2*PERIMETER_BEVEL) + (4*CARD_HEIGHT) + (3*INTERIOR_BEVEL);
public static final int PANEL_WIDTH = (2*PERIMETER_BEVEL) + (14*CARD_WIDTH) + (13*INTERIOR_BEVEL);
public static final String BACKGROUND_COLOR = "#64C866"; //window background color [hex]
public static final String CARD_FOLDER = "cardImages"; //default folder containing images
public static final String [] RANKS = { "jack"};
public static final ArrayList<String> ranks = new ArrayList<String>(Arrays.asList(RANKS));
public static void main(String[] args)
{
JFrame window = new JFrame("deck");
JPanel panel = new JPanel() {
public void paintComponent(Graphics g) { //find each rank of card in increasing
super.paintComponent(g); //order as specified in the array. All
File[] files = new File(CARD_FOLDER).listFiles(); //ranks appear in the same suit order in
//the filesystem so suits will automatically
//be in order when printing in groups of four
//cards.
int counter = 0;
for(String rank : ranks) {
for(File filename : files) {
if(filename.getName().contains(rank)) {
new ImageIcon(filename.getPath()).paintIcon(this, g,
LEFT_PERIMETER_BEVEL + (counter/4) * (CARD_WIDTH + INTERIOR_BEVEL),
PERIMETER_BEVEL + (3-(counter%4)) * (CARD_HEIGHT + INTERIOR_BEVEL));
counter++;
//counter/4 keeps track of the correct column
//3-(counter%4) keeps track of the correct row
//in which to print the card image
}
}
}
}
};
panel.setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setBackground(Color.decode(BACKGROUND_COLOR));
window.add(panel);
window.setVisible(true);
window.pack();
}
}
I was able to get the cards to move by adding this. A much better way of implementing this would be to follow what MadProgrammer and Andrew Thompson suggested.
public static MouseInputAdapter mouseHandler = new MouseInputAdapter(){
//internal JLabel displacement on mouse press for smooth dragging
public int labelDisX;
//internal JLabel displacement on mouse press for smooth dragging
public int labelDisY;
public void mousePressed(MouseEvent e) {
labelDisX = e.getX();
labelDisY = e.getY();
//move the card above all others
e.getComponent().getParent().setComponentZOrder(e.getComponent(), 0);
//repaint so card moves above others
e.getComponent().getParent().repaint();
}
public void mouseDragged (MouseEvent e) {
JPanel panel = (JPanel) e.getComponent().getParent();
//get preliminary new X coordinate
int newX = e.getComponent().getX() + e.getX() - labelDisX;
//get preliminary new Y coordinate
int newY = e.getComponent().getY() + e.getY() - labelDisY;
//here we check that the card is not
//being moved off the panel. If the
//user does try and do this then
//make the new coordinates such that
//the card is bounded by the panel's
//edges [extra credit]
if(newX > panel.getWidth() - CARD_WIDTH) {
newX = panel.getWidth() - CARD_WIDTH;
}
if(newY > panel.getHeight() - CARD_HEIGHT) {
newY = panel.getHeight() - CARD_HEIGHT;
}
if(newX < 0) { newX = 0; }
if(newY < 0) { newY = 0; }
e.getComponent().setLocation(newX, newY);
}
};