TITLE:JScrollPaneのスクロールを禁止
Posted by aterai at 2005-10-03

JScrollPaneのスクロールを禁止

JScrollPaneのスクロールを一時的に禁止します。
  • category: swing folder: DisableScrolling title: JScrollPaneのスクロールを禁止 tags: [JScrollPane, JScrollBar] author: aterai pubdate: 2005-10-03T10:00:11+09:00 description: JScrollPaneのスクロールを一時的に禁止します。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTLM6S99OI/AAAAAAAAAXM/9r2e_2JRA5g/s800/DisableScrolling.png

概要

JScrollPaneのスクロールを一時的に禁止します。
DisableScrolling.png

サンプルコード

#spanend
#spandel
JCheckBox b = new JCheckBox("スクロールを禁止する");
#spanend
#spandel
b.addItemListener(new ItemListener() {
#spanend
  public void itemStateChanged(ItemEvent ie) {
    JCheckBox box = (JCheckBox)ie.getSource();
    boolean flag = !box.isSelected();
    JScrollBar bar = scrollPane.getVerticalScrollBar();
    bar.setEnabled(flag);
    scrollPane.setWheelScrollingEnabled(flag);
    table.setEnabled(flag);
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
JCheckBox check = new JCheckBox("Disable Scrolling");
#spanend
#spanadd
check.addItemListener(new ItemListener() {
#spanend
  @Override public void itemStateChanged(ItemEvent ie) {
    table.clearSelection();
    JScrollBar bar = scroll.getVerticalScrollBar();
    if (ie.getStateChange() == ItemEvent.SELECTED) {
      bar.setEnabled(false);
      scroll.setWheelScrollingEnabled(false);
      table.setEnabled(false);
    } else if (ie.getStateChange() == ItemEvent.DESELECTED) {
      bar.setEnabled(true);
      scroll.setWheelScrollingEnabled(true);
      table.setEnabled(true);
    }
  }
});

解説

  • スクロールバーを取得し、JScrollBar#setEnabled(boolean)メソッドを使って、これを無効にします。
  • JScrollPane#setWheelScrollingEnabled(boolean)メソッドで、マウスホイールによるスクロールを無効にします。
  • JScrollPaneに配置したコンポーネントをsetEnabled(false)とし、フォーカスの移動などによるスクロールを無効にします。

解説

  • Disable Scrollingをチェックして無効状態にする
    • スクロールバーを取得しJScrollBar#setEnabled(boolean)メソッドを使用してこれを無効化
    • JScrollPane#setWheelScrollingEnabled(boolean)メソッドでマウスホイールによるスクロールを無効化
    • JScrollPaneに配置したコンポーネントをsetEnabled(false)とし、フォーカスの移動などによるスクロールを無効化
  • Disable Scrollingをチェックして無効状態にしても実行可能な操作
    • JTableHeaderは無効にしていないのでマウスクリックでのソートやドラッグによるカラムの移動が実行可能
    • JTableに設定したJPopupMenuが表示される
    • JTableに設定したJToolTipが表示される
  • - JDK 1.7.0 で追加されたJLayerを使用して、以下のように入力を禁止する方法もあります。
  • JLayerで指定したコンポーネントへの入力を禁止
    #spanend
    #spandel
    //package example;
    #spanend
    #spandel
    //-*- mode:java; encoding:utf8n; coding:utf-8 -*-
    #spanend
    #spandel
    // vim:set fileencoding=utf-8:
    #spanend
    #spandel
    //@homepage@
    #spanend
    #spandel
    import java.awt.*;
    #spanend
    #spandel
    import java.awt.event.*;
    #spanend
    #spandel
    import java.beans.PropertyChangeEvent;
    #spanend
    #spandel
    import javax.swing.*;
    #spanend
    #spandel
    import javax.swing.plaf.LayerUI;
    #spanend
    #spandel
    import javax.swing.table.*;
    #spanend
    #spanadd
    * 参考リンク [#reference]
    #spanend
    - [[JLayerで子コンポーネントへの入力を制限する>Swing/PopupMenuBlockLayer]]
    -- `JDK 1.7.0`で追加された`JLayer`を使用して入力を制限する方法もある
    - [[JLayerで指定したコンポーネントへの入力を禁止>Swing/DisableInputLayer]]
    
    #spandel
    public class MainPanel extends JPanel {
    #spanend
      private final String[] columnNames = {"String", "Integer", "Boolean"};
      private final Object[][] data = {
        {"aaa", 12, true}, {"bbb", 5, false},
        {"CCC", 92, true}, {"DDD", 0, false},
      };
      DefaultTableModel model = new DefaultTableModel(data, columnNames) {
        @Override public Class<?> getColumnClass(int column) {
          return getValueAt(0, column).getClass();
        }
      };
      private final JTable table     = new JTable(model);
      private final JScrollPane scroll = new JScrollPane(table);
      private final JCheckBox check  = new JCheckBox("Disable Scrolling");
      public MainPanel() {
        super(new BorderLayout());
        TableColumn col = table.getColumnModel().getColumn(0);
        col.setMinWidth(60);
        col.setMaxWidth(60);
        col.setResizable(false);
    #spandel
    
    #spanend
        for(int i=0;i<100;i++) { model.addRow(
          new Object[] {"Name "+i, Integer.valueOf(i), Boolean.FALSE}); }
    #spandel
    
    #spanend
        final DisableInputLayerUI layerUI = new DisableInputLayerUI();
        final JLayer<JComponent> jlayer = new JLayer<JComponent>(scroll, layerUI);
    #spandel
    
    #spanend
        check.addItemListener(new ItemListener() {
          @Override public void itemStateChanged(ItemEvent ie) {
            JCheckBox box = (JCheckBox)ie.getSource();
            layerUI.setEnabled(!box.isSelected());
    #spandel
    //         JScrollBar bar = scroll.getVerticalScrollBar();
    #spanend
    #spandel
    //         bar.setEnabled(flag);
    #spanend
    #spandel
    //         scroll.setWheelScrollingEnabled(flag);
    #spanend
    #spandel
    //         table.setEnabled(flag);
    #spanend
          }
        });
    #spandel
    
    #spanend
        scroll.setComponentPopupMenu(new TablePopupMenu());
        table.setInheritsPopupMenu(true);
    #spandel
    
    #spanend
        add(jlayer);
        add(check,  BorderLayout.NORTH);
        setPreferredSize(new Dimension(320, 240));
      }
    #spandel
    
    #spanend
      class TestCreateAction extends AbstractAction{
        public TestCreateAction(String label, Icon icon) {
          super(label,icon);
        }
        @Override public void actionPerformed(ActionEvent evt) {
          testCreateActionPerformed(evt);
        }
      }
      private void testCreateActionPerformed(ActionEvent e) {
        model.addRow(new Object[] {"New Name", Integer.valueOf(0), Boolean.FALSE});
        Rectangle rect = table.getCellRect(model.getRowCount()-1, 0, true);
        table.scrollRectToVisible(rect);
      }
    #spandel
    
    #spanend
      class DeleteAction extends AbstractAction{
        public DeleteAction(String label, Icon icon) {
          super(label,icon);
        }
        @Override public void actionPerformed(ActionEvent evt) {
          deleteActionPerformed(evt);
        }
      }
      public void deleteActionPerformed(ActionEvent evt) {
        int[] selection = table.getSelectedRows();
        if(selection==null || selection.length<=0) return;
        for(int i=selection.length-1;i>=0;i--) {
          model.removeRow(table.convertRowIndexToModel(selection[i]));
        }
      }
    #spandel
    
    #spanend
      private class TablePopupMenu extends JPopupMenu {
        private final Action createAction = new TestCreateAction("add", null);
        private final Action deleteAction = new DeleteAction("delete", null);
        public TablePopupMenu() {
          super();
          add(createAction);
          addSeparator();
          add(deleteAction);
        }
        @Override public void show(Component c, int x, int y) {
          createAction.setEnabled(!check.isSelected());
          int[] l = table.getSelectedRows();
          deleteAction.setEnabled(l!=null && l.length>0);
          super.show(c, x, y);
        }
      }
    #spandel
    
    #spanend
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() {
            createAndShowGUI();
          }
        });
      }
      public static void createAndShowGUI() {
        try{
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }catch(Exception e) {
          e.printStackTrace();
        }
        JFrame frame = new JFrame("@title@");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    #spandel
    }
    #spanend
    #spandel
    class DisableInputLayerUI extends LayerUI<JComponent> {
    #spanend
      private boolean isBlocking = false;
      @Override public void paint(Graphics g, JComponent c) {
        super.paint(g, c);
        if(!isBlocking) return;
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
        g2.setPaint(Color.GRAY);
        g2.fillRect(0, 0, c.getWidth(), c.getHeight());
        g2.dispose();
      }
      @Override public void installUI(JComponent c) {
        super.installUI(c);
        JLayer jlayer = (JLayer)c;
        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) {
        JLayer jlayer = (JLayer)c;
        jlayer.setLayerEventMask(0);
        super.uninstallUI(c);
      }
      @Override public void eventDispatched(AWTEvent e, JLayer l) {
        if(isBlocking && e instanceof InputEvent) {
          ((InputEvent)e).consume();
        }
      }
      private static final String CMD_REPAINT = "repaint";
      public void setEnabled(boolean flag) {
        isBlocking = !flag;
        firePropertyChange(CMD_REPAINT,flag,!flag);
      }
      @Override public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
        String cmd = pce.getPropertyName();
        if(CMD_REPAINT.equals(cmd)) {
          l.getGlassPane().setVisible((Boolean)pce.getNewValue());
          l.repaint();
        }
      }
    #spandel
    }
    #spanend
    #spandel
    

コメント

コメント