0

ボタンを押したときに新しいウィンドウを作成し、現在のウィンドウ数を表示してウィンドウを閉じ、ウィンドウを閉じるときにスレッドを実行するアプリケーションを作成しようとしています。

基本的に、機能は次のようになります (そして、それらのいくつかは機能しています):

  1. アプリケーションの起動時にウィンドウを表示 (OK)
  2. ボタンを押して新しいウィンドウを作成する (OK)
  3. ボタンを押すと現在のウィンドウ数が表示されます (作成時は OK、ウィンドウを閉じる時は NOK)。
  4. 「X」を押すとウィンドウを破棄 (OK)
  5. 元のウィンドウが閉じられたときにメイン スレッドを破棄する (NOK)

これが私のコードです:

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();
  }

}

マニフェスト.mf:

マニフェスト バージョン: 1.0
メインクラス: projectpackage.MyApp

コンソールでJavaアプリケーションをコンパイルして実行する方法を知っていることを願っています. そうでない場合は、次のとおりです。

(CLI で「projectpackage」ディレクトリ内のディレクトリに移動します。*.java ファイルは「projectpackage」ディレクトリ内にある必要があります)

    javac プロジェクトパッケージ\*.java
    jar cfm MyApp.jar manifest.mf projectpackage\*
    java -jar MyApp.jar

誰かが私が間違っていること、またはコードを機能させるために何をする必要があるかを教えてもらえますか? それとも、根本的な誤解をしているだけですか?

4

2 に答える 2

2
JFrame frame = new JFrame();

これはあなたの問題です。JFrame クラスを拡張しますが、新しいオブジェクトを使用しようとします。super();必要に応じて、この行をorに置き換える必要がありsuper("Frame " + getMyThreadCount());ます。

編集: 言及すべきもう 1 つの問題: クラスに MyThread という名前を付けましたが、これはウィンドウの非常に苛立たしいクラス名です;)

編集2:他にいくつか:

  • public void run()コンテンツがないのに、なぜMyThread実装するのRunnableですか?
  • あなたはいくつかのスレッドを作成しますが、私がそれを正しければ、それらのいずれも開始しません。
于 2013-05-14T18:32:02.330 に答える
1

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
        }

    }
}
于 2013-05-15T18:48:46.460 に答える