Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.gui > #2080 > unrolled thread

Clipped image when g.draw

Started by"A. Farber" <a..farber@THRWHITE.remove-dii-this>
First post2011-04-27 15:37 +0000
Last post2011-04-27 15:37 +0000
Articles 6 — 3 participants

Back to article view | Back to comp.lang.java.gui


Contents

  Clipped image when g.draw "A. Farber" <a..farber@THRWHITE.remove-dii-this> - 2011-04-27 15:37 +0000
    Re: Clipped image when g. "Roedy Green" <roedy.green@THRWHITE.remove-dii-this> - 2011-04-27 15:37 +0000
      Re: Clipped image when g. "A. Farber" <a..farber@THRWHITE.remove-dii-this> - 2011-04-27 15:37 +0000
    Re: Clipped image when g. "Ian Shef" <ian.shef@THRWHITE.remove-dii-this> - 2011-04-27 15:37 +0000
      Re: Clipped image when g. "A. Farber" <a..farber@THRWHITE.remove-dii-this> - 2011-04-27 15:37 +0000
        Re: Clipped image when g. "Ian Shef" <ian.shef@THRWHITE.remove-dii-this> - 2011-04-27 15:37 +0000

#2080 — Clipped image when g.draw

From"A. Farber" <a..farber@THRWHITE.remove-dii-this>
Date2011-04-27 15:37 +0000
SubjectClipped image when g.draw
Message-ID<1184800734.241660.17260@x35g2000prf.googlegroups.com>
  To: comp.lang.java.gui
Hello,

I've created a class (full source code at the bottom)
which extends java.awt.Component and is supposed to
represent a playing card. If the card is being dragged,
I'd like to draw a shadow underneath it. And the card
itself should be drawn a little bit displaced - to make
the impression that it has been lifted:

	public void paint(Graphics g) {
		if (this == dragged) {
			g.drawImage(shadow, 0, 0, this);
			g.drawImage(cardImg, -3, -4, this);
		} else {
			g.drawImage(cardImg, 0, 0, this);
		}
	}

My problem is however that the cardImg is being
clipped. Does anybody please have an idea how
to workaround this?

Thank you
Alex

PS: Here is the full source code:

// $Id: Card.java,v 1.2 2007/07/18 10:10:33 afarber Exp $

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;

