使用AWT关闭一个窗口框架(而不是整个应用程序)

4

当点击时,如何仅关闭一个Frame而不是两个或整个应用程序? (我还尝试过使用AWT事件分派、EDT)

注:本文中的HTML标记已保留。
package test;

import java.awt.*;
import java.awt.AWTEvent;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;

public class Test11 extends Frame implements MouseListener
{
  public static Frame gp;  
  public Test11()
  { 
    try {            
       this.setLayout (new BorderLayout ());
       Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
       this.setBounds(screen.width-400,33,400, 400);   
       this.setBackground(Color.red);
       this.addWindowListener(new WindowAdapter()
       {
         public void windowClosing(WindowEvent we) 
         {
           System.exit(0);
         }
       });       
       this.addMouseListener(this);       
       this.setVisible(true);
    } finally {
    }    
  }

  /* How do i do AWT Event Dispatch (EDT): to cloase AWT window? */
  public static void main(String[] args) throws InterruptedException, InvocationTargetException 
  {
    /* EDT: AWT Event Dispatch
    EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    eventQueue.push(new MyEventQueue()); */

    /* Simple close */
    EventQueue.invokeAndWait(new Runnable() 
    {
      public void run() 
      {
        System.out.println("Run: Window 1");
        gp = new Test11();
        gp.setVisible(true);      
        //gp.setVisible(false);
      }
    });

    /* Simple close */
    EventQueue.invokeAndWait(new Runnable() 
    {
      public void run() 
      {
        System.out.println("Run: Window 2");
        new Test11().setVisible(true);
      }
    });

  }

  @Override
  public void mouseClicked(MouseEvent me) 
  {
    System.out.println("Clicked: out of Window1 or Window2, close only any one not whole application");
    System.exit(0);
  }

  @Override
  public void mousePressed(MouseEvent me) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void mouseReleased(MouseEvent me) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void mouseEntered(MouseEvent me) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void mouseExited(MouseEvent me) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  /* EDT: Extended class
  private static class MyEventQueue extends EventQueue 
  {
    public void postEvent(AWTEvent theEvent) 
    {
      System.out.println("Event Posted"); 
      super.postEvent(theEvent);
    }
  }
  */  
}

跟进:

import java.awt.*;
import java.awt.event.*;

public class Test11 extends Frame 
{
    public static Frame window1;
    public static Frame window2;

    public Test11(String title) {
        super(title);
        setSize(400, 400);
        setBackground(Color.red);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.out.println(
                    getTitle() +
                    " says Bye-Bye!  " +
                    new java.util.Date());
                dispose();
            }
        });
        setLocationByPlatform(true);
    }

    public static void main(String[] args) {
        /* AFAIU starting the GUI on the EDT only applies to Swing.*/
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                System.out.println("Run: Window 1");
                window1 = new Test11("Window 1");
                window1.setVisible(true);

                System.out.println("Run: Window 2");
                window2 = new Test11("Window 2"); 
                window2.setVisible(true);
            }
        });

        /* Remotely: i need to close thi window, not manually */
        window2.setVisible(false);
        /* failed then try */
        window2.dispose();

        /* Now: I should have only Window1, but that i am not able to make yet */
    }
}

请你能否稍微具体一些说明你的原因,因为我在你的问题中没有看到这一点。 - mKorbel
1
顺便问一下,这个应用程序在本世纪为什么要使用AWT组件?如果你使用Swing,你会得到更好的帮助——因为开发人员可能在过去十年中使用过它并记得它。 ;) - Andrew Thompson
请注意,这是针对媒体播放器的内容,其中Window2播放全高清电影,而Window1则用于按钮控制。 - user285594
1
“FYI,这是针对媒体播放器的。”那是你对我的问题的回答吗?如果你使用的库不支持Swing,请获取更好的库。甚至JMF也内置了Swing支持。要么就针对1.7+,在那里混合使用Swing和AWT再次成为“酷炫的事情”。 - Andrew Thompson
谢谢Andrew Thompson大师,它起作用了。我不必使用AWT了,因为有时在Swing中播放每秒60帧的电影时,会出现一些灰色背景,这就是我使用AWT的原因,但这并不是必须的,我将切换到Swing。 - user285594
4个回答

4
import java.awt.*;
import java.awt.event.*;

public class Test11 extends Frame {

    public Test11(String title) {
        super(title);
        setSize(400, 400);
        setBackground(Color.red);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.out.println(
                    getTitle() +
                    " says Bye-Bye!  " +
                    new java.util.Date());
                dispose();
            }
        });
        setLocationByPlatform(true);
    }

    public static void main(String[] args) {
        /* AFAIU starting the GUI on the EDT only applies to Swing.*/
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                System.out.println("Run: Window 1");
                (new Test11("Window 1")).setVisible(true);
                System.out.println("Run: Window 2");
                (new Test11("Window 2")).setVisible(true);
            }
        });
    }
}

典型输出

Run: Window 1
Run: Window 2
Window 1 says Bye-Bye!  Mon Nov 14 10:20:25 EST 2011
Window 2 says Bye-Bye!  Mon Nov 14 10:20:35 EST 2011
Press any key to continue . . .

更新 1

