我在这个过程中创建一个GUI//需要将物品寄6.1为我的高级设计项目,但我跑进一个恼人的障碍。临时Windows喜欢我登录的弹出窗口和其他人不会消失的时候我告诉它。我一直在研究如何解决这个约2个月在一个关闭。我甚至疯狂的一个单独的线为我弹出来,但它仍然不会。只有这样,它将消失,如果我真的别惹任何其他GUI组成。...我的代码样本应该有助于描述我的愤怒...不介意的阴影码,这是为测试目的,这显然没有帮助。

//This method is called once a user presses the "first" login button on the main GUI
public synchronized void loginPopUpThread() {
    doHelloWorld = new Thread(){
        @Override
        public synchronized void run()
        {
            try
            {
                    loginPopUpFrame.pack();
                    loginPopUpFrame.setVisible(true);
                    System.out.println("waitin");
                    doHelloWorld.wait();
                    System.out.println("Not Sleepin..");
                    loginPopUpFrame.pack();
                    loginPopUpFrame.setVisible(false);
            }
            catch (InterruptedException e)
            {
            }
        }
    };
    doHelloWorld.start();

//This is called when the "second" loginB is pressed and the password is correct...
public synchronized void notifyPopUp() {
    synchronized(doHelloWorld) {

        doHelloWorld.notifyAll();
        System.out.println("Notified");
    }
}

我还想摆公用事业,但也许我实现也是错误的,因为它是我第一次使用它们。它本质上不同的代码上述除外的窗口,冻结时,它得到等,这上面的代码没有做:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public synchronized void run() {
            try
            {
                    loginPopUpFrame.pack();
                    loginPopUpFrame.setVisible(true);
                    System.out.println("waitin");
                    wait();
                        System.out.println("Not Sleepin.");
                        loginPopUpFrame.pack();
                       loginPopUpFrame.setVisible(false);
            }
            catch (InterruptedException e)
            {
            }
        }
    });

请帮帮我!

有帮助吗?

解决方案

经验法则:

  • 不操纵GUI件中的任意线程;总是安排好的操纵他们在事件线
  • 不等等或睡觉的内部事件线 (因此,永远不会内的代码发送到invokeLater())

所以回答你怎么解决这个问题是"某些其他方式"...

站回问题的一位, 它是什么你实际上想到做什么? 如果你只是想要登录对话等待用户输入的用户名和密码,是有一个原因,不要只使用一个模式JDialog(毕竟,这就是它的存在...).

如果你真的想做一些任意线等待信号要靠近窗户/操纵GUI,然后你 需要做的等待在其他线, 和那么做 线呼叫SwingUtilities.invokeLater()实际GUI操纵的代码。

P.S.实际上有一些GUI操作方法,它是安全的电话从其他线,例如呼叫"仅设置标签"往往是安全的。但这话都是安全的并不是非常好的定义,所以它是最好的,只是为避免这一问题在实践。

其他提示

在Swing组件应仅由摆动事件调度线程进行操作。

类SwingUtilites具有方法任务提交给调度线程。

它是困难的诊断你的问题。我不知道你想要什么做的 等等 方法,但我建议离开 等等/通知 独自一人。

这个代码有两个框架在创建第二个框架,首先是隐藏直到你靠近它。

public class SwapFrames {

  private JFrame frame;

  private JFrame createMainFrame() {
    JButton openOtherFrameButton = new JButton(
        "Show other frame");

    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = frame.getContentPane();
    contentPane.setLayout(new FlowLayout());
    contentPane.add(openOtherFrameButton);
    frame.pack();

    openOtherFrameButton
        .addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            onClickOpenOtherFrame();
          }
        });

    return frame;
  }

  private void onClickOpenOtherFrame() {
    frame.setVisible(false);

    JFrame otherFrame = new JFrame();
    otherFrame
        .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    otherFrame.setContentPane(new JLabel(
        "Close this to make other frame reappear."));
    otherFrame.pack();
    otherFrame.setVisible(true);
    otherFrame.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosed(WindowEvent e) {
        frame.setVisible(true);
      }
    });
  }

  public static void main(String[] args) {
    JFrame frame = new SwapFrames().createMainFrame();
    frame.setVisible(true);
  }

}

因为我没有看到任何证据证明他们在你的代码,我要建议你 读了使用事件的听众 而不是试图"等待"代码的完成。

它不完全清楚什么你想要实现的,但是你可能会更好一个模式对话:

public class DialogDemo {

  public JFrame createApplicationFrame() {
    JButton openDialogButton = new JButton("Open Dialog");

    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container container = frame.getContentPane();
    container.setLayout(new FlowLayout());
    container.add(openDialogButton);
    frame.pack();

    openDialogButton
        .addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            onOpenDialog(frame);
          }
        });

    return frame;
  }

  private void onOpenDialog(JFrame frame) {
    JDialog dialog = createDialog(frame);
    dialog.setVisible(true);
  }

  private JDialog createDialog(JFrame parent) {
    JButton closeDialogButton = new JButton("Close");

    boolean modal = true;
    final JDialog dialog = new JDialog(parent, modal);
    dialog
        .setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    Container container = dialog.getContentPane();
    container.add(closeDialogButton);
    dialog.pack();
    dialog.setLocationRelativeTo(parent);

    closeDialogButton
        .addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            dialog.setVisible(false);
          }
        });

    return dialog;
  }

  public static void main(String[] args) {
    new DialogDemo().createApplicationFrame().setVisible(
        true);
  }

}

如何做简单:

//This method is called once a user presses the "first" login button on the main GUI
public void loginPopUpThread() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            loginPopUpFrame.pack();
            loginPopUpFrame.setVisible(true);
        }
    };
}

//This is called when the "second" loginB is pressed and the password is correct...
public void notifyPopUp() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            loginPopUpFrame.setVisible(false);
        }
    };
}

你真的想使用什么是模态的JDialog。

请注意,这个比特被排除在外。这是你的功课/项目。

public void actionPerformed(ActionEvent e)
{
   // User clicked the login button
   SwingUtilities.invokeLater(new Runnable()
   {
       public void run()
       {
         LoginDialog ld = new LoginDialog();
         // Will block
         ld.setVisible(true);
       }
   });
}

public class LoginDialog extends JDialog
{
    public LoginDialog()
    {
        super((Frame)null, "Login Dialog", true);

        // create buttons/labels/components, add listeners, etc
    }

    public void actionPerformed(ActionEvent e)
    {
       // user probably clicked login
       // valid their info
       if(validUser)
       {
          // This will release the modality of the JDialog and free up the rest of the app
          setVisible(false);
          dispose();
       }
       else
       {
          // bad user ! scold them angrily, a frowny face will do
       }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top