このページで解決しない高度なJavaのシステム障害はJaTSにお任せください

Trouble 8: Swing/AWTコンポーネントがうまく動きません

8-1
フルスクリーン画面を表示する方法が分かりません。
8-2
Windows98上で、JDialogを閉じる時に一般保護違反例外が発生してしまいます。
8-3
一部機種(またはグラフィックスチップ?詳細は未調査)において、Swingコンポーネントの再描画が正しく行われません。
8-4
JTextFiledでIME2000を使用して文字を入力中にF5キーを押すとコンソールに大量のトレースが出力されてしまいます。
8-5
画面を(比較的速いスピードで)閉じたり開いたりしていると、その画面に設定されていたフォーカスが消えてしまいます。
8-6
JFrameをsetEnabled(false)で使用不可にしても、その中に含まれるコンポーネントは使用できてしまいます。
8-7
JButtonのフォーカスが外れていても、Enterキーを押すと、そのボタンが押されたような動きをしてしまいます。
8-8
JTextField(JPasswordField)で、スクロールが開始される文字数の文字を入力すると、カーソル(キャレット)が残ったままスクロールされてしまいます。
8-9
JMenuBarの要素が空の画面で、F10キーを押下すると、ArrayIndexOutOfBoundsExceptionが発生してしまいます。
8-10
ポップアップメニュー(カスケードメニュー)を表示させてから一度選択すると、次回選択時にNullPointerExceptionを出力し、正常に動作しません。
8-11
モーダレスダイアログを表示すると、親画面が操作不能になってしまう場合があります。
8-12
モーダルダイアログを表示すると、一部の画面だけでなく、表示中の全画面が操作不能になってしまいます。
8-13
Solarisにて、WindowsスタイルのLook&Feelが正しく設定できません。
8-14
JTreeのToolTipText表示処理にて、NullPointerExceptionが発生します。
8-15
JTextFieldで入力フィールド長を超える文字入力を行うと、既存文字が上書きされてしまいます。
8-16
JTextAreaにフォーカスがある状態で、TABキーによるコンポーネント間のフォーカス遷移ができません。
8-17
JFrameのsetBackground()で背景色を設定しても、フレームの背景色が変更されません。
8-18
JLabelのsetBackground()を利用して背景色を設定しても、ラベルの背景色が変更されません。
8-19
Swingでsleep時間を設定しても、sleepされずに描画されます。


<Q8-1>フルスクリーン画面を表示する方法が分かりません。

ウィンドウをフルスクリーンで表示したいのですが、JFrameを使用するとタイトルバーが表示されてしまいます。 タイトルバーのないフルスクリーン画面は実現できないのでしょうか?

<発生環境>
OS Any
JDK 1.4
Vender Any
<A8-1>
JDK1.4でサポートされたフルスクリーン排他モード(Full-Screen Exclusive Mode)を利用することで実現可能です。

■フルスクリーン排他モードを利用したフルスクリーン画面の表示手順
(1) JWindowを継承してフルスクリーン表示したいウィンドウを作成する。
(2) GraphicsEnvironmentを取得する。
(3) GraphicsEnvironmentからGraphicsDeviceを取得する。
(4) GraphicsDeviceをフルスクリーン排他モードに変更する。
(5) GraphicsDeviceフルスクリーン排他モードを解除する。

※) フルスクリーン排他モードは画面への直接描画を行なうことにより画面描画性能を向上させる仕組みです。 フルスクリーン排他モードがサポートされていない環境の場合、JDKによりウィンドウのサイズをスクリーンサイズに変更して (0,0) に配置するというシミュレートが行なわれます。