class Card extends Component implements MouseListener,
MouseMotionListener
{
	public static final int		WIDTH = 70;
	public static final int		HEIGHT = 100;

	public static final int		SPADE   = 0;
	public static final int		CLUB    = 1;
	public static final int		DIAMOND = 2;
	public static final int		HEART   = 3;
	public static final int		NOTRUMP = 4;

	private static Card		dragged;

	private static Image[][]	faces;
	private static Image		back;
	private static Image		shadow;

	public byte			rank, suit;
	public boolean			opened;
	public int			whose;

	public Card(int rank, int suit) {
		setSize(WIDTH, HEIGHT);
		addMouseListener(this);
		addMouseMotionListener(this);

		this.rank = (byte) rank;
		this.suit = (byte) suit;
	}

	public Card(char ch) {
		setSize(WIDTH, HEIGHT);
		addMouseListener(this);
		addMouseMotionListener(this);

		rank = (byte) (ch >> 8);
		suit = (byte) ch;
	}

	public boolean equals(Card card) {
		return (rank == card.rank && suit == card.suit);
	}

	public char toChar() {
		return (char) ((rank << 8) | suit);
	}

	public void paint(Graphics g) {
		if (this == dragged) {
			g.drawImage(shadow, 0, 0, this);

                        // XXX the image below is clipped :-(
			g.drawImage(opened ? faces[rank][suit] : back,
			    -3, -4, this);
		} else {
			g.drawImage(opened ? faces[rank][suit] : back,
			    0, 0, this);
		}
	}

	public static void prepImages(Image big) {
		ImageProducer source = big.getSource();

		// create 32 card images
		faces = new Image[8][4];
		for (int rank = 0; rank < 8; rank++)
			for (int suit = SPADE; suit <= HEART; suit++) {
				ImageFilter filter =
				    new CropImageFilter(rank * WIDTH,
				    suit * HEIGHT, WIDTH, HEIGHT);
				ImageProducer producer = new
				    FilteredImageSource(source, filter);
				faces[rank][suit] = Toolkit.getDefaultToolkit()
				    .createImage(producer);
			}
		// create the image of a card's back
		ImageFilter filter =
		    new CropImageFilter(560, 0, WIDTH, HEIGHT);
		ImageProducer producer =
		    new FilteredImageSource(source, filter);
		back = Toolkit.getDefaultToolkit().createImage(producer);
		// use a card shape to create shadow
		int[] pixels = new int[WIDTH * HEIGHT];
		PixelGrabber grabber = new PixelGrabber(big, 0, 0,
		    WIDTH, HEIGHT, pixels, 0, WIDTH);
		try {
			grabber.grabPixels();
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
		// turn non-transparent pixels to shadow
		for (int i = 0; i < pixels.length; i++)
			if (0 != (pixels[i] & 0xFF000000))
				pixels[i] = 0x60000000;
		shadow = Toolkit.getDefaultToolkit().createImage(
		    new MemoryImageSource(WIDTH, HEIGHT, pixels, 0, WIDTH));
	}

	public void mouseExited(MouseEvent event) {
		System.out.println("mouseExited:" + event);
		dragged = null;
		getParent().repaint();
	}

	public void mouseReleased(MouseEvent event) {
		System.out.println("mouseReleased" + event);
		dragged = null;
		getParent().repaint();
	}

	public void mousePressed(MouseEvent event) {
		System.out.println("mousePressed" + event);
		dragged = this;
		getParent().repaint();
	}

	public void mouseEntered(MouseEvent event) {
		System.out.println("mouseEntered" + event);
	}

	public void mouseClicked(MouseEvent event) {
		System.out.println("mouseClicked" + event);
	}

	public void mouseMoved(MouseEvent event) {
		System.out.println("mouseMoved" + event);
	}

	public void mouseDragged(MouseEvent event) {
		System.out.println("mouseDragged" + event);
	}

	public static int randomRank() {
		return (int) Math.floor(8.0 * Math.random());
	}

	public static int randomSuit() {
		return (int) Math.floor(4.0 * Math.random());
	}

	public static void main(String args[]) {
		Frame frame = new Frame("Card Test");
		frame.setForeground(Color.white);
		frame.setBackground(Color.gray);
		frame.setLayout(null);

		final String PATH = "media/cards.gif";
		Image big = Toolkit.getDefaultToolkit().getImage(PATH);
		MediaTracker tracker = new MediaTracker(frame);
		tracker.addImage(big, 0);
		try {
			tracker.waitForAll();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		if (tracker.isErrorAny()) {
			System.err.println("Image " + PATH + " not found");
			return;
		}

		Card.prepImages(big);
		Card card = new Card(randomRank(), randomSuit());
		card.opened = true;
		frame.add(card);
		frame.validate();
		card.setLocation(200, 100);

		frame.setSize(400, 300);
		frame.setVisible(true);
	}
}

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [next] | [standalone]


#2081 — Re: Clipped image when g.

From"Roedy Green" <roedy.green@THRWHITE.remove-dii-this>
Date2011-04-27 15:37 +0000
SubjectRe: Clipped image when g.
Message-ID<n1nt939e3ulrh2du5cu0qglue26ab8ikvs@4ax.com>
In reply to#2080
  To: comp.lang.java.gui
On Wed, 18 Jul 2007 23:18:54 -0000, "A. Farber"
<Alexander.Farber@gmail.com> wrote, quoted or indirectly quoted
someone who said :

>frame.validate();
>		card.setLocation(200, 100);
>
>		frame.setSize(400, 300);
You need to force the size of the card.

Dimension d = new Dimension( width, height );
        this.setPreferredSize( d );
        this.setMinimumSize( d );
        this.setMaximumSize( d );
-- 
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [next] | [standalone]


#2098 — Re: Clipped image when g.

From"A. Farber" <a..farber@THRWHITE.remove-dii-this>
Date2011-04-27 15:37 +0000
SubjectRe: Clipped image when g.
Message-ID<1184922170.955230.209010@q75g2000hsh.googlegroups.com>
In reply to#2081
  To: comp.lang.java.gui
On Jul 19, 5:38 am, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:
> >frame.validate();
> >            card.setLocation(200, 100);
>
> >            frame.setSize(400, 300);
>
> You need to force the size of the card.
>
> Dimension d = new Dimension( width, height );
>         this.setPreferredSize( d );
>         this.setMinimumSize( d );
>         this.setMaximumSize( d );

No, I'd like the parent frame to be bigger,
so that I can drag my Card Component around.

Or have I misunderstood you?

Regards
Alex

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [next] | [standalone]


#2089 — Re: Clipped image when g.

From"Ian Shef" <ian.shef@THRWHITE.remove-dii-this>
Date2011-04-27 15:37 +0000
SubjectRe: Clipped image when g.
Message-ID<Xns99727CF038A36vaj4088ianshef@138.126.254.210>
In reply to#2080
  To: comp.lang.java.gui
"A. Farber" <Alexander.Farber@gmail.com> wrote in 
news:1184800734.241660.17260@x35g2000prf.googlegroups.com:

> Hello,
> 
> I've created a class (full source code at the bottom)
> which extends java.awt.Component and is supposed to
> represent a playing card. If the card is being dragged,
> I'd like to draw a shadow underneath it. And the card
> itself should be drawn a little bit displaced - to make
> the impression that it has been lifted:
> 
>      public void paint(Graphics g) {
>           if (this == dragged) {
>                g.drawImage(shadow, 0, 0, this);
>                g.drawImage(cardImg, -3, -4, this);
>           } else {
>                g.drawImage(cardImg, 0, 0, this);
>           }
>      }
> 
> My problem is however that the cardImg is being
> clipped. Does anybody please have an idea how
> to workaround this?
> 
> Thank you
> Alex
From the java docs on the update(...) method of Component:

The origin of the graphics context, its (0, 0) coordinate point, is the 
top-left corner of this component. The clipping region of the graphics 
context is the bounding rectangle of this component. 

I believe that this is true for the paint(...) method as well.  Basically, 
it says that any pixels with a negative x or y will not be drawn.

You may be able to use setClip(...) to change the clipping rectangle prior 
to your attempt to draw the displaced card.

If setClip(...) doesn't work for you, there are other solutions, such as 
defining your Card to be slightly larger than needed, and drawing the image 
with the appropriate displacement within its bounding rectangle.

Write back and let us know what worked!


-- 
Ian Shef     805/F6      *    These are my personal opinions    
Raytheon Company         *    and not those of my employer.
PO Box 11337             * 
Tucson, AZ 85734-1337    *

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [next] | [standalone]


#2097 — Re: Clipped image when g.

From"A. Farber" <a..farber@THRWHITE.remove-dii-this>
Date2011-04-27 15:37 +0000
SubjectRe: Clipped image when g.
Message-ID<1184921933.889932.228120@k79g2000hse.googlegroups.com>
In reply to#2089
  To: comp.lang.java.gui
Hello Ian,

On Jul 19, 9:16 pm, Ian Shef <inva...@avoiding.spam> wrote:
> "A. Farber" <Alexander.Far...@gmail.com> wrote innews:1184800734.241660.17260@x35g2000prf.googlegroups.com:
> > If the card is being dragged,
> > I'd like to draw a shadow underneath it. And the card
> > itself should be drawn a little bit displaced - to make
> > the impression that it has been lifted:
>
> >      public void paint(Graphics g) {
> >           if (this == dragged) {
> >                g.drawImage(shadow, 0, 0, this);
> >                g.drawImage(cardImg, -3, -4, this);
> >           } else {
> >                g.drawImage(cardImg, 0, 0, this);
> >           }
> >      }
>
> > My problem is however that the cardImg is being
> > clipped.

> any pixels with a negative x or y will not be drawn.
>
> You may be able to use setClip(...) to change the clipping rectangle prior
> to your attempt to draw the displaced card.
>
> If setClip(...) doesn't work for you, there are other solutions, such as
> defining your Card to be slightly larger than needed, and drawing the image
> with the appropriate displacement within its bounding rectangle.

yes, setClip with negative x and y hasn't worked for me.

I've end up making my component a bit bigger:

class Card extends Component
{
        public static final int         WIDTH  = 70;
        public static final int         HEIGHT = 100;

        // shadow offsets
        public static final int         SHDX = 3;
        public static final int         SHDY = 4;

        private static Card             dragged;
.....
        protected Card() {
                // make the card bigger or the shadow will be clipped
                setSize(WIDTH + SHDX, HEIGHT + SHDY);

                enableEvents(AWTEvent.MOUSE_EVENT_MASK |
                    AWTEvent.MOUSE_MOTION_EVENT_MASK);
        }
....
        public void paint(Graphics g) {
                if (this == dragged)
                        g.drawImage(shadow, SHDX, SHDY, this);
                else
                        g.translate(SHDX, SHDY);
                g.drawImage(opened ? faces[rank][suit] : back, 0, 0,
this);
        }

This has the problem that when the card isn't being dragged,
then it is displaced a bit - it is located at SHDX, SHDY instead
of Component's 0, 0.  But I can live with it...

Now I'm struggling with 2 further problems -

1) my Card LW component flickers even though the Deck
    LW Container (represents playing table) to which I add
    it is double-buffered. (Yes I've read few docs about
    flickering LW  Components, but still can't fix it)

2) Defining a custom AWT event turned out to be such
    a pain! I wanted my Card to send an event to listeners
    after it has been dragged and released (i.e. the card
   has been played), but have ended up with this hack:

        protected void processMouseEvent(MouseEvent event) {
                if (event.getID() == MouseEvent.MOUSE_PRESSED) {
                        oldX = getLocation().x;
                        oldY = getLocation().y;

                        relX = event.getX();
                        relY = event.getY();

                        dragged = this;
                } else if (event.getID() == MouseEvent.MOUSE_RELEASED)
{
                        // pass the mouse released event to the
listeners,
                        // but only if this card has been dragged
around
                        if (dragged != null) {
                                super.processMouseEvent(event);

                                dragged = null;
                        }
                }
        }

Regards
Alex

PS: And here is my full source code:

// $Id: Card.java,v 1.5 2007/07/19 15:19:46 afarber Exp $

// Card lightweight component which sends a MouseEvent to the
// listeners when it has been dragged around and released

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;

class Card extends Component
{
	public static final int		WIDTH  = 70;
	public static final int		HEIGHT = 100;

	// shadow offsets
	public static final int		SHDX = 3;
	public static final int		SHDY = 4;

	public static final int		SPADE   = 0;
	public static final int		CLUB    = 1;
	public static final int		DIAMOND = 2;
	public static final int		HEART   = 3;
	public static final int		NOTRUMP = 4;

	// which cards may be moved
	public static int		allowedOwner;
	public static int		allowedSuit = NOTRUMP;

	private static Card		dragged;
	private static Image[][]	faces;
	private static Image		back;
	private static Image		shadow;
	private int			         oldX, oldY;
	// position of the mouse pointer inside the card, when pressed
	private int			         relX, relY;

	public byte			     rank, suit;
	public boolean			opened;
	// 0, 1, 2 = card belongs to a player; 3 = is on the table
	public int			      owner;

	public final static String[] SUIT = {
		" spades",
		" clubs",
		" diamonds",
		" hearts"
	};
	public final static String[] RANK4 = {
		"7",
		"8",
		"9",
		"10",
		"J",
		"Q",
		"K",
		"A"
	};

	protected Card() {
		// make the card bigger or the shadow will be clipped
		setSize(WIDTH + SHDX, HEIGHT + SHDY);

		enableEvents(AWTEvent.MOUSE_EVENT_MASK |
		    AWTEvent.MOUSE_MOTION_EVENT_MASK);
	}

	public Card(int rank, int suit) {
		this();

		this.rank = (byte) rank;
		this.suit = (byte) suit;
	}

	public Card(char ch) {
		this();

		rank = (byte) (ch >> 8);
		suit = (byte) ch;
	}

	public boolean equals(Card card) {
		return (rank == card.rank && suit == card.suit);
	}

	public char toChar() {
		return (char) ((rank << 8) | suit);
	}

	public void update(Graphics g) {
	}

	public void paint(Graphics g) {
		if (this == dragged)
			g.drawImage(shadow, SHDX, SHDY, this);
		else
			g.translate(SHDX, SHDY);
		g.drawImage(opened ? faces[rank][suit] : back, 0, 0, this);
	}

	public static void prepImages(Image big) {
		ImageProducer source = big.getSource();

		// create 32 card images
		faces = new Image[8][4];
		for (int rank = 0; rank < 8; rank++)
			for (int suit = SPADE; suit <= HEART; suit++) {
				ImageFilter filter =
				    new CropImageFilter(rank * WIDTH,
				    suit * HEIGHT, WIDTH, HEIGHT);
				ImageProducer producer = new
				    FilteredImageSource(source, filter);
				faces[rank][suit] = Toolkit.getDefaultToolkit()
				    .createImage(producer);
			}
		// create the image of a card's back
		ImageFilter filter =
		    new CropImageFilter(560, 0, WIDTH, HEIGHT);
		ImageProducer producer =
		    new FilteredImageSource(source, filter);
		back = Toolkit.getDefaultToolkit().createImage(producer);
		// use a card shape to create shadow
		int[] pixels = new int[WIDTH * HEIGHT];
		PixelGrabber grabber = new PixelGrabber(big, 0, 0,
		    WIDTH, HEIGHT, pixels, 0, WIDTH);
		try {
			grabber.grabPixels();
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
		// turn non-transparent pixels to shadow
		for (int i = 0; i < pixels.length; i++)
			if (0 != (pixels[i] & 0xFF000000))
				pixels[i] = 0x60000000;
		shadow = Toolkit.getDefaultToolkit().createImage(
		    new MemoryImageSource(WIDTH, HEIGHT, pixels, 0, WIDTH));
	}

	protected void processMouseEvent(MouseEvent event) {
		if (event.getID() == MouseEvent.MOUSE_PRESSED) {
			oldX = getLocation().x;
			oldY = getLocation().y;

			relX = event.getX();
			relY = event.getY();

			dragged = this;
		} else if (event.getID() == MouseEvent.MOUSE_RELEASED) {
			// pass the mouse released event to the listeners,
			// but only if this card has been dragged around
			if (dragged != null) {
				super.processMouseEvent(event);

				dragged = null;
			}
		}
	}

	protected void processMouseMotionEvent(MouseEvent event) {
		if (event.getID() == MouseEvent.MOUSE_DRAGGED) {
			// XXX check allowedOwner + allowedSuit
			// XXX here and display a red glow

			Point loc = getLocation();
			event.translatePoint(loc.x, loc.y);
			setLocation(event.getX() - relX, event.getY() - relY);
		}
	}

	public void putBack() {
		setLocation(oldX, oldY);
	}

	public static int randomRank() {
		return (int) Math.floor(8.0 * Math.random());
	}

	public static int randomSuit() {
		return (int) Math.floor(4.0 * Math.random());
	}

	// FOR TESTING: gmake build/Card.class && java -cp build/ Card
	public static void main(String args[]) {
		Frame frame = new Frame("Card Test");
		frame.setForeground(Color.white);
		frame.setBackground(Color.gray);
		frame.setLayout(null);

		final String PATH = "media/cards.gif";
		Image big = Toolkit.getDefaultToolkit().getImage(PATH);
		MediaTracker tracker = new MediaTracker(frame);
		tracker.addImage(big, 0);
		try {
			tracker.waitForAll();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		if (tracker.isErrorAny()) {
			System.err.println("Image " + PATH + " not found");
			return;
		}

		Card.prepImages(big);
		Card card = new Card(randomRank(), randomSuit());
		card.opened = true;

		card.addMouseListener(new MouseAdapter() {
			public void mouseReleased(MouseEvent event) {
				//System.out.println("mouseReleased" + event);

				Card card = (Card) event.getSource();

				System.out.println("The card (" +
				     RANK4[card.rank] + ", " +
				     SUIT[card.suit] + ") has been played!");

				card.putBack();
			}
		});

		frame.add(card);
		frame.validate();
		card.setLocation(200, 100);

		frame.setSize(400, 300);
		frame.setVisible(true);
	}
}

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [next] | [standalone]


#2126 — Re: Clipped image when g.

From"Ian Shef" <ian.shef@THRWHITE.remove-dii-this>
Date2011-04-27 15:37 +0000
SubjectRe: Clipped image when g.
Message-ID<Xns997783D31D5Evaj4088ianshef@138.126.254.210>
In reply to#2097
  To: comp.lang.java.gui
"A. Farber" <Alexander.Farber@gmail.com> wrote in
news:1184921933.889932.228120@k79g2000hse.googlegroups.com: 
<SNIP>
> Now I'm struggling with 2 further problems -
> 
> 1) my Card LW component flickers even though the Deck
>     LW Container (represents playing table) to which I add
>     it is double-buffered. (Yes I've read few docs about
>     flickering LW  Components, but still can't fix it)

I don't understand.  As far as I know, there is no double-buffering in AWT 
except for the BufferStrategy stuff that was added in version 1.4.  Is this 
what you are doing?
On the other hand, Swing has double buffering.  Are you mixing AWT and 
Swing?

If it is either of these two cases above, I can't help you.  I haven't 
worked with BufferStrategy, and I haven't mixed AWT and Swing.
I have performed double buffering in AWT by handling it myself, forcing 
paint(...) and update(...) to perform writing on my own buffer, and then 
copying the buffer to the screen myself.  I would have to really dig to 
find the code where I did this.
> 
> 2) Defining a custom AWT event turned out to be such
>     a pain! I wanted my Card to send an event to listeners
>     after it has been dragged and released (i.e. the card
>    has been played), but have ended up with this hack:
> 
>         protected void processMouseEvent(MouseEvent event) {
>                 if (event.getID() == MouseEvent.MOUSE_PRESSED) {
>                         oldX = getLocation().x;
>                         oldY = getLocation().y;
> 
>                         relX = event.getX();
>                         relY = event.getY();
> 
>                         dragged = this;
>                 } else if (event.getID() == MouseEvent.MOUSE_RELEASED)
> {
>                         // pass the mouse released event to the
> listeners,
>                         // but only if this card has been dragged
> around
>                         if (dragged != null) {
>                                 super.processMouseEvent(event);
> 
>                                 dragged = null;
>                         }
>                 }
>         }

I have never defined custom AWT events, so I can't help.  Typically (in 
AWT) I have done something along the lines of what you did.

Perhaps it is not too late to switch to Swing?
> 
> Regards
> Alex
> 
> PS: And here is my full source code:
> 
> // $Id: Card.java,v 1.5 2007/07/19 15:19:46 afarber Exp $
> 
> // Card lightweight component which sends a MouseEvent to the
> // listeners when it has been dragged around and released
> 
> import java.awt.*;
> import java.awt.image.*;
> import java.awt.event.*;
> 
> class Card extends Component
> {
>      public static final int          WIDTH  = 70;
>      public static final int          HEIGHT = 100;
> 
>      // shadow offsets
>      public static final int          SHDX = 3;
>      public static final int          SHDY = 4;
> 
>      public static final int          SPADE   = 0;
>      public static final int          CLUB    = 1;
>      public static final int          DIAMOND = 2;
>      public static final int          HEART   = 3;
>      public static final int          NOTRUMP = 4;
> 
>      // which cards may be moved
>      public static int          allowedOwner;
>      public static int          allowedSuit = NOTRUMP;
> 
>      private static Card          dragged;
>      private static Image[][]     faces;
>      private static Image          back;
>      private static Image          shadow;
>      private int                        oldX, oldY;
>      // position of the mouse pointer inside the card, when pressed
>      private int                        relX, relY;
> 
>      public byte                    rank, suit;
>      public boolean               opened;
>      // 0, 1, 2 = card belongs to a player; 3 = is on the table
>      public int                     owner;
> 
>      public final static String[] SUIT = {
>           " spades",
>           " clubs",
>           " diamonds",
>           " hearts"
>      };
>      public final static String[] RANK4 = {
>           "7",
>           "8",
>           "9",
>           "10",
>           "J",
>           "Q",
>           "K",
>           "A"
>      };
> 
>      protected Card() {
>           // make the card bigger or the shadow will be clipped
>           setSize(WIDTH + SHDX, HEIGHT + SHDY);
> 
>           enableEvents(AWTEvent.MOUSE_EVENT_MASK |
>               AWTEvent.MOUSE_MOTION_EVENT_MASK);
>      }
> 
>      public Card(int rank, int suit) {
>           this();
> 
>           this.rank = (byte) rank;
>           this.suit = (byte) suit;
>      }
> 
>      public Card(char ch) {
>           this();
> 
>           rank = (byte) (ch >> 8);
>           suit = (byte) ch;
>      }
> 
>      public boolean equals(Card card) {
>           return (rank == card.rank && suit == card.suit);
>      }
> 
>      public char toChar() {
>           return (char) ((rank << 8) | suit);
>      }
> 
>      public void update(Graphics g) {
>      }
> 
>      public void paint(Graphics g) {
>           if (this == dragged)
>                g.drawImage(shadow, SHDX, SHDY, this);
>           else
>                g.translate(SHDX, SHDY);
>           g.drawImage(opened ? faces[rank][suit] : back, 0, 0, this);
>      }
> 
>      public static void prepImages(Image big) {
>           ImageProducer source = big.getSource();
> 
>           // create 32 card images
>           faces = new Image[8][4];
>           for (int rank = 0; rank < 8; rank++)
>                for (int suit = SPADE; suit <= HEART; suit++) {
>                     ImageFilter filter =
>                         new CropImageFilter(rank * WIDTH,
>                         suit * HEIGHT, WIDTH, HEIGHT);
>                     ImageProducer producer = new
>                         FilteredImageSource(source, filter);
>                     faces[rank][suit] = Toolkit.getDefaultToolkit()
>                         .createImage(producer);
>                }
>           // create the image of a card's back
>           ImageFilter filter =
>               new CropImageFilter(560, 0, WIDTH, HEIGHT);
>           ImageProducer producer =
>               new FilteredImageSource(source, filter);
>           back = Toolkit.getDefaultToolkit().createImage(producer);
>           // use a card shape to create shadow
>           int[] pixels = new int[WIDTH * HEIGHT];
>           PixelGrabber grabber = new PixelGrabber(big, 0, 0,
>               WIDTH, HEIGHT, pixels, 0, WIDTH);
>           try {
>                grabber.grabPixels();
>           } catch (InterruptedException ex) {
>                ex.printStackTrace();
>           }
>           // turn non-transparent pixels to shadow
>           for (int i = 0; i < pixels.length; i++)
>                if (0 != (pixels[i] & 0xFF000000))
>                     pixels[i] = 0x60000000;
>           shadow = Toolkit.getDefaultToolkit().createImage(
>               new MemoryImageSource(WIDTH, HEIGHT, pixels, 0, WIDTH));
>      }
> 
>      protected void processMouseEvent(MouseEvent event) {
>           if (event.getID() == MouseEvent.MOUSE_PRESSED) {
>                oldX = getLocation().x;
>                oldY = getLocation().y;
> 
>                relX = event.getX();
>                relY = event.getY();
> 
>                dragged = this;
>           } else if (event.getID() == MouseEvent.MOUSE_RELEASED) {
>                // pass the mouse released event to the listeners,
>                // but only if this card has been dragged around
>                if (dragged != null) {
>                     super.processMouseEvent(event);
> 
>                     dragged = null;
>                }
>           }
>      }
> 
>      protected void processMouseMotionEvent(MouseEvent event) {
>           if (event.getID() == MouseEvent.MOUSE_DRAGGED) {
>                // XXX check allowedOwner + allowedSuit
>                // XXX here and display a red glow
> 
>                Point loc = getLocation();
>                event.translatePoint(loc.x, loc.y);
>                setLocation(event.getX() - relX, event.getY() - relY);
>           }
>      }
> 
>      public void putBack() {
>           setLocation(oldX, oldY);
>      }
> 
>      public static int randomRank() {
>           return (int) Math.floor(8.0 * Math.random());
>      }
> 
>      public static int randomSuit() {
>           return (int) Math.floor(4.0 * Math.random());
>      }
> 
>      // FOR TESTING: gmake build/Card.class && java -cp build/ Card
>      public static void main(String args[]) {
>           Frame frame = new Frame("Card Test");
>           frame.setForeground(Color.white);
>           frame.setBackground(Color.gray);
>           frame.setLayout(null);
> 
>           final String PATH = "media/cards.gif";
>           Image big = Toolkit.getDefaultToolkit().getImage(PATH);
>           MediaTracker tracker = new MediaTracker(frame);
>           tracker.addImage(big, 0);
>           try {
>                tracker.waitForAll();
>           } catch (Exception ex) {
>                ex.printStackTrace();
>           }
>           if (tracker.isErrorAny()) {
>                System.err.println("Image " + PATH + " not found");
>                return;
>           }
> 
>           Card.prepImages(big);
>           Card card = new Card(randomRank(), randomSuit());
>           card.opened = true;
> 
>           card.addMouseListener(new MouseAdapter() {
>                public void mouseReleased(MouseEvent event) {
>                     //System.out.println("mouseReleased" + event);
> 
>                     Card card = (Card) event.getSource();
> 
>                     System.out.println("The card (" +
>                          RANK4[card.rank] + ", " +
>                          SUIT[card.suit] + ") has been played!");
> 
>                     card.putBack();
>                }
>           });
> 
>           frame.add(card);
>           frame.validate();
>           card.setLocation(200, 100);
> 
>           frame.setSize(400, 300);
>           frame.setVisible(true);
>      }
> }
> 
> 



-- 
Ian Shef     805/F6      *    These are my personal opinions    
Raytheon Company         *    and not those of my employer.
PO Box 11337             * 
Tucson, AZ 85734-1337    *

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.gui


csiph-web