概要

JFrameがアクティブであるかどうかでその子JTextComponentのテキスト選択ハイライトの背景色を変更します。

サンプルコード

class FocusOwnerCaret extends DefaultCaret {
  private static final Color COLOR = Color.GRAY.brighter();
  private static final HighlightPainter NO_FOCUS_PAINTER = new DefaultHighlightPainter(COLOR);

  @Override public void focusLost(FocusEvent e) {
    super.focusLost(e);
    updateSelectionHighlightPainter();
  }

  @Override public void focusGained(FocusEvent e) {
    super.focusGained(e);
    updateSelectionHighlightPainter();
  }

  private void updateSelectionHighlightPainter() {
    setSelectionVisible(false); // removeHighlight
    setSelectionVisible(true); // addHighlight
  }

  @Override protected Highlighter.HighlightPainter getSelectionPainter() {
    JTextComponent c = getComponent();
    Container w = c.getTopLevelAncestor();
    // boolean isFocused = w instanceof Window && ((Window) w).isFocused();
    boolean isActive = w instanceof Window && ((Window) w).isActive();
    return c.hasFocus() && isActive ? super.getSelectionPainter() : NO_FOCUS_PAINTER;
    // https://ateraimemo.com/Swing/CaretSelectionHighlight.html
    // return c.hasFocus() ? super.getSelectionPainter() : NO_FOCUS_PAINTER;
  }
}
View in GitHub: Java, Kotlin

解説

  • Default
    • フォーカスが同じJFrame内の別コンポーネントに移動するとテキスト選択ハイライトは非表示になる
    • 別アプリケーションのフレームが選択されて親JFrameが非アクティブ化されてもテキスト選択ハイライトは変化しない
  • Custom
    • JTextAreaでのCaretによる選択状態表示を維持すると同様のCaretJTextAreaに設定し、フォーカスが同じJFrame内の別コンポーネントに移動するとテキスト選択ハイライトを灰色に変更して表示状態を維持する
    • 別アプリケーションのフレームが選択されて親JFrameが非アクティブ化されるとDefaultCaretfocusLostイベントが発生するのでWindow#isActive()メソッドで親JFrameのアクティブ状態を調査しテキスト選択ハイライトの背景色を変更する

参考リンク

コメント