---
category: swing
folder: PopupMenuBlockLayer
title: JLayerで子コンポーネントへの入力を制限する
tags: [JLayer, GlassPane, JScrollPane, JComponent]
author: aterai
pubdate: 2011-11-28T15:32:54+09:00
description: JLayerを使って、子コンポーネントへのすべての入力を制限します。
image: https://lh5.googleusercontent.com/-Svne2X0djJ8/TtJGGlPU-OI/AAAAAAAABFM/xjZfqHHbkJ0/s800/PopupMenuBlockLayer.png
---
* 概要 [#summary]
`JLayer`を使って、子コンポーネントへのすべての入力を制限します。

#download(https://lh5.googleusercontent.com/-Svne2X0djJ8/TtJGGlPU-OI/AAAAAAAABFM/xjZfqHHbkJ0/s800/PopupMenuBlockLayer.png)

* サンプルコード [#sourcecode]
#code(link){{
class DisableInputLayerUI<V extends Component> extends LayerUI<V> {
  private static final String CMD_REPAINT = "lock";
  private final MouseListener emptyMouseAdapter = new MouseAdapter() {
    /* do nothing listener */
  };
  private boolean isBlocking;

  public void setLocked(boolean flag) {
    firePropertyChange(CMD_REPAINT, isBlocking, flag);
    isBlocking = flag;
  }

  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      JLayer<?> jlayer = (JLayer<?>) c;
      jlayer.getGlassPane().addMouseListener(emptyMouseAdapter);
      jlayer.setLayerEventMask(
          AWTEvent.MOUSE_EVENT_MASK
          | AWTEvent.MOUSE_MOTION_EVENT_MASK
          | AWTEvent.MOUSE_WHEEL_EVENT_MASK
          | AWTEvent.KEY_EVENT_MASK);
    }
  }

  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      JLayer<?> jlayer = (JLayer<?>) c;
      jlayer.setLayerEventMask(0);
      jlayer.getGlassPane().removeMouseListener(emptyMouseAdapter);
    }
    super.uninstallUI(c);
  }

  @Override public void eventDispatched(
      AWTEvent e, JLayer<? extends V> l) {
    if (isBlocking && e instanceof InputEvent) {
      ((InputEvent) e).consume();
    }
  }

  @Override public void applyPropertyChange(
      PropertyChangeEvent e, JLayer<? extends V> l) {
    if (CMD_REPAINT.equals(e.getPropertyName())) {
      l.getGlassPane().setVisible((Boolean) e.getNewValue());
    }
  }
}
}}

* 解説 [#explanation]
上記のサンプルでは、`JLayer`を使用して`JScrollBar`の移動、`JTable`のセル選択、`JToolTip`の表示、`JTableHeader`の移動など、子コンポーネントに対するすべての入力をまとめて制限しています。

- [[JScrollPaneのスクロールを禁止>Swing/DisableScrolling]]のように`JScrollPane`、`JTable`などの各コンポーネント個別に入力禁止にする必要がない
- [[JLayerで指定したコンポーネントへの入力を禁止>Swing/DisableInputLayer]]とほぼ同等だが、このサンプルでは`setComponentPopupMenu(...)`で設定した`JPopupMenu`が制限できない点を変更している
-- `JLayer#setLayerEventMask(...)`でポップアップメニュー表示の入力イベントが取得できない(`Windows7`、`JDK 1.7.0_01`)ため、[[Cursorを砂時計に変更>Swing/WaitCursor]]のように`GlassPane`にダミーのマウスリスナーを追加してポップアップメニューの表示トリガーを無視することで対応
-- `JLayer#setLayerEventMask(...)`でポップアップメニュー表示の入力イベントが取得できない(`Windows7`、`JDK 1.7.0_01`)ため、[[Cursorを砂時計に変更>Swing/WaitCursor]]のように`GlassPane`に空のマウスリスナーを追加してポップアップメニューの表示トリガーを無視することで対応

* 参考リンク [#reference]
- [[JLayerで指定したコンポーネントへの入力を禁止>Swing/DisableInputLayer]]
- [[JScrollPaneのスクロールを禁止>Swing/DisableScrolling]]
- [[Cursorを砂時計に変更>Swing/WaitCursor]]

* コメント [#comment]
#comment
- また`src.zip`などを上げ忘れていたので修正。 -- &user(aterai); &new{2011-11-29 (火) 17:16:11};

#comment