【问题标题】:Java Swing Validation?Java Swing 验证?
【发布时间】:2019-03-11 05:39:17
【问题描述】:

我正在尝试使用摇摆创建一个二十一点应用程序,当玩家单击点击按钮时,我很难添加新牌。我觉得这与未验证 JLabel 有关,但我不知道这真正意味着什么或如何解决这些问题。请帮忙...

我真的是 Java swing 的新手,所以它可能看起来非常直观的问题,但我希望有人能善意地解释......

下面是我目前拥有的代码,它为经销商和玩家各发两张牌,没有重复牌,但即使选择了这张牌,也无法显示新发的牌,因为我可以在控制台上看到它们......

            import javax.swing.*;
        import java.awt.*;

        @SuppressWarnings("serial")
        public class PlayerHand extends JPanel {

            //declaring private vars

            private JLabel cardPonTable[] = new JLabel[11];
            private int cardP[] = new int[11];
            private Image cardPImage[] = new Image[11];

            private int cardOnTableCount = 0; //counter for number of cards on the table

            public PlayerHand(boolean firstDeal){
                setLayout(null);
                /**
                 * Deals the first two cards for the player
                 */
                if (firstDeal == true) { //run this code if true

                    //playerHand config
                    setBackground(new Color(238, 238, 238));
                    setLayout(null);

                    JLabel playersHandLabel = new JLabel("Player's Hand"); //creates a label indicating the bottom half of the screen is the player's hand

                    //player's hand label config
                    playersHandLabel.setFont(new Font("Lucida Grande", Font.PLAIN, 25));
                    playersHandLabel.setHorizontalAlignment(SwingConstants.CENTER);
                    playersHandLabel.setBounds(192, 314, 200, 80);

                    add(playersHandLabel); //add player's hand label to the container

                    //creates JLabel for two of the player's card, set the positions, and add to the container
                    cardPonTable[0] = new JLabel("");
                    cardPonTable[0].setBounds(80, 6, 220, 320);
                    add(cardPonTable[0]);

                    cardPonTable[1] = new JLabel("");
                    cardPonTable[1].setBounds(340, 6, 220, 320);
                    add(cardPonTable[1]);

                    System.out.println("Player's cards"); //indicate that the following is the player's dealt card on the console


                    CardDeal.createDeck(); //create a deck

                    //deal two card for the player
                    cardP[0] = CardDeal.cardDeal(); 
                    cardP[1] = CardDeal.cardDeal(); 

                    //get the image from the src folder

                    cardPImage[0] = new ImageIcon (this.getClass().getResource(cardP[0]+".png")).getImage(); 
                    cardPImage[1] = new ImageIcon (this.getClass().getResource(cardP[1]+".png")).getImage();

                    cardPonTable[0].setIcon(new ImageIcon (cardPImage[0])); //set the JLabel of the card to the image chosen above
                    cardOnTableCount++; //increase the counter by one
                    cardPonTable[1].setIcon(new ImageIcon (cardPImage[1])); //set the JLabel of the card to the image chosen above
                    cardOnTableCount++; //increase the counter by one


                }
                /**
                 * Do not deal the first two cards (instance made)
                 */

            }

            public void cardAdded() throws Exception  {

                //cardP1onTable.setBounds(cardP1onTable.getX()-50, cardP1onTable.getY(), (int)(WIDTH*0.7), (int)(HEIGHT*0.7));
                //cardP2onTable.setBounds(cardP2onTable.getX()-50, cardP2onTable.getY(), (int)(WIDTH*0.7), (int)(HEIGHT*0.7));

                PlayerHand newDealt = new PlayerHand(false); //creates an instance of playerHand method (send false as a parameter so that the method won't deal two cards again)

                System.out.println("Player's card dealt");

                newDealt.setLayout(null);

                cardPonTable[cardOnTableCount] = new JLabel("");
                cardPonTable[cardOnTableCount].setBounds(192, 6, 220, 320);
                newDealt.add(cardPonTable[cardOnTableCount]);
                cardP[cardOnTableCount] = CardDeal.cardDeal();
                cardPImage[cardOnTableCount] = new ImageIcon (newDealt.getClass().getResource(cardP[cardOnTableCount]+".png")).getImage();
                cardPonTable[cardOnTableCount].setIcon(new ImageIcon (cardPImage[cardOnTableCount]));

                cardOnTableCount++;
            }
        }

下面这段代码是让玩家选择命中或停留的JPanel

        import java.awt.Dimension;
        import javax.swing.JButton;
        import javax.swing.JPanel;
        import java.awt.GridLayout;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;

        @SuppressWarnings("serial")
        public class ChoiseBar extends JPanel{

            private JButton hitButton;
            private JButton stayButton;

            public ChoiseBar() {

                Dimension dim = getPreferredSize();
                dim.height = 100;
                setPreferredSize(new Dimension(1200, 100));

                hitButton = new JButton("HIT");

                hitButton.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {

                        try {
                            PlayerHand.cardAdded();
                        } catch (Exception e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }

                    }

                });

                stayButton = new JButton("STAY");
                setLayout(new GridLayout(0, 2, 0, 0));



                add(hitButton);
                add(stayButton);
            }

        }