这段代码可以通过编程方式关闭“窗口 2”。你的版本存在“时间”问题,这是由于调用了invokeLater(您认为这意味着什么?)所致。有两种相对容易的方法可以解决这个问题。

  1. 一种是丑陋的方法。添加一个Swing Timer/ActionListener,在主程序运行后 2 秒钟触发。对于这种方法,请将主程序中所有注释代码行的“注释部分”删除。
  2. 更好的解决方案是删除对EventQueue.invokeLater()的调用,因为它与 AWT 组件无关。

下面是修改后的代码:

import java.awt.*;
import java.awt.event.*;
// since the OP has not taken the time to explain 'why AWT',
// I choose to make life easy by using a Swing class.
import javax.swing.Timer;

public class Test11 extends Frame
{
    public static Frame window1;
    public static Frame window2;

    public Test11(String title) {
        super(title);
        setSize(400, 400);
        setBackground(Color.red);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.out.println(
                    getTitle() +
                    " says Bye-Bye!  " +
                    new java.util.Date());
                dispose();
            }
        });
        setLocationByPlatform(true);
    }

    public static void main(String[] args) {
        // AFAIU starting the GUI on the EDT only applies to Swing.
        //EventQueue.invokeLater(new Runnable() {
        //    public void run() {
                System.out.println("Run: Window 1");
                window1 = new Test11("Window 1");
                window1.setVisible(true);

                System.out.println("Run: Window 2");
                window2 = new Test11("Window 2");
                window2.setVisible(true);
        //    }
        //});

        //ActionListener closeWindow = new ActionListener(){
        //  public void actionPerformed(ActionEvent ae) {
                System.out.println(
                    window2.getTitle() +
                    " says Bye-Bye!  " +
                    new java.util.Date());
                /* failed then try */
                window2.dispose();
        //  }
        //};
        //Timer timer = new Timer(2000,closeWindow);
        //timer.setRepeats(false);
        //timer.start();
    }
}

@mKorbel(笑)我把你的链接从6->7更新了(紧张的习惯),并检查了链接是否有效,但没有意识到它指向了一个Swing特定的方法。只有当我在处理源码时,打算展示使用setDefaultCloseOperation(int)是多么容易的时候,我的编译器友善地警告我说:“编造方法-别这样!”。JavaDocs很好,但编译器更好。 :) - Andrew Thompson
1)在AWT时代,我从沙子中建造了塔楼。 2)我不相信Java7以目前的形式存在,新的所有者==一切已经死亡,只剩下7。 - mKorbel
  1. 哦,别误会了!我现在还没有在这台机器上安装J7。它和我的DukeBox完全不兼容,所以我回退到了6,直到有一个更稳定的JRE出现为止。然而,JavaDocs是另一回事。我只是想看到1.4.2从Google链接中消失,并且获得许多7文档的链接可能会产生这样的结果。(?)
- Andrew Thompson
<只是玩笑>也许我错了,但你已经没有任何机会了。如果我没记错的话,这个引擎有字母顺序,然后是1.4.2、1.5,有时是6 (-: 在谷歌的500万、758T、856位置上 :-) 我从来没有看到过像Java7这样的东西,什么是Java7?没有在谷歌上找到,抱歉,没有办法。请不要停止思考Java7,也许有一天会出现,但不是明天 :-) </只是玩笑> - mKorbel
@Andrew Thompson:请看我的编辑(后续部分)。我目前还无法以编程方式关闭Window2(但是可以通过鼠标单击关闭)。 - user285594

3
看一下setDefaultCloseOperation()方法: HIDE_ON_CLOSE是该行为的正确属性,这些方法适用于Swing。
编辑:
如果您想重复使用该/这些容器,则
this.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent we) {
        this.setVisible(false);
    }
});

我有两个打开的Frame/Window(AWT)。一旦我想关闭一个,我只想关闭那个。但不是像System.exit(0)现在所做的关闭整个应用程序。 - user285594
@Google 如果您想了解有关这些更改的信息,请查看http://download.oracle.com/javase/tutorial/uiswing/events/componentlistener.html和http://download.oracle.com/javase/tutorial/uiswing/events/windowlistener.html,两者都适用于AWT和Swing容器。 - mKorbel
我在http://download.oracle.com/javase/6/docs/api/java/awt/Frame.html中看到了这两个,那么JFrame默认是什么,或者我在你的评论中漏掉了什么吗 :-) - mKorbel
1
OP正在使用纯AWT,因此没有setDefaultCloseOperation(int)可用。 - Andrew Thompson
1
this.setVisible(false); 的问题在于它没有处理该框架的线程。即使所有框架都关闭了,JRE 仍然会运行。如果像我的示例一样将它们 处理掉,则在最后一个框架消失后,JRE 将退出。 - Andrew Thompson
@mKorbel:谢谢。我使用了Andrew Thompson的示例,它可以工作,但我需要使用鼠标关闭窗口。这在我的情况下不适用。但目标是,我需要使用窗口1按钮关闭窗口2。 - user285594

2
最简单的方法是使用:
dispose();

如果在onClickListner中放置此代码,它将简单地关闭与文件相关联的窗口,但不会终止整个程序。


0

在设计模式下,您必须通过右键单击并选择jframe的属性来执行以下操作: 在defaultcloseoperation行中选择DISPOSE(通常是第一行)。

所有这些操作在设计中都更容易。 我是在谈论NetBeans,但我希望在其他IDE中也类似。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接