Reputation: 1
I'm typing my first obiect program - BlackJack, and I have problem with print card image. My class Card extended JLabel and has ImageIcon property.
package Blackjack;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class Card extends JLabel{
private final String suit, faceName;
private int cardValue;
private boolean isVisible = false;
private BufferedImage cardImage;
public ImageIcon cardIcon;
public Card(String suit, String faceName){
this.suit = suit;
this.faceName = faceName;
//this.cardImage = getCardImage();
this.cardIcon = new ImageIcon(getCardImage());
switch(faceName){
case "2":
this.cardValue = 2;
break;
case "3":
this.cardValue = 3;
break;
case "4":
this.cardValue = 4;
break;
case "5":
this.cardValue = 5;
break;
case "6":
this.cardValue = 6;
break;
case "7":
this.cardValue = 7;
break;
case "8":
this.cardValue = 8;
break;
case "9":
this.cardValue = 9;
break;
case "10":
this.cardValue = 10;
break;
case "Jack":
this.cardValue = 10;
break;
case "Queen":
this.cardValue = 10;
break;
case "King":
this.cardValue = 10;
break;
case "Ace":
this.cardValue = 11;
break;
}
}
public void setCardVisible(boolean v){
isVisible = v;
}
public boolean getVisible(){
return isVisible;
}
public String getCardName(){
if (isVisible)
return faceName + " of " + suit;
else
return "Karta zakryta";
}
public int getCardValue(){
if (isVisible)
return cardValue;
else
return 0;
}
public BufferedImage getCardImage(){ //dopisać
String fileName;
if (faceName.equals("10"))
fileName = "T";
else if (faceName.equals("Jack"))
fileName = "J";
else if (faceName.equals("Queen"))
fileName = "Q";
else if (faceName.equals("King"))
fileName = "K";
else if (faceName.equals("Ace"))
fileName = "A";
else
fileName = faceName;
fileName = fileName + suit.substring(0, 1).toUpperCase();
File imgFile = new File("img/" + fileName + ".png");
try{
if (isVisible)
cardImage = ImageIO.read(imgFile);
else
cardImage = ImageIO.read(new File("img/RE.png"));
}
catch (IOException e) {
System.err.println("Blad odczytu obrazka");
e.printStackTrace();
}
Dimension dimension = new Dimension(cardImage.getWidth(), cardImage.getHeight());
setPreferredSize(dimension);
return cardImage;
}
}
Next class is Table extended JPanel
package Blackjack;
import java.awt.Color;
import javax.swing.JPanel;
public class Table extends JPanel{
private Deck deck;
private Player player;
private Dealer dealer;
private Hand dealerHand;
private Hand playerHand;
public Table(Deck d, Dealer dealer, Player player){
this.deck = d;
this.deck.shuffleDeck();
this.dealer = dealer;
this.player = player;
this.dealerHand = dealer.getPlayerHand();
this.playerHand = player.getPlayerHand();
this.setBackground(Color.GREEN);
}
public Player getPlayer(){
return player;
}
public Dealer getDealer(){
return dealer;
}
public Deck getDeck(){
return deck;
}
}
And class Game extended JFrame
package Blackjack;
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Game extends JFrame{
private Table table;
public Game(Table t){
JFrame frame = new JFrame("BlackJack game");
frame.setSize(800, 500);
frame.setLayout(new BorderLayout());
frame.add(t, BorderLayout.CENTER);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main (String[] args){
Deck deck = new Deck();
Player player = new Player();
Dealer dealer = new Dealer();
Table table = new Table (deck, dealer, player);
player.hitCard(deck.drawCard());
player.getPlayerHand().getCardsInHand().get(0).setCardVisible(true);
table.getDealer().hitCard(table.getDeck().drawCard());
dealer.getPlayerHand().getCardsInHand().get(0).setCardVisible(true);
player.hitCard(deck.drawCard());
player.getPlayerHand().getCardsInHand().get(1).setCardVisible(true);
dealer.hitCard(deck.drawCard());
table.add(player.getPlayerHand().getCardsInHand().get(0));
for (Card c : player.getPlayerHand().getCardsInHand())
System.out.println(c.getCardName());
for (Card c : dealer.getPlayerHand().getCardsInHand())
System.out.println(c.getCardName());
Game g = new Game(table);
}
}
How should I correctly add card image on my window? Because this
table.add(player.getPlayerHand().getCardsInHand().get(0));
didn't work... I see only empty green window with JPanels.
Upvotes: 0
Views: 1446
Reputation: 347334
The primary problem is, you never actually set the icon
property of the JLabel
, so it has nothing to show
What I would recommend doing, is creating an instance of the face and back image and when the visible state changes, change the icon
property
public class Card extends JLabel {
private final String suit, faceName;
private int cardValue;
private boolean isVisible = false;
private BufferedImage faceImage;
private BufferedImage backImage;
public Card(String suit, String faceName) {
this.suit = suit;
this.faceName = faceName;
this.faceImage = getCardFaceImage();
backImage = getCardBackImage();
setCardVisible(false);
switch (faceName) {
case "2":
this.cardValue = 2;
break;
case "3":
this.cardValue = 3;
break;
case "4":
this.cardValue = 4;
break;
case "5":
this.cardValue = 5;
break;
case "6":
this.cardValue = 6;
break;
case "7":
this.cardValue = 7;
break;
case "8":
this.cardValue = 8;
break;
case "9":
this.cardValue = 9;
break;
case "10":
this.cardValue = 10;
break;
case "Jack":
this.cardValue = 10;
break;
case "Queen":
this.cardValue = 10;
break;
case "King":
this.cardValue = 10;
break;
case "Ace":
this.cardValue = 11;
break;
}
}
public void setCardVisible(boolean v) {
isVisible = v;
if (isVisible) {
setIcon(new ImageIcon(faceImage));
} else {
setIcon(new ImageIcon(backImage));
}
}
public boolean isCardVisible() {
return isVisible;
}
public String getCardName() {
if (isVisible) {
return faceName + " of " + suit;
} else {
return "Karta zakryta";
}
}
public int getCardValue() {
if (isVisible) {
return cardValue;
} else {
return 0;
}
}
protected BufferedImage getCardFaceImage() { //dopisać
String fileName;
if (faceName.equals("10")) {
fileName = "T";
} else if (faceName.equals("Jack")) {
fileName = "J";
} else if (faceName.equals("Queen")) {
fileName = "Q";
} else if (faceName.equals("King")) {
fileName = "K";
} else if (faceName.equals("Ace")) {
fileName = "A";
} else {
fileName = faceName;
}
BufferedImage img = new BufferedImage(100, 200, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.RED);
g2d.fill(new Rectangle(100, 200));
g2d.dispose();
// fileName = fileName + suit.substring(0, 1).toUpperCase();
// File imgFile = new File("img/" + fileName + ".png");
// try {
// if (isVisible) {
// cardImage = ImageIO.read(imgFile);
// } else {
// cardImage = ImageIO.read(new File("img/RE.png"));
// }
// } catch (IOException e) {
// System.err.println("Blad odczytu obrazka");
// e.printStackTrace();
// }
// Dimension dimension = new Dimension(cardImage.getWidth(), cardImage.getHeight());
// setPreferredSize(dimension);
return img;
}
protected BufferedImage getCardBackImage() { //dopisać
BufferedImage img = new BufferedImage(100, 200, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.BLUE);
g2d.fill(new Rectangle(100, 200));
g2d.dispose();
return img;
}
}
You don't need to change the preferredSize
, the JLabel
will take care of that itself.
When you change the state of the card's visibility, don't forget to switch the images...
public void setCardVisible(boolean v) {
isVisible = v;
if (isVisible) {
setIcon(new ImageIcon(faceImage));
} else {
setIcon(new ImageIcon(backImage));
}
}
And don't forget to call this in your constructor, after you've loaded the images ;)
As a general recommendation, instead of dealing with String
as card name/suits, which allows a lot of possible errors, constraint the values to a small, known group using enum
public enum CardFace {
TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, JACK, QUEEN, KING, ACE
}
public enum CardSuit {
HEARTS, DIAMONDS, CLUBS, SPADES
}
public class Card extends JLabel {
private CardSuit suit;
private CardFace face;
//...
public Card(String CardSuits, CardFace faceName) {
While this might seem like a nit pick (and it kind of is), you can expand the enum
s to do other tasks, for example, you can assign each instance with it's name
public enum CardFace {
TWO("Two"), ...;
private String name;
private CardFace(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
You could even assign the face value to the enum
...
public enum CardFace {
TWO("Two", 2), ...;
private String name;
private int value;
private CardFace(String name, int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
}
Upvotes: 1
Reputation: 1179
Instead of creating another JFrame
(also pointed out by @user1803551) within the extended class, just set the frame up as this. This will still give you only one window.
public class Game extends JFrame{
private Table table;
public Game(Table t){
setSize(800, 500);
setLayout(new BorderLayout());
add(t, BorderLayout.CENTER);
//setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main (String[] args){
Deck deck = new Deck();
Player player = new Player();
Dealer dealer = new Dealer();
Table table = new Table (deck, dealer, player);
player.hitCard(deck.drawCard());
player.getPlayerHand().getCardsInHand().get(0).setCardVisible(true);
table.getDealer().hitCard(table.getDeck().drawCard());
dealer.getPlayerHand().getCardsInHand().get(0).setCardVisible(true);
player.hitCard(deck.drawCard());
player.getPlayerHand().getCardsInHand().get(1).setCardVisible(true);
dealer.hitCard(deck.drawCard());
table.add(player.getPlayerHand().getCardsInHand().get(0));
for (Card c : player.getPlayerHand().getCardsInHand())
System.out.println(c.getCardName());
for (Card c : dealer.getPlayerHand().getCardsInHand())
System.out.println(c.getCardName());
Game g = new Game(table);
//g.setLayout(new BorderLayout());
//g.add(table, BorderLayout.CENTER); // your table
g.setVisible(true);
}
Anything you add to the frame can be done direct from the Game
class.
EDIT: added the layout and the Table
(Removed again)
EDIT2:
Within your code I've noticed you do use System.out.println()
for debug output. Without more information on your output, there's not much else to suggest apart from validating that your images are being loaded correctly, or even the file exists (File.exists()
) which will show whether the path is correct too. If they load, then output the dimensions of the image and ensure the JLable
is also set.
My best suggestion would be to use more of the debug output to find where the problem lies. The classes Deck
and Dealer
are missing which only leads us to speculate.
Upvotes: -1