【问题标题】:Wait doesn't allow the JFrame to update等待不允许 JFrame 更新
【发布时间】:2017-04-25 22:55:31
【问题描述】:

在我的程序中,我需要等待用户从 JFrame 输入。当用户完成第一个输入时,他们按下 JButton。这为我创建的一个类调用了一个构造函数:HumanTrainer。在构造函数中,我需要用户有更多的输入。我做了两个函数来等待和通知。但是当代码等待时,一切都冻结了,JFrame 没有更新到它应该更新的状态。

这是第一个按钮执行的操作

startingButton.addActionListener((e)->{
        Trainer[]t=new Trainer[2];//HumanTrainer extends Trainer
        String[]names=new String[2];
        for(int a=0;a<2;a++)
            names[a]=((JTextField)(startingInputs[2][1+a])).getText();
        grid.removeAll();//The JPanel that the Frame has
        Frame.repaint();//The JFrame
        Frame.validate();
        if(isHuman[0])
            t[0]=new HumanTrainer(names[0],grid,Frame);//The constructor
        if(isHuman[1])
            t[1]=new HumanTrainer(names[1],grid,Frame);

    });

以及 HumanTrainer 的构造函数

HumanTrainer(String name,JPanel grid,JFrame Frame){
    super(name);

    GridBagConstraints manager=new GridBagConstraints();
    manager.gridx=0;
    manager.gridy=0;
    manager.gridheight=1;
    manager.gridwidth=1;
    manager.fill=GridBagConstraints.HORIZONTAL;
    Font Format=new Font("Courier New",Font.PLAIN,14);

    JButton cont=new JButton("Continue");//This is the button that when clicked should run the function that notifies

    grid.add(cont,manager);

    grid.repaint();//One of these four things SHOULD change the view of the frame
    grid.validate();
    Frame.repaint();
    Frame.validate();

    System.out.print("TEST");//This prints
    cont.addActionListener((e)->{
        made();//This is a function contained in HumanTrainer that only calls notify();
    });
    make();//This is a function contained in HumanTrainer that only calls wait(); With the proper try and catch
}

但是当 starterButton 被按下时,屏幕会冻结并且不会更新,因此可以按下 cont。

【问题讨论】:

  • 如果您想等待用户输入,请使用模态 JDialog 而不是 JFrame
  • @MadProgrammer 但是在代码继续创建两个培训师之前,我需要来自 HumanTrainer 构造函数的输入。使用 JDialog 不会暂停代码执行。
  • “使用 JDialog 不会暂停代码执行” - 嗯,是的,他们会这样做,除非您在 EDT 之外执行代码(或不使用模态对话框),这意味着您还有其他问题需要处理
  • 根据您对上下文外代码的描述,在 EDT 上下文中调用 wait 将阻止 EDT 并冻结您的程序
  • 你能告诉我怎么做吗,也许我对 JDialogs 的了解并不完整。如果您愿意,我认为它们只会限制与原始框架的交互。我不认为你也可以暂停代码。 @MadProgrammer

标签: java swing jframe wait notify


【解决方案1】:

首先查看Concurrency in Swing。 Swing 使用单个线程来调度它的事件,如果您在 EDT 中执行任何长时间运行或阻塞操作(例如调用 wait),那么它会冻结您的程序并且用户将不得不终止它。

您有两个基本选择。您可以使用模式对话框从用户那里收集信息,请参阅How to Make Dialogs,这将在显示代码时阻止代码的执行,而不会阻止整个 EDT,或者使用观察者模式,它可以生成通知用户提供了您所期望的任何信息。

说实话,模态对话框通常更容易,并且有助于防止意外的副作用

这...

make();//This is a function contained in HumanTrainer that only calls wait(); With the proper try and catch

似乎是您问题的核心,但如果没有更多信息和您正在尝试做的事情的背景,就不可能真正建议您应该做什么,但是我建议您查看model-view-controller 和将您的代码分成更合适的层

【讨论】:

  • 是的,make 函数有点牵强。我保留它是因为这是我在将它放到 StackOverflow 之前尝试过的最后一件事。我会尝试模态对话框并回复你:)
  • 如果您仍然遇到问题,请考虑根据您对问题的描述,提供一个可运行的示例来说明您正在做的事情以及有关您正在尝试做的事情的更多详细信息,这似乎是解决方法
  • 使用模态对话框确实停止了代码,它允许我做我需要的事情。我不知道那件事。谢谢!也很抱歉,我真的不擅长解释我需要做什么/我的代码做什么。
【解决方案2】:

首先,您可能想用{} 关闭for 循环,这样它就不会循环整个代码两次。此外,您应该检查 wait()notify() 是否在没有 java awt 的情况下单独测试它们是否正常工作。

【讨论】:

  • for 循环没有 { 所以它只循环下一行代码
  • 如何检查 wait() 和 notify() 是否正常工作,能否提供示例。
  • 你应该看看Concurrency in Swing,看看为什么这是个坏主意
  • @JamesLeavens 您可以通过试运行轻松测试等待和通知。
猜你喜欢
  • 2022-11-11
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2018-08-13
  • 2021-08-01
相关资源
最近更新 更多