为什么某些涉及字符串的方法会阻止 paintComponent() 工作?
Why do certain methods involving strings prevent paintComponent() from working?
我正在研究二十一点项目。它可以工作,但在向其添加投注功能时,三件事导致程序被绘制为空白的白色面板:
1. 如果我有一个 JLabel。
2. 如果我有一个 JTextField,构造函数中的 String 参数不为 null。
3. 如果我在面板的构造函数中有一个 drawString() 调用,其中包含一个从双精度转换为字符串的字符串参数。
这是整个程序,问题区域已用注释标记:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BlackjackGUI extends JPanel implements ActionListener{
private static Deck deck;
private static BlackjackHand userHand = new BlackjackHand();
private static BlackjackHand dealerHand = new BlackjackHand();
private static String message = "Play Blackjack!";
private static JButton hit, stand;
private static JTextField betField;
private static double pot = 100.0;
public static void main(String[] args){
JFrame window = new JFrame("Blackjack");
window.setVisible(true);
window.setSize(600, 450);
window.setResizable(false);
BlackjackGUI content = new BlackjackGUI();
window.setContentPane(content);
}
public BlackjackGUI(){//constructs button panel and panel with cards.
setLayout(new BorderLayout());
JPanel cardTable = new JPanel();
setOpaque(true);
setBackground(new Color(164, 0, 45));
cardTable.setOpaque(false);
add(cardTable, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(BorderFactory.createEtchedBorder());
hit = new JButton("Hit");
hit.addActionListener(this);
hit.setEnabled(false);
buttonPanel.add(hit);
stand = new JButton("Stand");
stand.addActionListener(this);
stand.setEnabled(false);
buttonPanel.add(stand);
JButton newGame = new JButton("New Game");
newGame.addActionListener(this);
buttonPanel.add(newGame);
JLabel betLabel = new JLabel("Bet:");//This is a problem.
buttonPanel.add(betLabel);
betField = new JTextField("0", 5);//Also a problem.
buttonPanel.add(betField);
add(buttonPanel, BorderLayout.SOUTH);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int i;//iterator
for(i = 0; i < dealerHand.getCardCount(); i ++){
if(i == 1)
drawCard(g, dealerHand.getCard(i), 10 + (100 * i), 60, true);
else
drawCard(g, dealerHand.getCard(i), 10 + (100 * i), 60, false);
}
for(i = 0; i < userHand.getCardCount(); i ++){
drawCard(g, userHand.getCard(i), 10 + (100 * i), 220, true);
}
g.setColor(Color.BLUE);
g.drawString(message, 10, 370);
g.drawString("Dealer's Cards:", 10, 50);
g.drawString("Your Cards:", 10, 210);
g.drawString(String.valueOf(pot), 300, 210);//Also a problem.
}
public void actionPerformed(ActionEvent evt){
String button = evt.getActionCommand();
if(button.equals("New Game")){
deck = new Deck(false);
userHand = new BlackjackHand();
dealerHand = new BlackjackHand();
deck.shuffle();
userHand.addCard(deck.dealCard());
userHand.addCard(deck.dealCard());
dealerHand.addCard(deck.dealCard());
dealerHand.addCard(deck.dealCard());
handAssessment(userHand.getBlackjackValue(), dealerHand.getBlackjackValue());
repaint();
}
else if(button.equals("Hit")){
userHand.addCard(deck.dealCard());
handAssessment(userHand.getBlackjackValue(), dealerHand.getBlackjackValue());
repaint();
}
else if(button.equals("Stand")){
if(dealerHand.getBlackjackValue() < 17)
dealerHand.addCard(deck.dealCard());
if(userHand.getBlackjackValue() > dealerHand.getBlackjackValue())
message = "You win!";
else
message = "You lose.";
hit.setEnabled(false);
stand.setEnabled(false);
repaint();
}
}
/**
* Draws a card as a 80 by 100 rectangle with upper left corner at (x,y).
* The card is drawn in the graphics context g. If card is null, then
* a face-down card is drawn. (The cards are rather primitive!)
*/
void drawCard(Graphics g, Card card, int x, int y, boolean faceUp) {
if (!faceUp) {
// Draw a face-down card
g.setColor(Color.BLUE);
g.fillRect(x,y,80,100);
g.setColor(Color.WHITE);
g.drawRect(x+3,y+3,73,93);
g.drawRect(x+4,y+4,71,91);
}
else {
g.setColor(Color.WHITE);
g.fillRect(x,y,80,100);
g.setColor(Color.GRAY);
g.drawRect(x,y,79,99);
g.drawRect(x+1,y+1,77,97);
if (card.getSuit() == Card.DIAMONDS || card.getSuit() == Card.HEARTS)
g.setColor(Color.RED);
else
g.setColor(Color.BLACK);
g.drawString(card.getValueAsString(), x + 10, y + 30);
g.drawString("of", x+ 10, y + 50);
g.drawString(card.getSuitAsString(), x + 10, y + 70);
}
} // end drawCard()
/**
Assesses whether the game is over or not based on the values of each player's hand. Determines functionality of buttons accordingly.
@param userVal The blackjack value of the player's hand.
@param dealerVal The blackjack value of the dealer's hand.
*/
void handAssessment(int userVal, int dealerVal){
//dealer has 21
if(dealerVal == 21){
message = "You lose. Dealer has 21.";
hit.setEnabled(false);
stand.setEnabled(false);
}
//player has 21
else if(userVal == 21){
message = "You win with 21!";
hit.setEnabled(false);
stand.setEnabled(false);
}
//player is over 21
else if(userVal > 21){
message = "You lose. You went over 21.";
hit.setEnabled(false);
stand.setEnabled(false);
}
//dealer is over 21
else if(dealerVal > 21){
message = "You win! Dealer is over 21!";
hit.setEnabled(false);
stand.setEnabled(false);
}
//player has more than dealer
else{
message = "Hit or Stand?";
hit.setEnabled(true);
stand.setEnabled(true);
}
}
}
我猜这个问题与 paintComponent() 的工作方式有关。有什么想法吗?
"Call setVisible only AFTER you have established the basic UI." - 美食节目
我正在研究二十一点项目。它可以工作,但在向其添加投注功能时,三件事导致程序被绘制为空白的白色面板: 1. 如果我有一个 JLabel。 2. 如果我有一个 JTextField,构造函数中的 String 参数不为 null。 3. 如果我在面板的构造函数中有一个 drawString() 调用,其中包含一个从双精度转换为字符串的字符串参数。
这是整个程序,问题区域已用注释标记:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BlackjackGUI extends JPanel implements ActionListener{
private static Deck deck;
private static BlackjackHand userHand = new BlackjackHand();
private static BlackjackHand dealerHand = new BlackjackHand();
private static String message = "Play Blackjack!";
private static JButton hit, stand;
private static JTextField betField;
private static double pot = 100.0;
public static void main(String[] args){
JFrame window = new JFrame("Blackjack");
window.setVisible(true);
window.setSize(600, 450);
window.setResizable(false);
BlackjackGUI content = new BlackjackGUI();
window.setContentPane(content);
}
public BlackjackGUI(){//constructs button panel and panel with cards.
setLayout(new BorderLayout());
JPanel cardTable = new JPanel();
setOpaque(true);
setBackground(new Color(164, 0, 45));
cardTable.setOpaque(false);
add(cardTable, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(BorderFactory.createEtchedBorder());
hit = new JButton("Hit");
hit.addActionListener(this);
hit.setEnabled(false);
buttonPanel.add(hit);
stand = new JButton("Stand");
stand.addActionListener(this);
stand.setEnabled(false);
buttonPanel.add(stand);
JButton newGame = new JButton("New Game");
newGame.addActionListener(this);
buttonPanel.add(newGame);
JLabel betLabel = new JLabel("Bet:");//This is a problem.
buttonPanel.add(betLabel);
betField = new JTextField("0", 5);//Also a problem.
buttonPanel.add(betField);
add(buttonPanel, BorderLayout.SOUTH);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int i;//iterator
for(i = 0; i < dealerHand.getCardCount(); i ++){
if(i == 1)
drawCard(g, dealerHand.getCard(i), 10 + (100 * i), 60, true);
else
drawCard(g, dealerHand.getCard(i), 10 + (100 * i), 60, false);
}
for(i = 0; i < userHand.getCardCount(); i ++){
drawCard(g, userHand.getCard(i), 10 + (100 * i), 220, true);
}
g.setColor(Color.BLUE);
g.drawString(message, 10, 370);
g.drawString("Dealer's Cards:", 10, 50);
g.drawString("Your Cards:", 10, 210);
g.drawString(String.valueOf(pot), 300, 210);//Also a problem.
}
public void actionPerformed(ActionEvent evt){
String button = evt.getActionCommand();
if(button.equals("New Game")){
deck = new Deck(false);
userHand = new BlackjackHand();
dealerHand = new BlackjackHand();
deck.shuffle();
userHand.addCard(deck.dealCard());
userHand.addCard(deck.dealCard());
dealerHand.addCard(deck.dealCard());
dealerHand.addCard(deck.dealCard());
handAssessment(userHand.getBlackjackValue(), dealerHand.getBlackjackValue());
repaint();
}
else if(button.equals("Hit")){
userHand.addCard(deck.dealCard());
handAssessment(userHand.getBlackjackValue(), dealerHand.getBlackjackValue());
repaint();
}
else if(button.equals("Stand")){
if(dealerHand.getBlackjackValue() < 17)
dealerHand.addCard(deck.dealCard());
if(userHand.getBlackjackValue() > dealerHand.getBlackjackValue())
message = "You win!";
else
message = "You lose.";
hit.setEnabled(false);
stand.setEnabled(false);
repaint();
}
}
/**
* Draws a card as a 80 by 100 rectangle with upper left corner at (x,y).
* The card is drawn in the graphics context g. If card is null, then
* a face-down card is drawn. (The cards are rather primitive!)
*/
void drawCard(Graphics g, Card card, int x, int y, boolean faceUp) {
if (!faceUp) {
// Draw a face-down card
g.setColor(Color.BLUE);
g.fillRect(x,y,80,100);
g.setColor(Color.WHITE);
g.drawRect(x+3,y+3,73,93);
g.drawRect(x+4,y+4,71,91);
}
else {
g.setColor(Color.WHITE);
g.fillRect(x,y,80,100);
g.setColor(Color.GRAY);
g.drawRect(x,y,79,99);
g.drawRect(x+1,y+1,77,97);
if (card.getSuit() == Card.DIAMONDS || card.getSuit() == Card.HEARTS)
g.setColor(Color.RED);
else
g.setColor(Color.BLACK);
g.drawString(card.getValueAsString(), x + 10, y + 30);
g.drawString("of", x+ 10, y + 50);
g.drawString(card.getSuitAsString(), x + 10, y + 70);
}
} // end drawCard()
/**
Assesses whether the game is over or not based on the values of each player's hand. Determines functionality of buttons accordingly.
@param userVal The blackjack value of the player's hand.
@param dealerVal The blackjack value of the dealer's hand.
*/
void handAssessment(int userVal, int dealerVal){
//dealer has 21
if(dealerVal == 21){
message = "You lose. Dealer has 21.";
hit.setEnabled(false);
stand.setEnabled(false);
}
//player has 21
else if(userVal == 21){
message = "You win with 21!";
hit.setEnabled(false);
stand.setEnabled(false);
}
//player is over 21
else if(userVal > 21){
message = "You lose. You went over 21.";
hit.setEnabled(false);
stand.setEnabled(false);
}
//dealer is over 21
else if(dealerVal > 21){
message = "You win! Dealer is over 21!";
hit.setEnabled(false);
stand.setEnabled(false);
}
//player has more than dealer
else{
message = "Hit or Stand?";
hit.setEnabled(true);
stand.setEnabled(true);
}
}
}
我猜这个问题与 paintComponent() 的工作方式有关。有什么想法吗?
"Call setVisible only AFTER you have established the basic UI." - 美食节目