■コード例
※コード中の(1)、(2)などの表記は上の実現方法の(1)、(2)などに対応します。
public class FullScreenTestVer
 {
    public static void main(String args[])
    {
        JWindow window = new JWindow()
        {
            public void paint(Graphics graphics)
            {
                graphics.setColor(Color.blue);
                graphics.setFont(new Font(null, Font.BOLD, 80));
                graphics.drawString("Hello, World!", 40, 100);
            }
        }; //(1) JWindowを継承して全画面表示したいウィンドウを作成する。

        testGraphicsDevice(window);
    }

    /**
     * 指定したウィンドウを、フルスクリーン排他モードに設定する。
     * @param window 表示するwindow
     */
    private static void testGraphicsDevice(Window window)
    {
        // (2) GraphicsEnvironmentを取得する。
        GraphicsEnvironment graphicsEnvironment =
            GraphicsEnvironment.getLocalGraphicsEnvironment();

        // (3) GraphicsEnvironmentからGraphicsDeviceを取得する。
        GraphicsDevice graphicsDevice = graphicsEnvironment.getDefaultScreenDevice();

        // (4) フルスクリーン排他モードに変更する。
        graphicsDevice.setFullScreenWindow(window);

        try
        {
            Thread.sleep(3000);
        }
        catch (InterruptedException iex)
        {
            ;
        }
        
        // (5) フルスクリーン排他モードを解除する。
        graphicsDevice.setFullScreenWindow(null);
        System.exit(0);
    }
 }

Page Top

<Q8-2>Windows98上で、JDialogを閉じる時に一般保護違反例外が発生してしまいます。

例外がIMM32.DLLで発生しています。

<発生環境>
OS Windows
JDK JDK1.3.0
Vender Sun
<A8-2>
IMEとの相性問題によるものです。
インスタンスを破棄するときにdispose()の代わりにfinalize()を実行するように実装することで解決できます。また、finalize()はprotectedメソッドであるため、継承/委譲クラスを作成する必要があります。
BugParade#4366221 を参照してください。

参考URL:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4366221
Page Top

<Q8-3>一部機種(またはグラフィックスチップ?詳細は未調査)において、Swingコンポーネントの再描画が正しく行われません。


<発生環境>
OS Windows
JDK JDK1.2.2/JDK1.3.0
Vender Sun
<A8-3>
Javaの起動オプションに-Dsun.java2d.noddraw=trueを付与することで、解決できます。(DirectDrawを描画に使用しないことを意味する)
BugParade#4197243 を参照してください。

参考URL:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4197243
Page Top

<Q8-4>JTextFiledでIME2000を使用して文字を入力中にF5キーを押すとコンソールに大量のトレースが出力されてしまいます。

Windows98において、javawを使用して起動したjavaプロセスの場合、コンソールバッファが詰まってプログラム動作が停止してしまいます。(Q5-3に関連)

<発生環境>
OS Windows
JDK JDK1.3.0
Vender Sun
<A8-4>
未解決です。
Page Top

<Q8-5>画面を(比較的速いスピードで)閉じたり開いたりしていると、その画面に設定されていたフォーカスが消えてしまいます。

再現頻度:1時間ほど画面のオープンクローズを繰り返しつづけて1回出るか出ないかです。

<発生環境>
OS Windows98
JDK JDK1.3
Vender Sun
<A8-5>
原因不明です。
仕様として、「画面を開いた際のデフォルトフォーカス」というものを設け、setVisibleされた際に必ずそのコンポーネントにフォーカスを当てることで解決できます。
Page Top

<Q8-6>JFrameをsetEnabled(false)で使用不可にしても、その中に含まれるコンポーネントは使用できてしまいます。

たとえば、マウスカーソルがテキストフィールドにある状態で、上記のように使用不可にしても、テキストが入力できてしまいます。

<発生環境>
OS Windows2000/NT
JDK JDK1.3
Vender Sun
<A8-6>
JFrameのsetEnabledをオーバーライドし、中に含まれる全てのコンポーネントのsetEnabledメソッドを呼ぶようにすることで解決できます。
Page Top

<Q8-7>JButtonのフォーカスが外れていても、Enterキーを押すと、そのボタンが押されたような動きをしてしまいます。

Look&FeelがWindowsの場合のみに発生します。

<発生環境>
OS Windows2000/NT
JDK JDK1.3
Vender Sun
<A8-7>
そのJButtonが、その画面のデフォルトボタンになっているためです。
setDefaultCapable(false)で解除すれば、この現象は出なくなります。
Page Top

<Q8-8>JTextField(JPasswordField)で、スクロールが開始される文字数の文字を入力すると、カーソル(キャレット)が残ったままスクロールされてしまいます。

しかし、再描画を行うと、カーソルは消えます。

