TITLE:JLayerを使用して無効時のコンポーネントの文字色を変更する

Posted by at 2012-02-13

JLayerを使用して無効時のコンポーネントの文字色を変更する

JLayerを使用して、JButtonなどのコンポーネントを無効にしたときの文字色を変更します。

  • &jnlp;
  • &jar;
  • &zip;
JLayerDisabledText.png

サンプルコード

class DisableInputLayerUI extends LayerUI<JComponent> {
  private static final boolean DEBUG_POPUP_BLOCK = true;
  private static final MouseAdapter dummyMouseListener = new MouseAdapter() {};
  private static final KeyAdapter dummyKeyListener = new KeyAdapter() {};
  private boolean isBlocking = false;
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    JLayer jlayer = (JLayer)c;
    if(DEBUG_POPUP_BLOCK) {
      jlayer.getGlassPane().addMouseListener(dummyMouseListener);
      jlayer.getGlassPane().addKeyListener(dummyKeyListener);
    }
    jlayer.setLayerEventMask(
      AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK |
      AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK |
      AWTEvent.FOCUS_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK);
  }
  @Override public void uninstallUI(JComponent c) {
    JLayer jlayer = (JLayer)c;
    jlayer.setLayerEventMask(0);
    if(DEBUG_POPUP_BLOCK) {
      jlayer.getGlassPane().removeMouseListener(dummyMouseListener);
      jlayer.getGlassPane().removeKeyListener(dummyKeyListener);
    }
    super.uninstallUI(c);
  }
  @Override protected void processComponentEvent(
      ComponentEvent e, JLayer<? extends JComponent> l) {
    System.out.println("processComponentEvent");
  }
  @Override protected void processKeyEvent(
      KeyEvent e, JLayer<? extends JComponent> l) {
    System.out.println("processKeyEvent");
  }
  @Override protected void processFocusEvent(
      FocusEvent e, JLayer<? extends JComponent> l) {
    System.out.println("processFocusEvent");
  }
  @Override public void eventDispatched(
      AWTEvent e, JLayer<? extends JComponent> l) {
    if(isBlocking && e instanceof InputEvent) {
      ((InputEvent)e).consume();
    }
  }
  private static final String CMD_BLOCKING = "lock";
  public void setLocked(boolean flag) {
    boolean oldv = isBlocking;
    isBlocking = flag;
    firePropertyChange(CMD_BLOCKING,oldv,isBlocking);
  }
  @Override public void applyPropertyChange(
      PropertyChangeEvent pce, JLayer<? extends JComponent> l) {
    String cmd = pce.getPropertyName();
    if(CMD_BLOCKING.equals(cmd)) {
      JButton b = (JButton)l.getView();
      b.setFocusable(!isBlocking);
      b.setMnemonic(isBlocking?0:b.getText().charAt(0));
      b.setForeground(isBlocking?Color.RED:Color.BLACK);
      l.getGlassPane().setVisible((Boolean)pce.getNewValue());
    }
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、LayerUI#applyPropertyChange(...) をオーバーライドして、コンポーネントを無効にした場合の文字色、Focus移動の禁止、Mnemonic、PopupMenu、ToolTip の非表示を行なっています。

JLayerの場合、無効時の文字色は、JCheckBoxなどが無効な状態での文字色を変更 のように、Look&Feel によっては反映されないといったことがありません。

参考リンク

コメント