Question

I'm working on the game of blackjack as a final project for my class in OOP. I can't for the life of me figure out why my cards won't render properly (the values of the cards not displaying are still accounted for - meaning if I had blackjack and I could only see one of my cards, I would still receive credit for having blackjack). Here's a screenshot of what I'm trying to convey (Note: There is always at least one card missing each time and the dealer's face down card does not show up properly either):

enter image description here

Here is the code segment relevant to my card rendering problem:

/**
     * Paints the cards stacked top-down in addition to the rest of the 
     * components. The cards are arranged so the user can still see all of
     * the cards' values.
     */
    public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (hand == null) return;
            for (int i = 0; i < hand.length(); i++) {
                    drawCard(g, hand.get(i), 10, 76 + 33*i);
            }
    }

    /**
     * Paints a card image onto (x,y) of the container. A face down card will
     * be drawn accordingly.
     * @param g the graphics context
     * @param card the card to be printed
     * @param x the x-position of the printed card in this container
     * @param y the y-position of the printed card in this container
     */
    private void drawCard(Graphics g, Card card, int x, int y){
        String face = "";
        String suit = "";
        String filepath = "";

        if (!card.isFaceUp()) {
            suit = "b1";
            face = "fv";
        }
        else {
            face = String.valueOf(card.getFace());
            if (face == "11"){
                face = "j";
            }
            if (face == "12"){
                face = "q";
            }
            if (face == "13"){
                face = "k";
            }
            switch (card.getSuit()) {
                    case Card.DIAMONDS: suit = "d";       break;
                    case Card.CLUBS:    suit = "c";         break;              
                    case Card.HEARTS:   suit = "h";     break;
                    default:            suit = "s";     break; //Spades
            }
            BufferedImage cardImg = null;
            filepath = "C:/Users/Student/workspace/Blackjack GUI/src/images/" + suit + face + ".png";
            try {
                cardImg = ImageIO.read(new File(filepath));
            } catch (IOException e) {
            }
            g.drawImage(cardImg,x,y,71,96,this);

        }

The cards' values ("face") and suits are derived from integers in my class called Card. Here is a copy of that class:

/**
 * A class the represents the deck of 52 cards used in Blackjack.
 * Cards can be one of 13 faces, one of four suits, and one of two colors.
 * Methods will get the names, faces, values, suits, or colors of the cards and
 * can flip the card face up or face down.
 * @author Mike Mulhearn
 */
public class Card {

    /**
     * The value of an Ace
     */
    public static final int ACE = 1; 
    /**
     * The value of a Two
     */
    public static final int TWO = 2; 
    /**
     * The value of a Three
     */
    public static final int THREE = 3; 
    /**
     * The value of a Four
     */
    public static final int FOUR = 4; 
    /**
     * The value of a Five
     */
    public static final int FIVE = 5;
    /**
     * The value of a Six
     */
    public static final int SIX = 6; 
    /**
     * The value of a Seven
     */
    public static final int SEVEN = 7;
    /**
     * The value of an Eight
     */
    public static final int EIGHT = 8; 
    /**
     * The value of a Nine
     */
    public static final int NINE = 9; 
    /**
     * The value of a Ten
     */
    public static final int TEN = 10; 
    /**
     * The value of a Jack
     */
    public static final int JACK = 11; 
    /**
     * The value of a Queen
     */
    public static final int QUEEN = 12; 
    /**
     * The value of a King
     */
    public static final int KING = 13; 
    /**
     * The value of a Spade
     */
    public static final int SPADES = 3;
    /**
     * The value of a Diamond
     */
    public static final int DIAMONDS = 0; 
    /**
     * The value of a Club
     */
    public static final int HEARTS = 2; 
    /**
     * The value of a Club
     */
    public static final int CLUBS = 1; 

    private int suit; //Represents the suit of the card (0-Diamond,1-Club,2-Heart,3-Spade)
    private int face; //Will contain a value from 0 to 12, from Ace to King
    private boolean isFaceUp = true; //Tells whether the card is face up or face down
    /**
     * Create a card with suit cardSuit, face cardFace, and visibility faceUp
     * @param cardSuit is the suit of the card
     * @param cardFace is the face of the card
     * @param faceUp is true when card is face up, false if face down
     */
    public Card(int cardSuit, int cardFace, boolean faceUp){
        suit = cardSuit;
        face = cardFace;
        isFaceUp = faceUp;
    }

    /**
     * Create a card with suit cardSuit, face cardFace
     * @param cardSuit is the suit of the Card
     * @param cardFace is the face of the Card
     */
    public Card(int cardSuit, int cardFace){
        suit = cardSuit;
        face = cardFace;
        isFaceUp = true;
    }

    /**
     * Gets the suit of the card
     * @return integer value with the suit of the card
     */
    public int getSuit(){
        return suit;
    }

    /**
     * Gets the color of the card
     * @return Color of the card as a String
     */
    public String getColor(){
        if(suit == 0 || suit == 2)
            return "Red";
        else
            return "Black";
    }

    /**
     * Gets the face of the Card
     * @return Face of the Card
     */
    public int getFace(){
        return face;
    }

    /**
     * Gets the value of the Card
     * Uses the face of the Card to calculate the value
     * Ace is 1, 2-9 are themselves, 10 and higher are 10
     * @return value of the card
     */
    public int getValue(){
        if(face >= TWO && face <= TEN)
            return face;
        else if(face > TEN)
            return 10;
        return -1;
    }

    /**
     * Gets the highest possible value of the ace
     * @return integer of the highest possible value of the ace
     */
    public int getHighValue() {
        int high = getValue();
        if (high == -1) {
            return 11;
        } else {
            return high;
        }
    }

    /**
     * Gets the lowest value of the ace
     * @return integer of the lowest possible value of the ace
     */
    public int getLowValue() {
        int low = getValue();
        if (low == -1) {
            return 1;
        } else {
            return low;
        }
    }

    /**
     * Flips the card over
     */
    public void flip(){
        isFaceUp = !isFaceUp;
    }

    /**
     * Determines whether the cards are face up
     * @return boolean value representing whether the card is face up or down
     */
    public boolean isFaceUp(){
        return isFaceUp;        
    }
    /**
     * Gets the suit name
     * @return String with the suit of the card
     */
    public String getSuitName(){
        switch(suit) {
            case DIAMONDS: return "Diamonds";
            case CLUBS: return "Clubs";
            case HEARTS: return "Hearts";
            case SPADES: return "Spades";
            default: return "Error: No Suit Found";    
        }
    }
    /**
     * Gets the face name
     * @return String with the face of the card
     */
    public String getFaceName() {
        switch (face) {
            case ACE: return "Ace";
            case TWO: return "Two"; 
            case THREE: return "Three"; 
            case FOUR: return "Four"; 
            case FIVE: return "Five"; 
            case SIX: return "Six"; 
            case SEVEN: return "Seven"; 
            case EIGHT: return "Eight"; 
            case NINE: return "Nine";
            case TEN: return "Ten";
            case JACK: return "Jack"; 
            case QUEEN: return "Queen"; 
            case KING: return "King"; 
            default: return "Error: No Face Found";                 
        }
    }
}

And finally a copy of the main function in the GUI class:

 /** 
     * Runs the Game
     * @param args Main Method
     */
    public static void main(String[] args) {
            GUI b = new GUI();
    Game game = b.new Game();
    JOptionPane.showMessageDialog(game, "Welcome to Mike Mulhearn's House of Cards. " +
                                        "Today we will be indulging ourselves in a game of Blackjack. " +
                                        "Please take your seat.");        
    while (true) {

            if (game.human.getMoney() < MIN_BET) {
                    JOptionPane.showMessageDialog(game, "You don't have enough money to play. YOU LOSE!");
                    System.exit(0);
            }

            System.out.println(game.deck.getCount());
            game.askBets(); 
            game.deal();            
            game.repaint();
            game.setButtonState(true, true, true, false, true);
            if (game.human.getCurrentBet() > game.human.getMoney()) 
                    game.playerChoices.disableDouble();
            while (game.turnContinue) { game.repaint(); }           
            game.setButtonState(false, false, false, false, false);                 
            game.doAITurns();
            game.repaint();
            game.doDealerTurn();
            game.repaint();       
            game.doPayOuts(); 
            game.reset();           
    }        
    }

If I left any code out, here's a zipped copy of my program: Blackjack GUI.zip!

I would be extremely grateful if someone could please help me on this one!

Was it helpful?

Solution

I'm almost certain this is due to bad String comparison:

face = String.valueOf(card.getFace());
if (face == "11"){
    face = "j";
}
if (face == "12"){
    face = "q";
}
if (face == "13"){
    face = "k";
}

Change them to if (face.equals("another string")). See "How do I compare strings in Java?"

Those checks will not be true so you are getting file paths that do not exist. You would know about this if you were not eating the IOException:

filepath = "C:/Users/Student/workspace/Blackjack GUI/src/images/" + suit + face + ".png";
try {
    cardImg = ImageIO.read(new File(filepath));
} catch (IOException e) {
}

As a side note, you should not be doing IO while painting. Instead, read all of the images once at startup and put them in a Map.

static final Map<String, Image> IMGS = new HashMap<String, Image>();

static {
    HashMap<String, Image> imgs = new HashMap<String, Image>();

    String dir = "C:/Users/Student/workspace/Blackjack GUI/src/images/";
    String png = ".png";

    for (String suit = "d", name; ;) {
        for (int face = 1; face <= 13; face++) {
            if (face == 11) {
                name = suit + "j";
            } else if (face == 12) {
                name = suit + "q";
            } else if (face == 13) {
                name = suit + "k";
            } else {
                name = suit + face;
            }

            try {
                imgs.put(
                    name,
                    ImageIO.read(new File(dir + name + png));
                );
            } catch (IOException e) {
                System.out.println(
                    "Exception <" + e.toString() + "> for " + name
                );
            }
        }

        if (suit.equals("d") {
            suit = "c";
        } else if (suit.equals("c")) {
            suit = "h";
        } else if (suit.equals("h")) {
            suit = "s");
        } else {
            break;
        }
    }

    IMGS = Collections.unmodifiableMap(imgs);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top