<発生環境>
OS Windows2000/NT
JDK JDK1.3
Vender Sun
<A8-8>
BugParade #4338315を参照してください。
JDK1.4Betaで修正された模様です。

参考URL:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4338315
Page Top

<Q8-9>JMenuBarの要素が空の画面で、F10キーを押下すると、ArrayIndexOutOfBoundsExceptionが発生してしまいます。


<発生環境>
OS Windows2000/NT
JDK JDK1.3
Vender Sun
<A8-9>
JMenuBarの要素が無い場合は、JFrameにaddしないようにすることで解決できます。
Page Top

<Q8-10>ポップアップメニュー(カスケードメニュー)を表示させてから一度選択すると、次回選択時にNullPointerExceptionを出力し、正常に動作しません。


<発生環境>
OS WindowsNT4
JDK JDK1.3
Vender Sun
<A8-10>
Bug Parade-4298592に記載されている対処策で解決することができます(JDK1.3.1では解決されています)。

参考URL:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4298592
Page Top

<Q8-11>モーダレスダイアログを表示すると、親画面が操作不能になってしまう場合があります。


<発生環境>
OS Windows2000
JDK JDK1.3
Vender Sun
<A8-11>
親画面を最小化した状態でモーダレスダイアログ(ダイアログを閉じなくても親画面を操作できる)を開くと、ダイアログを閉じるまで親画面を最大化することができません。
最小化されているウィンドウを親とするダイアログを開く場合、親ウィンドウを通常サイズに戻す、といった対応が必要になります。
Page Top

<Q8-12>モーダルダイアログを表示すると、一部の画面だけでなく、表示中の全画面が操作不能になってしまいます。


<発生環境>
OS WindowsNT4,WindowsXP
JDK JDK1.3,JDK1.4
Vender Sun
<A8-12>
Swingのモーダルダイアログは、特定の画面に対しては働かず、全画面に対してモーダルになってしまいます。
回避策としては、Swingのモーダル機能は用いず、すべてモーダレスにして、自分自身で親画面を選択不可にする方法があります。
Page Top

<Q8-13>Solarisにて、WindowsスタイルのLook&Feelが正しく設定できません。

以下の設定が行えません。

javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

<発生環境>
OS Solaris
JDK JDK1.3.1
Vender Sun
<A8-13>
現在、WindowsスタイルのLook&Feelについては、Win32環境でのみサポートされています。 従って、Solaris上で利用することはできません。
Look&Feelのサポート状況については、SunのSwingチュートリアルを参照してください。
Page Top

<Q8-14>JTreeのToolTipText表示処理にて、NullPointerExceptionが発生します。

発生する例外は以下の通りです。

java.lang.NullPointerException
    at javax.swing.JTree.getPathForLocation(JTree.java:1702)
    at javax.swing.JTree.getRowForLocation(JTree.java:1721)
    at javax.swing.JTree.getToolTipText(JTree.java:1009)
    at javax.swing.ToolTipManager.mouseMoved(ToolTipManager.java:522)
    (以下省略)

<発生環境>
OS WindowsNT4
JDK JDK1.3.1
Vender Sun
<A8-14>
javax.swing.JTreeクラスに定義されているツールチップ表示領域を取得する処理で、正しくnullチェックが行われていないためです。
この問題の詳細は、BugParade:4292529を参照してください。
JDK1.3.1以前では、JTreeを継承しnullチェック処理を加えたクラスを利用することで、回避できます。
この問題は、リリースノートには記載されていませんが、JDK1.4.0以降で修正されているようです。

参考URL: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4292529
Page Top

<Q8-15>JTextFieldで入力フィールド長を超える文字入力を行うと、既存文字が上書きされてしまいます。

日本語など、IMを介して文字を入力する場合に発生します。

<発生環境>
OS WindowsNT4
JDK JDK1.3
Vender Sun
<A8-15>
IM利用中におけるフィールド長制限が適切に機能していないのが原因です。IM利用中の未確定文字の場合は、設定フィールド長をオーバーしても入力できるようにし、入力文字確定処理時に最大フィールド長分で文字を切るように変更することで、上書きを回避できます。
Page Top

