概要

NimbusLookAndFeelを適用したJSpinnerでそのFormattedTextFieldArrowButtonが半透明になるよう設定します。

サンプルコード

UIDefaults d = new UIDefaults();
Painter<JComponent> painter1 = (g, c, w, h) -> {
  g.setColor(new Color(100, 100, 100, 100));
  g.fillRect(0, 0, w, h);
};
Painter<JComponent> painter2 = (g, c, w, h) -> {
  g.setColor(new Color(100, 200, 200, 100));
  g.fillRect(0, 0, w, h);
};
d.put("Spinner:Panel:\"Spinner.formattedTextField\"[Enabled].backgroundPainter", painter1);
d.put("Spinner:Panel:\"Spinner.formattedTextField\"[Focused].backgroundPainter", painter2);
d.put("Spinner:Panel:\"Spinner.formattedTextField\"[Selected].backgroundPainter", painter2);
// d.put("Spinner:Panel:\"Spinner.formattedTextField\"[Focused+Selected].backgroundPainter", painter2);
// d.put("Spinner:Panel:\"Spinner.formattedTextField\"[Disabled].backgroundPainter", painter);

Painter<JComponent> painter3 = (g, c, w, h) -> {
  g.setColor(new Color(100, 100, 200, 100));
  g.fillRect(0, 0, w, h);
};
Painter<JComponent> painter4 = (g, c, w, h) -> {
  g.setColor(new Color(120, 120, 120, 100));
  g.fillRect(0, 0, w, h);
};
d.put("Spinner:\"Spinner.previousButton\"[Enabled].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.previousButton\"[Focused+MouseOver].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.previousButton\"[Focused+Pressed].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.previousButton\"[Focused].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.previousButton\"[MouseOver].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.previousButton\"[Pressed].backgroundPainter", painter4);

d.put("Spinner:\"Spinner.nextButton\"[Enabled].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.nextButton\"[Focused+MouseOver].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.nextButton\"[Focused+Pressed].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.nextButton\"[Focused].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.nextButton\"[MouseOver].backgroundPainter", painter3);
d.put("Spinner:\"Spinner.nextButton\"[Pressed].backgroundPainter", painter4);

SpinnerModel model = new SpinnerNumberModel(0, 0, 100, 5);
JSpinner spinner1 = new JSpinner(model);
// NG: spinner1.putClientProperty("Nimbus.Overrides", d);
((JSpinner.DefaultEditor) spinner1.getEditor())
    .getTextField().putClientProperty("Nimbus.Overrides", d);
configureSpinnerButtons(spinner1, d);
View in GitHub: Java, Kotlin

解説

  • UIDefaultsを作成してJSpinnerFormattedTextFieldArrowButtonで使用するPainterを登録
    • Nimbus Defaults (The Java™ Tutorials > Creating a GUI With JFC/Swing > Modifying the Look and Feel)にキー一覧がある
    • JSpinnerFormattedTextFieldSpinner:Panel:"Spinner.formattedTextField"[Enabled].backgroundPainterのようにPanelが付くので注意
    • JSpinnerPreviousButtonSpinner:\"Spinner.previousButton\"[Enabled].backgroundPainterだが、上記のチュートリアルではcodeviousButtonと文字化けしているので注意が必要
      • <pre><code>タグに変換しようとしてpreviouscodeviousになっている?
      • 他にもColorChooser.previewPanelHolderColorChooser.codeviewPanelHolderComboBox.pressedWhenPopupVisibleComboBox.codessedWhenPopupVisibleと同様におかしくなっている
      • NimbusBrowser.javaで生成されるhtmlファイルでは問題ないのでThe Java™ Tutorialsに転載するときに変換ミスがあったのかもしれない
    • JSpinnerNextButtonSpinner:\"Spinner.nextButton\"[Enabled].backgroundPainter
  • putClientProperty("Nimbus.Overrides", d)メソッドでJSpinnerFormattedTextFieldArrowButtonUIDefaultsを上書きで設定
    • JSpinnerUIDefaultsを上書きしても無効でJFormattedTextFieldJButtonを取得して直接それに設定する必要がある
    • JFormattedTextFieldJSpinner.DefaultEditor#getTextField()で取得可能
    • ArrowButtonを取得するメソッドは存在しないので名前がSpinner.previousButtonSpinner.nextButtonになっているJButtonを検索して取得している
    • 特定のJSpinnerputClientProperty(...)を設定しても他のJSpinnerまで上書きされてしまう?

参考リンク

コメント