我正在通过Java创建一个Blackjack纸牌游戏。我创建的按钮应该从Blackjack类调用main方法以启动游戏。
我的问题是,当按下按钮时,按钮保持蓝色,我无法输入弹出窗口。这是Window类,ActionPerformed方法应该调用Blackjack类。
import java.awt.*;
import javax.swing.*;
import java.awt.Font;
import java.awt.Dimension;
import javax.swing.JButton;
import java.awt.event.*;
public class exampleWindow implements ActionListener
{
public void createWindow()
{
JFrame frame = new JFrame("Blackjack");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel textLabel = new JLabel("Welcome to Blackjack!", SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(800, 600));
textLabel.setFont(new Font("Zapfino", Font.BOLD, 36));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.getContentPane().setBackground(new Color(0,132,32));
JButton start = new JButton();
frame.getContentPane().add(BorderLayout.SOUTH, start);
start.setText("Start Game");
start.addActionListener(this);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
}
public void actionPerformed(ActionEvent e)
{
Blackjack.main(null);
}
public static void main(String[] args)
{
exampleWindow e = new exampleWindow();
e.createWindow();
}
}
这是主要类,二十一点:
import java.util.Scanner;
public class Blackjack
{
public static void main(String[] args)
{
System.out.println("Welcome to Blackjack! Please enter your name:");
Scanner name = new Scanner(System.in);
String playerName = name.nextLine();
System.out.println("Place your bet: ");
Scanner bet = new Scanner(System.in);
int playerBet = bet.nextInt();
int card1 = (int) Math.ceil(Math.random() * 11);
int card2 = (int) Math.ceil(Math.random() * 11);
int card3 = (int) Math.ceil(Math.random() * 11);
int card4 = (int) Math.ceil(Math.random() * 11);
System.out.println("Dealing Cards...");
System.out.println(playerName + " has: " + card1 + " and " + card2);
System.out.println("Dealer has: " + card3 + " and " + card4);
Scanner answer = new Scanner(System.in);
int playerTotal = card1 + card2;
int dealerTotal = card1 + card2;
String WoL = "";
String DWoL = "";
int stop = 0;
if (playerTotal == 21)
{
System.out.println("BlackJack! You win: " + 2 * playerBet);
}
while (stop == 0)
{
System.out.println("Hit or Stand? (H/S)");
String HoS = answer.nextLine();
if(HoS.equals("h") || HoS.equals("H"))
{
playerTotal += (int) Math.ceil(Math.random() * 11);
if(playerTotal > 21)
{
System.out.println(playerName + " has: " + playerTotal + " --> Bust! You Lose: -" + playerBet);
WoL = "L";
stop++;
}
else if (playerTotal == 21)
{
System.out.println(playerName + " has: " + playerTotal + " --> Blackjack! You win " + 2 * playerBet);
WoL = "W";
stop++;
}
else
{
System.out.println(playerName + " has: " + playerTotal);
}
}
else
{
stop++;
}
}
if(WoL.equals("W") || WoL.equals("L"))
{
}
else
{
while (dealerTotal <=16)
{
System.out.println("Dealer hits");
dealerTotal += (int) Math.ceil(Math.random() * 11);
if(dealerTotal > 21)
{
System.out.println("Dealer has: " + dealerTotal + " --> Bust! You Win: " + 2 * playerBet);
DWoL="L";
}
else if (dealerTotal == 21)
{
System.out.println("Dealer has: " + dealerTotal + " --> Blackjack! You lose: -" + playerBet);
DWoL="W";
}
else
{
System.out.println("Dealer has: " + dealerTotal);
}
}
if(DWoL.equals("W") || DWoL.equals("L"))
{
}
else
{
System.out.println("Dealer stands on: " + dealerTotal);
}
}
if(DWoL.equals("L") || DWoL.equals("W") || WoL.equals("W") || WoL.equals("L"))
{
}
else if (dealerTotal == playerTotal)
{
System.out.println("Tie Game! No money exchanged");
}
else if (dealerTotal > playerTotal)
{
System.out.println("Dealer has higher cards. Dealer wins! You lose: -" + playerBet);
}
else
{
System.out.println(playerName + " has higher cards. " + playerName + " wins! You win: " + 2 * playerBet);
}
}
}
答案 0 :(得分:1)
从我在这里看到的,Blackjack.main(null)
执行一个永不返回的循环。由于此调用来自事件调度线程(EDT),这将导致UI无法响应,因为在EDT上处理UI。由于您将控制台应用程序与GUI组合在一起,因此在您的main()
函数返回之前,UI将不会收到任何处理时间。 Scanner
类中Blackjack
的输入是控制台的标准。因此,您有一个UI等待从控制台完成二十一点。
将事件调度线程上运行的代码视为一个非常有用 一系列简短的任务。大多数任务都是事件处理方法的调用, 例如ActionListener.actionPerformed。其他任务可以安排 应用程序代码,使用invokeLater或invokeAndWait。活动上的任务 派遣线程必须快速完成;如果他们不这样做,未处理的事件就会重新开始 并且用户界面没有响应。
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
我的建议是调查javax.swing.SwingWorker
。您可以在此处找到教程:https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
或javax.swing.Timer
:
https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
修改强>
如果您打算坚持使用GUI,则需要重新设计应用程序的结构。如果你想使用Swing来运行你的Blackjack游戏,你可以将游戏将执行的每个动作分解为他们自己的方法。这就分离了大脑&#34;来自视觉效果。然后,您可以使用组合这两者的图层。这被称为模型,视图,控制器。该模型将是一个包含游戏需要进行的所有计算和操作的类,视图是GUI和外观,控制器是视图上的用户交互如何触发模型中的操作。 http://www.oracle.com/technetwork/articles/javase/index-142890.html