<Q8-16>JTextAreaにフォーカスがある状態で、TABキーによるコンポーネント間のフォーカス遷移ができません。


<発生環境>
OS Windows98SE / WindowsXP
JDK JDK1.3 / JDK1.4
Vender Sun
<A8-16>
JTextAreaは、テキストエリア内のTAB文字入力を可能にする為、TABキーでフォーカスイベントを発生させないように実装されています。ただし、Ctrl+TABでフォーカス遷移が可能です。
TABキーのみでコンポーネント間のフォーカス遷移を行いたい場合は、JTextAreaにKeyListenerを追加することで挙動を変更可能です。
KeyListener#keyPressed()でKeyEventオブジェクトからキーコードを取得し、TABキーである場合にはComponent#transferFocus()を呼び出します。
Page Top

<Q8-17>JFrameのsetBackground()で背景色を設定しても、フレームの背景色が変更されません。


<発生環境>
OS any
JDK any
Vender any
<A8-17>
JFrameはコンポーネントを配置するためにContentPaneと呼ばれるコンテナを使用します。JFrameの背景色はこのContentPaneの背景色に依存します。
なお、ContentPaneはContainerの拡張であり、通常はJPanelです。
JFrameの背景色を変更する場合は以下のように記述する必要があります。
JFrame frame;
frame.getContentPane().setBackground(<RGB>); 

Page Top

<Q8-18>JLabelのsetBackground()を利用して背景色を設定しても、ラベルの背景色が変更されません。


<発生環境>
OS any
JDK any
Vender any
<A8-18>
JLabelのOpaqueプロパティがデフォルトでfalse(透明)になっているためです。
JLabelの背景色を変更する場合は以下のように設定します。
JLabel label;
label.setOpaque(true);
label.setBackground(<RGB>);

Page Top

<Q8-19>Swingでsleep時間を設定しても、sleepされずに描画されます。

Swingを利用して、「画面消去→sleep→再描画」という処理を行ったのですが、 再描画処理を行いません。

public void redraw(int x, int y){
  // 消去処理
  this.initialize();
  this.view_.getFrame().repaint();

  // sleep処理
  Thread.sleep(1000);

  // 描画処理
  Rectangle2D rectangle = new Rectangle2D.Double(x, y, 1, 1);
  ・・・
  this.view_.getFrame().repaint();
}

<発生環境>
OS Any
JDK JDK5.0以降
Vender Sun
<A8-19>
Swingの仕様です。

Swingはイベント駆動で動作し、イベントキューと呼ばれるキューにためられます。
そして、このイベントキューからイベントを取り出してイベント処理を実行するのが
イベント・ディスパッチ・スレッドです。

Swingでは、このイベント・ディスパッチ・スレッドが描画処理も行います。

そのため、上記のようなプログラムを書いても、イベントキューにイベントが入るタイミングが異なるだけで、
描画処理が行われるときには、イベント取得→描画→イベント取得→描画、という処理が連続して行われます。


この問題を回避するためには、2つの処理を別スレッドに切り分けるなど、
イベント・ディスパッチ・スレッドによって行なわれる2つの描画処理が、
別のタイミングで行われるようにする必要があります。

Page Top

注意:本文書の内容に誤りがあり、またこの文書によって不利益を被っても、
Acroquest Technology 株式会社は一切関知いたしません。

  • 現象別Index
  • 原因別Index

Find Bugsバグ詳細

Find Bugs Bug Descriptions日本語版

RSSで更新情報を取得する

RSSとは、ホームページの更新情報を配信する為のフォーマットです。
RSSを利用すると、登録したページの情報が更新された場合に、更新情報を自動的に受け取る事ができます。

詳細

弊社小森が執筆致しました

Javaでオブジェクト指向開発

Javaプログラミング言語習得において、新人プログラマーの最初の障害は「オブジェクト指向の壁」です。
本書は、Javaのソフトウェア開発を中心に事業を発展させてきたAcroquest社の新人教育セミナーを加筆・書籍化したもので、大卒の新人に対して、ゼロからJava言語を教えてきた実績をフィードバックしています。

メールマガジン配信中

Javaトラブルシューティングのメルマガをはじめました!是非ご購読ください

詳細