我正在为我的高级设计项目在Netbeans 6.1中创建一个GUI,但我遇到了一个烦人的问题。像我的登录PopUp和其他临时Windows一样,当我告诉它时不会消失。我一直在研究如何解决这个问题大约2个月。我甚至为我的Pop Up疯了一个单独的线程,但它仍然无法正常工作....如果我真的不乱用任何其他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");
}
}
我也试过Swing Utilities,但也许我错了,因为这是我第一次使用它们。它基本上与上面的代码做同样的事情,除了窗口在等待时冻结,上面的代码没有做到:
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)
{
}
}
});
请帮助我!!!
答案 0 :(得分:1)
Swing组件只能由swing事件派发线程操纵。
类SwingUtilites具有向调度线程提交任务的方法。
答案 1 :(得分:1)
经验法则:
所以你解决这个问题的答案是“其他方式”......
稍微摆脱问题,你实际上要做的是什么?如果你只想要一个登录对话框来等待用户输入用户名和密码,那么一个不使用模态JDialog的原因(毕竟,这就是它的用途......)。
如果你确实想要一些任意线程等待信号关闭窗口/操纵GUI,那么你需要在另一个线程中等待,然后使 线程使用实际的GUI操作代码调用SwingUtilities.invokeLater()。
P.S。实际上有一些GUI操作方法可以安全地从其他线程调用,例如“只是设置标签”的电话通常是安全的。但哪些电话是安全的并不是非常明确,所以最好只是在实践中避免这个问题。
答案 2 :(得分:0)
很难诊断您的问题。我不确定您尝试使用wait方法做什么,但我建议单独留下wait / notify。
此代码有两个框架 - 当您创建第二个框架时,第一个框架将被隐藏,直到您关闭它为止。
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);
}
}
因为我在你的代码中没有看到任何证据,我建议你read up on using event listeners而不是试图“等待”代码完成。
目前还不完全清楚你想要实现的目标,但你可能会更好地使用模态对话框:
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);
}
}
答案 3 :(得分:0)
如何简单地做:
//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);
}
};
}
答案 4 :(得分:0)
你真正想要使用的是模态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
}
}
}