TITLE:JLayerで子コンポーネントへの入力を制限する
Posted by aterai at 2011-11-28

JLayerで子コンポーネントへの入力を制限する

JLayerを使って、子コンポーネントへのすべての入力を制限します。
  • 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

概要

JLayerを使って、子コンポーネントへのすべての入力を制限します。
PopupMenuBlockLayer.png

サンプルコード

#spanend
#spanadd
class DisableInputLayerUI<V extends Component> extends LayerUI<V> {
#spanend
  private static final String CMD_REPAINT = "lock";
  private final MouseListener emptyMouseAdapter = new MouseAdapter() {
    /* do nothing listener */
  };
  private boolean isBlocking;

#spandel
**サンプルコード [#p31bbd51]
#spanend
#spandel
#code{{
#spanend
#spandel
class DisableInputLayerUI extends LayerUI<JComponent> {
#spanend
  private static final MouseAdapter dummyMouseListener = new MouseAdapter() {};
  private boolean isBlocking = false;
  public void setLocked(boolean flag) {
    firePropertyChange(CMD_REPAINT, isBlocking, flag);
    isBlocking = flag;
  }
#spanadd

#spanend
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    JLayer jlayer = (JLayer)c;
    jlayer.getGlassPane().addMouseListener(dummyMouseListener);
    jlayer.setLayerEventMask(
      AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK |
      AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
    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);
    }
  }
#spanadd

#spanend
  @Override public void uninstallUI(JComponent c) {
    JLayer jlayer = (JLayer)c;
    jlayer.setLayerEventMask(0);
    jlayer.getGlassPane().removeMouseListener(dummyMouseListener);
    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 l) {
    if(isBlocking && e instanceof InputEvent) {
      ((InputEvent)e).consume();
#spanadd

#spanend
  @Override public void eventDispatched(
      AWTEvent e, JLayer<? extends V> l) {
    if (isBlocking && e instanceof InputEvent) {
      ((InputEvent) e).consume();
    }
  }
  private static final String CMD_REPAINT = "lock";
  public void setLocked(boolean flag) {
    firePropertyChange(CMD_REPAINT,isBlocking,flag);
    isBlocking = flag;
  }
  @Override public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
    String cmd = pce.getPropertyName();
    if(CMD_REPAINT.equals(cmd)) {
      l.getGlassPane().setVisible((Boolean)pce.getNewValue());
#spanadd

#spanend
  @Override public void applyPropertyChange(
      PropertyChangeEvent e, JLayer<? extends V> l) {
    if (CMD_REPAINT.equals(e.getPropertyName())) {
      l.getGlassPane().setVisible((Boolean) e.getNewValue());
    }
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JLayerを使って、JScrollPane(JScrollBar)のスクロール、JTableのセル選択、JToolTip、JTableHeaderの移動など、子コンポーネントへのすべての入力をまとめて制限しています。

解説

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

参考リンク

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

参考リンク

コメント

コメント