Java: Example - Card Demo
![]() |
This program displays card images, which can then be dragged around the screen. The images are stored in an array that represents the z coordinate (what's on top of what). This order is never changed even if a card is dragged, which give the peculiar effect of dragging under. It is divided into several source files. The card images are in a zipped file.
|
CardDemo1.java - The main program as a subclass of JFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
// File : GUI-lowlevel/cards1/cards/CardDemo1
// Purpose: Basic GUI to show dragging cards.
// Illustrates how to load images from files.
// Author : Fred Swartz - 2007-02-19 - Placed in public domain.
//
// Enhancements:
// * This really doesn't have a user interface beyond dragging.
// It doesn't do anything, and therefore has no model.
// Make it play a game.
// * Needs to have a Deck class to shuffle, deal, ... Cards.
// Persumably based on ArrayList<Card>.
// * Perhaps a Suit and Face class would be useful.
// * Like Deck, there would also be a class for Hand.
// * May need Player class too.
package cards;
import java.net.URL;
import javax.swing.*;
////////////////////////////////////////////////////////////// class CardDemoGUI
class CardDemo1 extends JFrame {
//=================================================================== fields
private static Card[] _deck = new Card[52];
//===================================================================== main
public static void main(String[] args) {
CardDemo1 window = new CardDemo1();
window.setTitle("Card Demo 1");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setContentPane(new CardTable(_deck));
window.pack();
window.setLocationRelativeTo(null);
window.setVisible(true);
}
//============================================================== constructor
public CardDemo1() {
//... ClassLoader is where to get images from this .jar file.
ClassLoader cldr = this.getClass().getClassLoader();
int n = 0; // Which card.
int xPos = 0; // Where it should be placed initially.
int yPos = 0;
//... Read in the cards using particular file name conventions.
// Images for the backs and Jokers are ignored here.
String suits = "shdc";
String faces = "a23456789tjqk";
for (int suit=0; suit < suits.length(); suit++) {
for (int face=0; face < faces.length(); face++) {
//... Get the image from the images subdirectory.
String imagePath = "cards/images/" + faces.charAt(face) +
suits.charAt(suit) + ".gif";
URL imageURL = cldr.getResource(imagePath);
ImageIcon img = new ImageIcon(imageURL);
//... Create a card and add it to the deck.
Card card = new Card(img);
card.moveTo(xPos, yPos);
_deck[n] = card;
//... Update local vars for next card.
xPos += 5;
yPos += 4;
n++;
}
}
}
}
|
CardTable.java - A subclass of JComponent for displaying the cards
This displays the cards, and listens to mouse events so that it can drag the cards around. There should really be a "model" of a card game, and this would simply interrogate the model to find out what to display, and pass mouse actions to the model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
// File : GUI-lowlevel/cards1/cards/CardTable.java
// Purpose: This is just a JComponent for drawing the cards that are
// showing on the table.
//
// Author : Fred Swartz - February 19, 2007 - Placed in public domain.
//
// Enhancements:
// * Use model. Currently, it is initialized with a whole deck of cards,
// but instead it should be intialized with a "model" which
// it should interrogate (calling model methods) to find out what
// should be displayed.
// * Similarly, actions by the mouse might be used to set things in the
// model, Perhaps by where it's dragged to, or double-clicked, or
// with pop-up menu, or ...
package cards;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
////////////////////////////////////////////////////////////////////// CardTable
public class CardTable extends JComponent implements MouseListener,
MouseMotionListener {
//================================================================ constants
private static final Color BACKGROUND_COLOR = Color.GREEN;
private static final int TABLE_SIZE = 400; // Pixels.
//=================================================================== fields
//... Initial image coords.
private int _initX = 0; // x coord - set from drag
private int _initY = 0; // y coord - set from drag
//... Position in image of mouse press to make dragging look better.
private int _dragFromX = 0; // Displacement inside image of mouse press.
private int _dragFromY = 0;
private Card[] _deck; // Should really be in a model, but ...
private Card _currentCard = null; // Current selected card.
//============================================================== constructor
public CardTable(Card[] deck) {
_deck = deck; // Should be passed a model.
//... Initialize graphics
setPreferredSize(new Dimension(TABLE_SIZE, TABLE_SIZE));
setBackground(Color.blue);
//... Add mouse listeners.
addMouseListener(this);
addMouseMotionListener(this);
}
//=========================================================== paintComponent
@Override
public void paintComponent(Graphics g) {
//... Paint background
int width = getWidth();
int height = getHeight();
g.setColor(BACKGROUND_COLOR);
g.fillRect(0, 0, width, height);
//... Display the cards, starting with the first array element.
// The array order defines the z-axis depth.
for (Card c : _deck) {
c.draw(g, this);
}
}
//====================================================== method mousePressed
// Check to see if press is within any card.
// If it is,
// * Set _currentCard so mouseDragged knows what to drag.
// * Record where in the image (relative to the upper left coordinates)
// the mouse was clicked, because it looks best if we drag from there.
// TODO: Move the card to the last position so that it displays on top.
public void mousePressed(MouseEvent e) {
int x = e.getX(); // Save the x coord of the click
int y = e.getY(); // Save the y coord of the click
//... Find card image this is in. Check from top down.
_currentCard = null; // Assume not in any image.
for (int crd=_deck.length-1; crd>=0; crd--) {
Card testCard = _deck[crd];
if (testCard.contains(x, y)) {
//... Found, remember this card for dragging.
_dragFromX = x - testCard.getX(); // how far from left
_dragFromY = x - testCard.getY(); // how far from top
_currentCard = testCard; // Remember what we're dragging.
break; // Stop when we find the first match.
}
}
}
//============================================================= mouseDragged
// Set x,y to mouse position and repaint.
public void mouseDragged(MouseEvent e) {
if (_currentCard != null) { // Non-null if pressed inside card image.
int newX = e.getX() - _dragFromX;
int newY = e.getY() - _dragFromY;
//--- Don't move the image off the screen sides
newX = Math.max(newX, 0);
newX = Math.min(newX, getWidth() - _currentCard.getWidth());
//--- Don't move the image off top or bottom
newY = Math.max(newY, 0);
newY = Math.min(newY, getHeight() - _currentCard.getHeight());
_currentCard.moveTo(newX, newY);
this.repaint(); // Repaint because position changed.
}
}
//======================================================= method mouseExited
// Turn off dragging if mouse exits panel.
public void mouseExited(MouseEvent e) {
_currentCard = null;
}
//=============================================== Ignore other mouse events.
public void mouseMoved (MouseEvent e) {} // ignore these events
public void mouseEntered(MouseEvent e) {} // ignore these events
public void mouseClicked(MouseEvent e) {} // ignore these events
public void mouseReleased(MouseEvent e) {} // ignore these events
}
|
Card.java - Class representing one card
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
// File : GUI-lowlevel/cards1/cards/Card.java
// Purpose: Represents one card.
// Author : Fred Swartz - February 19, 2007 - Placed in public domain.
//
// Enhancements:
// * Needs to have Suit and Face value.
package cards;
import java.awt.*;
import javax.swing.*;
/////////////////////////////////////////////////////////////////////////// Card
class Card {
//=================================================================== fields
private ImageIcon _image;
private int _x;
private int _y;
//============================================================== constructor
public Card(ImageIcon image) {
_image = image;
}
//=================================================================== moveTo
public void moveTo(int x, int y) {
_x = x;
_y = y;
}
//================================================================= contains
public boolean contains(int x, int y) {
return (x > _x && x < (_x + getWidth()) &&
y > _y && y < (_y + getHeight()));
}
//================================================================= getWidth
public int getWidth() {
return _image.getIconWidth();
}
//================================================================ getHeight
public int getHeight() {
return _image.getIconHeight();
}
//===================================================================== getX
public int getX() {
return _x;
}
//===================================================================== getY
public int getY() {
return _x;
}
//===================================================================== draw
public void draw(Graphics g, Component c) {
_image.paintIcon(c, g, _x, _y);
}
}
|
