TITLE:JScrollPaneのスクロールを禁止

Posted by aterai at 2005-10-03

JScrollPaneのスクロールを禁止

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

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

サンプルコード

JCheckBox b = new JCheckBox("スクロールを禁止する");
b.addItemListener(new ItemListener() {
  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);
  }
});

解説

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

  • このサンプルでは、"Disable Scrolling"をチェックして無効状態にしても
    • JTableHeaderは無効にしていないので、クリックしてソートや、カラムの移動を行うことができます。
    • JScrollPaneに設定したJPopupMenuを表示することができます。

JDK 1.7.0 で追加されたJLayerを使用して、以下のように入力を禁止する方法もあります。

  • JLayerで指定したコンポーネントへの入力を禁止
    //package example;
    //-*- mode:java; encoding:utf8n; coding:utf-8 -*-
    // vim:set fileencoding=utf-8:
    //@homepage@
    import java.awt.*;
    import java.awt.event.*;
    import java.beans.PropertyChangeEvent;
    import javax.swing.*;
    import javax.swing.plaf.LayerUI;
    import javax.swing.table.*;
    
    public class MainPanel extends JPanel {
      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);
    
        for(int i=0;i<100;i++) { model.addRow(
          new Object[] {"Name "+i, Integer.valueOf(i), Boolean.FALSE}); }
    
        final DisableInputLayerUI layerUI = new DisableInputLayerUI();
        final JLayer<JComponent> jlayer = new JLayer<JComponent>(scroll, layerUI);
    
        check.addItemListener(new ItemListener() {
          @Override public void itemStateChanged(ItemEvent ie) {
            JCheckBox box = (JCheckBox)ie.getSource();
            layerUI.setEnabled(!box.isSelected());
    //         JScrollBar bar = scroll.getVerticalScrollBar();
    //         bar.setEnabled(flag);
    //         scroll.setWheelScrollingEnabled(flag);
    //         table.setEnabled(flag);
          }
        });
    
        scroll.setComponentPopupMenu(new TablePopupMenu());
        table.setInheritsPopupMenu(true);
    
        add(jlayer);
        add(check,  BorderLayout.NORTH);
        setPreferredSize(new Dimension(320, 240));
      }
    
      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);
      }
    
      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]));
        }
      }
    
      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);
        }
      }
    
      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);
      }
    }
    class DisableInputLayerUI extends LayerUI<JComponent> {
      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();
        }
      }
    }
    

コメント