2010-12-26 7 views
0

スレッドセーフなJavaのGUI作成の問題以下<a href="http://download.oracle.com/javase/tutorial/uiswing/examples/components/TopLevelDemoProject/src/components/TopLevelDemo.java" rel="nofollow">sample code</a>で

/* 
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions 
* are met: 
* 
* - Redistributions of source code must retain the above copyright 
*  notice, this list of conditions and the following disclaimer. 
* 
* - Redistributions in binary form must reproduce the above copyright 
*  notice, this list of conditions and the following disclaimer in the 
*  documentation and/or other materials provided with the distribution. 
* 
* - Neither the name of Oracle or the names of its 
*  contributors may be used to endorse or promote products derived 
*  from this software without specific prior written permission. 
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/ 

package components; 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

/* TopLevelDemo.java requires no other files. */ 
public class TopLevelDemo { 
    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("TopLevelDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create the menu bar. Make it have a green background. 
     JMenuBar greenMenuBar = new JMenuBar(); 
     greenMenuBar.setOpaque(true); 
     greenMenuBar.setBackground(new Color(154, 165, 127)); 
     greenMenuBar.setPreferredSize(new Dimension(200, 20)); 

     //Create a yellow label to put in the content pane. 
     JLabel yellowLabel = new JLabel(); 
     yellowLabel.setOpaque(true); 
     yellowLabel.setBackground(new Color(248, 213, 131)); 
     yellowLabel.setPreferredSize(new Dimension(200, 180)); 

     //Set the menu bar and add the label to the content pane. 
     frame.setJMenuBar(greenMenuBar); 
     frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     //Schedule a job for the event-dispatching thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

機能createAndShowGUI(上記のコメントは)、「スレッドの安全のため、この方法は、イベントディスパッチスレッドから呼び出される必要があります。 "

このメソッドをイベントディスパッチスレッドから呼び出す理由を説明できますか。私はこのメソッドをpublic void mainメソッドに入れようとしましたが、それは問題ではありません。

+0

時間の98%は問題ではありませんが、上司や顧客の前で何かをデモする必要があるときは一度問題になります。答えに記されているように、あなたはEDTでSwingコールをするように気を付けるべきです。 –

+0

ところで、あなたはこのフォーラムで公開している著作権で保護されたコードではありませんか? –

+3

@ Hovercraft Eelsの完全版:明らかにあなたは*著作権*の単語を見つけることができました。おそらくあなたが見つけられた*著作権*の下の段落を読むことを試みることができますか? – SyntaxT3rr0r

答えて

5

これはうまくいくかもしれませんが、それがどこでもうまくいくとは限りません。 (ほぼ)Swingクラスへのアクセスは、Javadocsに記載されているように、EDTから実行する必要があります。これには、JFrameとコンポーネントの初期作成が含まれます。

一般に、スイングはスレッドセーフではありません。特に記載がない限り、すべてのSwingコンポーネントおよび関連するクラスは、イベントディスパッチスレッドでアクセスする必要があります。

...インパクトがある

は、しかし、Swingアプリケーションを構築し、表示しています。アプリケーションのメインメソッドまたはアプレットのメソッドへの呼び出しは、イベントディスパッチスレッドでは呼び出されません。そのため、アプリケーションまたはアプレットを構築して表示するときに、イベントをディスパッチするスレッドに制御を移すように注意する必要があります。

以前は、この「初期作成」ルールはありませんでしたが、このアプローチを使用するとスレッドの問題がいくつか見つかりました。関連する議論があれば、私はここでそれをリンクします。

更新:this answer on Stack Overflowでは、スイングシングルスレッドポリシールールと、他のスレッドからアクセスされている「まだ実現していない」コンポーネントを禁止する変更が行われています。

関連する問題

 関連する問題