在windowClosing事件中用Java杀死JFrame线程

时间:2013-05-14 18:27:35

标签: java multithreading swing jframe terminate

我正在尝试编写应用程序,按下按钮时会创建新窗口,显示当前窗口计数并关闭窗口时关闭窗口和线程。

所以基本上,功能就像这样(其中一些是有效的):

  1. 启动应用程序时显示窗口(确定)
  2. 按下按钮创建新窗口(确定)
  3. 按下按钮显示当前窗口计数(创建时确定,关闭窗口时显示NOK)
  4. 按下“X”(确定)
  5. 时销毁窗口
  6. 原始窗口关闭时破坏主线程(NOK)
  7. 这是我的代码:

    package projectpackage;
    
    import javax.swing.JFrame;
    import javax.swing.JButton;
    import javax.swing.JPanel;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.*;
    
    class MyMouseEvent extends MouseAdapter 
    { 
        public void mousePressed(MouseEvent me)
        { 
          MyWindowThread.incrementMyWindowThreadCount();
    
          MyWindowThread obj1 = new MyWindowThread();
    
          Thread thr1 = new Thread(obj1); 
    
          thr1.start();
    
        }
    }
    
    class MyWindowThread extends JFrame implements Runnable
    {
    
      private int height;
      private int width;
    
      private static int MyWindowThreadCount = 1;
    
      public static int getMyWindowThreadCount()
      {
        return MyWindowThreadCount;
      }
    
      public static void incrementMyWindowThreadCount()
      {
        MyWindowThreadCount++;
      }
    
      public static void decrementMyWindowThreadCount()
      {
        MyWindowThreadCount--;
      }
    
      public MyWindowThread()
      {
        super("Frame "+getMyWindowThreadCount());
    
        this.setHeight(300);
    
        this.setWidth(400);
    
        this.setBounds(100,100,getWidth(),getHeight());
    
        this.addWindowListener(new WindowAdapter()
                                {
                                 @Override
                                 public void windowClosing(WindowEvent e)
                                 {
                                    MyWindowThread.decrementMyWindowThreadCount();
                                    //Thread.currentThread().interrupt(); 
                                    return; 
                                 }
                                }
                                );
    
        JPanel panel1 = new JPanel();
    
        JButton button1 = new JButton("New window");
    
        JButton button2 = new JButton("Count running windows");
    
        this.getContentPane().add(panel1);
    
        panel1.add(button1);
    
        panel1.add(button2);
    
        button1.addMouseListener(new MyMouseEvent());
    
        button2.addMouseListener(new MouseAdapter()
                                 {
                                   public void mousePressed(MouseEvent me)
                                   {
                                     javax.swing.JOptionPane.showMessageDialog(null,"Window count = " + MyWindowThread.getMyWindowThreadCount());
                                   }
                                 }
                                );
    
        this.setVisible(true); // show frame
      }
    
      public int getHeight()
      {
       return this.height;
      }
    
      public void setHeight(int h)
      {
       this.height = h;
      }
    
      public int getWidth()
      {
       return this.width;
      }
    
      public void setWidth(int w)
      {
       this.width = w;
      }
    
      public void run()
      {
    
      }
    
    }
    
    public class MyApp 
    {
    
      public static void main(String[] args)
      {
        // Creating objects START
    
        MyWindowThread obj1 = new MyWindowThread(); 
    
        Thread thr1 = new Thread(obj1); 
    
        thr1.start();
      }
    
    }
    

    MANIFEST.MF:

    Manifest-Version: 1.0
    Main-Class: projectpackage.MyApp
    
    

    我希望您知道如何在控制台中编译和运行Java应用程序。如果你不这样做,这里是:

    (在CLI中导航到目录中带有“projectpackage”目录。* .java文件必须在“projectpackage”目录中)

    
        javac projectpackage\*.java
        jar cfm MyApp.jar manifest.mf projectpackage\*
        java -jar MyApp.jar
    
    

    任何人都可以告诉我我做错了什么或者我需要做些什么来使代码工作?或者我只是有一个根本的误解?

2 个答案:

答案 0 :(得分:2)

JFrame frame = new JFrame();

这是您的问题,您扩展了JFrame类但尝试使用新对象。 如果您愿意,可以将此行替换为super();super("Frame " + getMyThreadCount());

编辑:要提到的另一个问题:你将你的类命名为MyThread,这是一个非常恼人的窗口类名;)

编辑2:其他几件事:

  • public void run()没有内容,为什么MyThread实施Runnable
  • 你创建了一些线程,但是如果我做对了,你就不会启动它们。

答案 1 :(得分:0)

如果你只是希望你的应用程序在JFrame关闭时退出,那么你就是这么错了。摆脱所有Thread对象和Runnables。 Swing应用程序在事件派发线程(EDT)中运行。如果需要执行磁盘或网络I / O等操作,则只应使用后台线程。

在EDT中创建/显示JFrame。如果将JFrame上的默认关闭操作设置为DISPOSE_ON_CLOSE,则当所有窗口都已关闭时,主线程将正常终止。

public class MyApp {

    public static void main( String[] args ) {
        EventQueue.invokeLater( new Runnable() {
            public void run() {
                MyWindow w = new MyWindow();
                w.setVisible( true );
            }
        } );
    }

    private static class MyWindow extends JFrame {

        // Simplified reference counting
        private static AtomicInteger frameCount = new AtomicInteger( 0 );
        public MyWindow() {
            super("Frame " + frameCount.incrementAndGet() );   
            this.setSize( 400, 300 );
            this.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
            JButton button = new JButton("New Window");
            button.addActionListener( new ActionListener() {

                @Override
                public void actionPerformed( ActionEvent e ) {
                    MyWindow w = new MyWindow();
                    w.setVisible( true );
                }
            } );

            this.getContentPane().add( button );
            // ignore reference count button for now
        }

    }
}