1

私は単純なJavaSwingプロジェクトに取り組んでいます。これはメインクラスのコードです(名前が変更されました):

public class MainProg
{
    private static MainProg program; 

    //mainWin is a JFrame
    private MainWindow mainWin;

    //Event handler class which extends MouseAdapter
    private TrayManager trayMgr;


    public static void main(String[] args)
    {                
        program = new MainProg();
    }

    public MainProg()
    {
        mainWin = new MainWindow();
        trayMgr = new TrayManager();

        mainWin.startBtn.addMouseListener(trayMgr);

        mainWin.setVisible(true);
    }
}

明らかなように、プログラムが起動すると、クラスmain()の新しいインスタンスが作成され、コンストラクターが呼び出されます。MainProgコンストラクターでは、JFrameの新しいインスタンスを作成しますmainWin。次に、のボタンにイベントハンドラーをアタッチしますmainWin

イベントハンドラークラスtrayMgrでは、唯一のメソッドはmouseClicked()System.out.println('Clicked');

問題は、このプログラムをNetbeansで実行すると、JFrameがすぐに表示されることですが、メッセージがコンソールに出力される前に、ボタンを2〜3回クリックする必要があるようです。

これはNetbeansに固有のものですか、それともウィンドウを表示する前にイベントハンドラを設定するために何かを変更する必要がありますか?

4

2 に答える 2

5

スレッドの問題が現在の問題を引き起こしている可能性は低いですが、理論的に問題が発生する可能性があります。より扱いにくいルックアンドフィールに関連する実際の問題をいくつか見てきました。非常に簡単に言えば、GUIを開始するコードをSwingイベントスレッドにキューイングする必要があります。これを行うには、次のようにします。

public void main(String[] args) {
  SwingUtilities.invokeLater(new Runnable(
    public void run() {
      program = new MainProg();
    }
  ));
}

他の誰かがinvokeAndWait(...)代わりに使用することを推奨しましたinvokeLater(...)が、特にSwingイベントスレッド自体からこの呼び出しを誤って行った場合、これは危険な場合があります。状況に応じて、を使用することをお勧めしますinvokeLater(...)

しかし、繰り返しになりますが、あなたが示したコードの主な問題は、ActionListenerが使用されるべき場所でのMouseListenerの不適切な使用であったと思います。GUIライブラリのコーディングを学ぶのは非常に難しい場合があり、そのため、何も想定できません。チュートリアルをチェックして、専門家から学びましょう。また、Swingの長期的なコーディングを検討している場合は、NetBeanのコード生成ユーティリティを廃止することを検討し、最初にSwingを手動でコーディングする方法を学びます。あなたはこれをしたことを後悔することはありません。

于 2012-09-05T02:07:34.650 に答える
3

あなたが尋ねたので、私がここに投稿したコードは別のトピックに関するJavaSSCCEです。invokeLaterEDTで計算を実行する方法です。(invokeAndWaitここでも正常に機能するが、他の条件ではデッドロックが発生する可能性があるもあります。)

実際、この例はおそらく少し保守的すぎます。show()いくつかの参考文献は、またはへの呼び出しをメインスレッドからSwingを実行できると言っていますsetVisible()。ただし、Java7で試してみると誤動作するプログラムがあります。

于 2012-09-05T01:37:22.120 に答える