这是添加 PlayerHand、DealerHand 和 ChoiceBar 的 MainFrame 类。

import javax.swing.JFrame;
import java.awt.Color;

@SuppressWarnings("serial")
public class MainFrame extends JFrame{

//declaring private vars

private DealerHand dealerHand;
private PlayerHand playerHand;
private ChoiseBar choiseBar;

public MainFrame() {

    super("TABLE"); //calling the "TABLE" method in BJ_APP

    playerHand = new PlayerHand(true); //creates an instance of playerHand (firstDeal is true as it is the first deal)
    //playerHand config 
    playerHand.setForeground(new Color(0, 0, 0)); 
    playerHand.setBackground(new Color(238, 238, 238));
    playerHand.setLocation(300, 625);
    playerHand.setSize(600, 400);

    dealerHand = new DealerHand(); //creates an instance of dealerHand
    //playerHand config
    dealerHand.setLocation(300, 31);
    dealerHand.setSize(600, 429);

    choiseBar = new ChoiseBar(); //creates an instance of choiseBar
    //choiseBar config
    choiseBar.setSize(800, 120);
    choiseBar.setLocation(214, 472);

    getContentPane().setLayout(null); //mainFrame uses absolute layout


    //add these three containers to mainFrame
    getContentPane().add(choiseBar);
    getContentPane().add(playerHand);
    getContentPane().add(dealerHand);

    setSize(1200,1080); //set the size of mainFrame

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //the program will terminated when mainFrame is closed

    this.setVisible(true); //set mainFrame visible


}

}

【问题讨论】:

  • 不要调用validate() 方法。您需要创建 revalidate() 方法。当您不使用 LayoutManager (setLayout(null)) 时,这两种方法都不起作用。我建议您使用 LayoutManager 重新开始。
  • 1) 不要使用静态变量。您的代码应该使用实例变量。最好不要使用单个变量,使用数组,这样您就可以通过使用索引来访问卡片,这将简化您的代码。 2)摆脱静态方法。您再次向类添加自定义方法,因此它们不需要是静态的。 3) 类名应以大写字符开头。 4) 查看Overlap Layout,它可以让您轻松添加显卡。
  • @GeorgeZ。谢谢你的建议。我不能使用绝对布局并验证我的组件?
  • @camickr 谢谢你的建议。根据您的建议,我对代码进行了几处更改。我已经相应地更新了上面的代码,还添加了另一类 JPanel,让用户选择点击或停留。但是,在 'PlayerHand.cardAdded();' ,它说“不能从 PlayerHand 类型对非静态方法 cardAdded() 进行静态引用”并建议我将 cardAdded() 更改为静态。
  • 当您创建“PlayerHand”面板时,您需要保留对面板的引用。然后,当您创建“ChoiceBar”时,将对 PlayerHand 的引用传递给 ChoiceBarl。现在,ChoiceBar 可以使用此引用调用 PlayerHand 面板中的任何方法..

标签: java swing


【解决方案1】:

“保留参考”究竟是什么意思?

你一直这样做:

hitButton = new JButton("HIT");

您在上面创建了一个 JButton 实例并保留对它的引用。

然后在您的代码中使用以下方法更改按钮的属性:

hitButton.addActionListener(new ActionListener() ...

您的自定义面板也不例外。您可以使用要执行的方法创建一个自定义类。

所以在你的代码中的某个地方你需要这样的逻辑:

PlayHand playHandPanel = new PlayHand();
ChoiceBar choiceBarPanel = new ChoiceBar( playHandPanel );
frame.add( playHandPanel );
frame.add( choiceBar );

然后在 ChoiceBar 的构造函数中,您将对“playHandPanel”的引用保存为类中的实例变量。然后在按钮的 ActionListener 中,您现在可以调用 cardAdded() 方法。

【讨论】:

  • 再次感谢您的友好回复。我仍然不确定我应该在哪里添加这 4 行代码......在 ChoiceBar 类中,还是我需要创建另一个只包含此代码的类? >PlayHand playHandPanel = new PlayHand(); ChoiceBar choiceBarPanel = new ChoiceBar( playHandPanel ); frame.add(playHandPanel); frame.add( 选择栏 );谢谢,
  • 我不知道你的代码是如何组织的,但是你需要在某个地方创建面板并将它们添加到你的框架中。
  • 我在添加了所有面板的地方添加了 MainFrame 的代码。 MainFrame是我需要添加你上面提到的四个代码的类吗?
猜你喜欢
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多