透明にすることを目的としたいくつかの場所で無効なJTextFieldsを使用するアプリケーションがあります。これにより、テキストフィールドの通常の背景の代わりに背景が透けて見えます。
新しいNimbusLAFを実行すると、これらのフィールドは不透明になり(setOpaque(false)を設定しているにもかかわらず)、UIが壊れます。LAFが不透明なプロパティを無視しているようです。背景色を明示的に設定することは、いくつかの場所で困難であり、背景画像が実際には機能しないため、最適ではありません-それでも、LAFのデフォルトの背景を上にペイントし、境界線のような外観を残します(下のスプラッシュ画面には背景は画像と一致するように明示的に設定されています)。
NimbusにJTextFieldの背景をペイントしないようにする方法についてのアイデアはありますか?
注:スレッドセーフなsetText()とラッピング機能が必要なため、JLabelではなくJTextFieldが必要です。
注:私のフォールバックポジションは、システムLAFを引き続き使用することですが、ニンバスの方がかなり見栄えがします。
以下の画像の例を参照してください。
結論
この動作の驚きは、setOpaque()が何を意味するのかを誤って解釈したことによるものです-Nimbusバグレポートから:
これは、Swingの元の設計と、それが何年にもわたって混乱してきた問題です。問題は、setOpaque(false)がLAFの終了に副作用をもたらしたことです。これは、背景を非表示にすることであり、実際にはその目的ではありません。コンポーネントには透明なパーツがあり、スイングはその背後にある親コンポーネントをペイントする必要があると言っても過言ではありません。
NimbusコンポーネントもsetBackground(null)を尊重していないように見えるのは残念です。そうしないと、背景のペイントを停止するための推奨される方法になります。完全に透明な背景を設定することは、私には直感的ではないようです。
私の意見では、setOpaque()/ isOpaque()は誤ったパブリックAPIの選択であり、次のようになっているはずです。
public boolean isFullyOpaque();
isOpaque()== trueはSwingとの契約であり、コンポーネントサブクラスが背景全体のペイントを担当するためです。つまり、親は必要に応じてその領域のペイントをスキップできます(これは重要なパフォーマンスの向上です)。外部の何かがこの契約を(合法的に) 直接変更することはできません。その履行はコンポーネントにコード化される可能性があります。
したがって、コンポーネントの不透明度は、setOpaque()を使用して設定可能であってはなりません。代わりに、setBackground(null)のようなものを使用すると、多くのコンポーネントに「背景がない」ため、完全に不透明になりません。例として、理想的な世界では、ほとんどのコンポーネントに次のようなisOpaque()が必要です。
public boolean isOpaque() { return (background!=null); }