Swing/PopupMenuBlockLayer のバックアップの現在との差分(No.2)
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:
概要
JLayer
を使って、子コンポーネントへのすべての入力を制限します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#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の移動など、子コンポーネントへのすべての入力をまとめて制限しています。- JScrollPaneのスクロールを禁止のように、JScrollPane、JTableなどを個別に入力禁止に設定する必要がない
- JLayerで指定したコンポーネントへの入力を禁止と、ほとんど同じだが、その場合、setComponentPopupMenu(...)で設定したJPopupMenuが制限できない。
- JLayer#setLayerEventMask(...)でポップアップメニュー表示の入力イベントが取得できない?(Windows7, JDK 1.7.0_01)
- Cursorを砂時計に変更のように、GlassPaneにダミーのマウスリスナーを追加してポップアップメニューの表示トリガーを無視する
解説
上記のサンプルでは、JLayer
を使用してJScrollBar
の移動、JTable
のセル選択、JToolTip
の表示、JTableHeader
の移動など、子コンポーネントに対するすべての入力をまとめて制限しています。
参考リンク
- JScrollPaneのスクロールを禁止のように
JScrollPane
、JTable
などの各コンポーネント個別に入力禁止にする必要がない - JLayerで指定したコンポーネントへの入力を禁止とほぼ同等だが、このサンプルでは
setComponentPopupMenu(...)
で設定したJPopupMenu
が制限できない点を変更している-
JLayer#setLayerEventMask(...)
でポップアップメニュー表示の入力イベントが取得できない(Windows7
、JDK 1.7.0_01
)ため、Cursorを砂時計に変更のようにGlassPane
に空のマウスリスナーを追加してポップアップメニューの表示トリガーを無視することで対応
-