####################### # CardDemo.java A demo providing multiple buttons to select a playing card. A Panel, using CardLayout control which of four possible subpanels, holding a different card, to display.Uses the following class and images: * CardPanel.java A Panel that displays a playing card. * ImageLabel.java A Canvas for displaying images. * Ace.gif, King.gif, Queen.gif, Jack.gif. ##################### import java.applet.Applet; import java.awt.*; import java.awt.event.*; /** An example of CardLayout. The right side of the window holds * a Panel that uses CardLayout to control four possible * subpanels (each of which is a CardPanel that shows a * picture of a playing card). The buttons on the left side * of the window manipulate the "cards" in this layout by * calling methods in the right-hand panel's layout manager. * ********************************* public class CardDemo extends Applet implements ActionListener { private Button first, last, previous, next; private String[] cardLabels = { "Jack","Queen","King","Ace" }; private CardPanel[] cardPanels = new CardPanel[4]; private CardLayout layout; private Panel cardDisplayPanel; public void init() { setBackground(Color.white); setLayout(new BorderLayout()); addButtonPanel(); addCardDisplayPanel(); } private void addButtonPanel() { Panel buttonPanel = new Panel(); buttonPanel.setLayout(new GridLayout(9, 1)); Font buttonFont = new Font("SansSerif", Font.BOLD, 18); buttonPanel.setFont(buttonFont); for(int i=0; inot use CardLayout. Rather, instances of CardPanel * are contained in another window used in the CardDemo * example. It is this enclosing window that uses CardLayout * to manipulate which CardPanel it shows. * ************************* public class CardPanel extends Panel { private Label name; private ImageLabel picture; public CardPanel(String cardName, URL directory, String imageFile) { setLayout(new BorderLayout()); name = new Label(cardName, Label.CENTER); name.setFont(new Font("SanSerif", Font.BOLD, 50)); add(name, BorderLayout.NORTH); picture = new ImageLabel(directory, imageFile); Panel picturePanel = new Panel(); picturePanel.add(picture); add(picturePanel, BorderLayout.CENTER); setSize(getPreferredSize()); } public Label getLabel() { return(name); } public ImageLabel getImageLabel() { return(picture); } } ******************* ImageLabel.java A Canvas for displaying images. ******************* import java.awt.*; import java.net.*; /** A class for displaying images. It places the Image * into a canvas so that it can moved around by layout * managers, will get repainted automatically, etc. * No mouseXXX or action events are defined, so it is * most similar to the Label Component. * * By default, with FlowLayout the ImageLabel takes * its minimum size (just enclosing the image). The * default with BorderLayout is to expand to fill * the region in width (North/South), height * (East/West) or both (Center). This is the same * behavior as with the builtin Label class. If you * give an explicit setSize or * setBounds call before adding the * ImageLabel to the Container, this size will * override the defaults. * * Here is an example of its use: * * * public class ShowImages extends Applet { * private ImageLabel image1, image2; * * public void init() { * image1 = new ImageLabel(getCodeBase(), * "some-image.gif"); * image2 = new ImageLabel(getCodeBase(), * "other-image.jpg"); * add(image1); * add(image2); * } * } * * */ public class ImageLabel extends Canvas { // Instance variables. // The actual Image drawn on the canvas. private Image image; // A String corresponding to the URL of the image you will // get if you call the constructor with no arguments. private static String defaultImageString = "http://java.sun.com/lib/images/" + "logo.java.color-transp.55x60.gif"; // The URL of the image. But sometimes we will use an existing // image object (e.g. made by createImage) for which this info // will not be available, so a default string is used here. private String imageString = ""; // Turn this on to get verbose debugging messages. private boolean debug = false; /** Amount of extra space around the image. */ private int border = 0; /** If there is a non-zero border, what color should it be? * Default is to use the background color of the Container. */ private Color borderColor = null; // Width and height of the Canvas. This is the // width/height of the image plus twice the border. private int width, height; /** Determines if it will be sized automatically. If the user * issues a setSize() or setBounds()call before adding the * label to the Container, or if the LayoutManager resizes * before drawing (as with BorderLayout), then those sizes * override the default, which is to make the label the same * size as the image it holds (after reserving space for the * border, if any). This flag notes this, so subclasses that * override ImageLabel need to check this flag, and if it is * true, and they draw modified image, then they need to draw * them based on the width height variables, not just blindly * drawing them full size. */ private boolean explicitSize = false; private int explicitWidth=0, explicitHeight=0; // The MediaTracker that can tell if image has been loaded // before trying to paint it or setSize based on its size. private MediaTracker tracker; // Used by MediaTracker to be sure image is loaded before // paint & setSize, since you can't find out the size until it // is done loading. private static int lastTrackerID=0; private int currentTrackerID; private boolean doneLoading = false; private Container parentContainer; /** Create an ImageLabel with the default image. * * @see #getDefaultImageString * @see #setDefaultImageString */ // Remember that the funny "this()" syntax calls // constructor of same class public ImageLabel() { this(defaultImageString); } /** Create an ImageLabel using the image at URL * specified by the string. * * @param imageURLString A String specifying the * URL of the image. */ public ImageLabel(String imageURLString) { this(makeURL(imageURLString)); } /** Create an ImageLabel using the image at URL * specified. * * @param imageURL The URL of the image. */ public ImageLabel(URL imageURL) { this(loadImage(imageURL)); imageString = imageURL.toExternalForm(); } /** Create an ImageLabel using the image in the file * in the specified directory. * * @param imageDirectory Directory containing image * @param file Filename of image */ public ImageLabel(URL imageDirectory, String file) { this(makeURL(imageDirectory, file)); imageString = file; } /** Create an ImageLabel using the image specified. The other * constructors eventually call this one, but you may want * to call it directly if you already have an image (e.g. * created through createImage). * * @param image The image */ public ImageLabel(Image image) { this.image = image; tracker = new MediaTracker(this); currentTrackerID = lastTrackerID++; tracker.addImage(image, currentTrackerID); } /** Makes sure that the Image associated with the Canvas is * done loading before returning, since loadImage spins off * a separate thread to do the loading. Once you get around * to drawing the image, this will make sure it is loaded, * waiting if not. The user does not need to call this at * all, but if several ImageLabels are used in the same * Container, this can cause several repeated layouts, so * users might want to explicitly call this themselves before * adding the ImageLabel to the Container. Another * alternative is to start asynchronous loading by calling * prepareImage on the ImageLabel's image (see getImage). * * @param doLayout Determines if the Container should be * re-laid out after you are finished waiting. This * should be true when called from user functions, * but is set to false when called from getPreferredSize * to avoid an infinite loop. This is needed when using * BorderLayout, which calls getPreferredSize * before calling paint. */ public void waitForImage(boolean doLayout) { if (!doneLoading) { debug("[waitForImage] - Resizing and waiting for " + imageString); try { tracker.waitForID(currentTrackerID); } catch (InterruptedException ie) {} catch (Exception e) { System.out.println("Error loading " + imageString + ": " + e.getMessage()); e.printStackTrace(); } if (tracker.isErrorID(0)) new Throwable("Error loading image " + imageString).printStackTrace(); doneLoading = true; if (explicitWidth != 0) width = explicitWidth; else width = image.getWidth(this) + 2*border; if (explicitHeight != 0) height = explicitHeight; else height = image.getHeight(this) + 2*border; setSize(width, height); debug("[waitForImage] - " + imageString + " is " + width + "x" + height + "."); // If no parent, you are OK, since it will have // been resized before being added. But if // parent exists, you have already been added, // and the change in size requires re-layout. if (((parentContainer = getParent()) != null) && doLayout) { setBackground(parentContainer.getBackground()); parentContainer.doLayout(); } } } /** Moves the image so that it is centered at * the specified location, as opposed to the setLocation * method of Component which places the top left * corner at the specified location. * * Note: The effects of this could be undone * by the LayoutManager of the parent Container, if * it is using one. So this is normally only used * in conjunction with a null LayoutManager. * * @param x The X coord of center of the image * (in parent's coordinate system) * @param y The Y coord of center of the image * (in parent's coordinate system) * @see java.awt.Component#setLocation */ public void centerAt(int x, int y) { debug("Placing center of " + imageString + " at (" + x + "," + y + ")"); setLocation(x - width/2, y - height/2); } /** Determines if the x and y (in the ImageLabel's * own coordinate system) is inside the * ImageLabel. Put here because Netscape 2.02 has * a bug in which it doesn't process contains() and * locate() tests correctly. */ public synchronized boolean contains(int x, int y) { return((x >= 0) && (x <= width) && (y >= 0) && (y <= height)); } /** Draws the image. If you override this in a * subclass, be sure to call super.paint. */ public void paint(Graphics g) { if (!doneLoading) waitForImage(true); else { if (explicitSize) g.drawImage(image, border, border, width-2*border, height-2*border, this); else g.drawImage(image, border, border, this); drawRect(g, 0, 0, width-1, height-1, border, borderColor); } } /** Used by layout managers to calculate the usual * size allocated for the Component. Since some * layout managers (e.g. BorderLayout) may * call this before paint is called, you need to * make sure that the image is done loading, which * will force a setSize, which determines the values * returned. */ public Dimension getPreferredSize() { if (!doneLoading) waitForImage(false); return(super.getPreferredSize()); } /** Used by layout managers to calculate the smallest * size allocated for the Component. Since some * layout managers (e.g. BorderLayout) may * call this before paint is called, you need to * make sure that the image is done loading, which * will force a setSize, which determines the values * returned. */ public Dimension getMinimumSize() { if (!doneLoading) waitForImage(false); return(super.getMinimumSize()); } // LayoutManagers (such as BorderLayout) might call // setSize or setBounds with only 1 dimension of // width/height non-zero. In such a case, you still // want the other dimension to come from the image // itself. /** Resizes the ImageLabel. If you don't setSize the * label explicitly, then what happens depends on * the layout manager. With FlowLayout, as with * FlowLayout for Labels, the ImageLabel takes its * minimum size, just enclosing the image. With * BorderLayout, as with BorderLayout for Labels, * the ImageLabel is expanded to fill the * section. Stretching GIF/JPG files does not always * result in clear looking images. So just as * with builtin Labels and Buttons, don't * use FlowLayout if you don't want the Buttons to * get resized. If you don't use any * LayoutManager, then the ImageLabel will also * just fit the image. * * Note that if you setSize explicitly, you must do * it before the ImageLabel is added to the * Container. In such a case, the explicit size * overrides the image dimensions. * * @see #setBounds */ public void setSize(int width, int height) { if (!doneLoading) { explicitSize=true; if (width > 0) explicitWidth=width; if (height > 0) explicitHeight=height; } super.setSize(width, height); } /** Resizes the ImageLabel. If you don't setSize the * label explicitly, then what happens depends on * the layout manager. With FlowLayout, as with * FlowLayout for Labels, the ImageLabel takes its * minimum size, just enclosing the image. With * BorderLayout, as with BorderLayout for Labels, * the ImageLabel is expanded to fill the * section. Stretching GIF/JPG files does not always * result in clear looking images. So just as * with builtin Labels and Buttons, don't * use FlowLayout if you don't want the Buttons to * get resized. If you don't use any * LayoutManager, then the ImageLabel will also * just fit the image. * * Note that if you setSize explicitly, you must do * it before the ImageLabel is added to the * Container. In such a case, the explicit size * overrides the image dimensions. * * @see #setSize */ public void setBounds(int x, int y, int width, int height) { if (!doneLoading) { explicitSize=true; if (width > 0) explicitWidth=width; if (height > 0) explicitHeight=height; } super.setBounds(x, y, width, height); } // You can't just set the background color to // the borderColor and skip drawing the border, // since it messes up transparent gifs. You // need the background color to be the same as // the container. /** Draws a rectangle with the specified OUTSIDE * left, top, width, and height. * Used to draw the border. */ protected void drawRect(Graphics g, int left, int top, int width, int height, int lineThickness, Color rectangleColor) { g.setColor(rectangleColor); for(int i=0; i
A demo providing multiple buttons to select a playing card-A Panel, using CardLayout control which of four possible subpanels, holding a different card, to display
Permanent link to this article: http://bangla.sitestree.com/a-demo-providing-multiple-buttons-to-select-a-playing-card-a-panel-using-cardlayout-control-which-of-four-possible-subpanels-holding-a-different-card-to-display/