调用Scanner后,java方法不会更新GUI
如果调用了cont()
,为什么屏幕不更新为新面板(称为theView.continueToGame()
)?如果我注释掉ask()
调用cont()
的地方,这似乎是可行的。有人能解释一下为什么会这样吗?看来有什么东西把循环搞砸了
司机。爪哇
public class Driver {
public static void main(String[] args)
{
Controller con = new Controller();
con.ask();
}
}
控制器。爪哇
public class Controller {
private View theView = new View();
private Model theModel = new Model();
public void ask()
{
theView.displayMenu();
cont();
System.out.println("ready");
theView.continueToGame();
}
private void cont()
{
Scanner stdin = new Scanner(System.in);
int input = 0;
while(!(input == 1))
{
System.out.println("Enter 1 to continue");
input = 0;
try
{
input = stdin.nextInt();
}
catch (InputMismatchException e)
{
System.out.println("error");
stdin.next();
}
}
stdin.close();
}
}
视图。爪哇
public class View extends JFrame {
/**
* Serial id
*/
private static final long serialVersionUID = 1L;
private String String1 = "1";
private String String2 = "2";
View()
{
setVisible(true);
setTitle("Tic-Tac-Toe");
setSize(400,400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void displayMenu()
{
this.add(new startMenu());
}
public void continueToGame()
{
this.getContentPane().removeAll();
this.add(new gameScreen());
}
class startMenu extends JPanel{
/**
* Serial id
*/
private static final long serialVersionUID = 1L;
private startMenu()
{
setVisible(true);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
setBackground(Color.blue);
g.setColor(Color.black);
g.drawString(String1, this.getWidth()/2, this.getHeight()/2);
}
}
class gameScreen extends JPanel
{
/**
* Serial id
*/
private static final long serialVersionUID = 1L;
private gameScreen()
{
setVisible(true);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
setBackground(Color.green);
g.setColor(Color.black);
g.drawString(String2, this.getWidth()/2, this.getHeight()/2);
}
}
}
编辑:
将cont()
更改为
private void cont()
{
Integer input = -1;
while(!(input == 0))
{
input = JOptionPane.showConfirmDialog(theView, "Continue?", null, JOptionPane.YES_OPTION);
System.out.println(input);
}
}
也不行
# 1 楼答案
您遇到了一个线程问题,其中一个阻塞方法正在阻止GUI的事件线程冻结程序。这是因为您试图将控制台程序及其线性程序逻辑与事件驱动GUI程序结合起来
解决办法很简单:不要这样做。摆脱
new Scanner(System.in)
,只通过GUI以事件驱动的方式获取用户输入。您可以使用JOptionPane或JDialog来获取此输入,这两种方法都很有效,但是new Scanner(System.in)
却不行。我自己,我只会使用JOptionPane.showConfirmDialog(...)
作为旁注,您使用的类名,如视图和控制器,就好像您计划进行一个模型-视图-控件类型的程序设计,如果您问我,这是一个非常好的想法,但是控件应该处理GUI的用户输入,而不是控制台的输入
编辑
我错了。您的问题是,在交换组件后,您没有在容器上调用
revalidate()
和repaint()
。i、 e最好不要担心这些事情,使用CardLayout交换您的视图JPanel
编辑2
CardLayout实际上非常易于使用,但如果将其添加到JFrame,实际上就是将其添加到contentPane,并且在调用CardLayout对象的
show
方法时必须使用contentPane。例如: