TITLE:JListのアイテムを範囲指定で選択

JListのアイテムを範囲指定で選択

編集者:Terai Atsuhiro
作成日:2006-08-14
更新日:2022-08-17 (水) 14:32:17

概要

JListのアイテムをラバーバンドで範囲指定して選択します。

#screenshot

サンプルコード

class MyList extends JList {
  private final Color pcolor;
  private final AlphaComposite alcomp =
    AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
  private final Polygon polygon = new Polygon();
  private final Line2D line = new Line2D.Double();
  private Point srcPoint = null;
  public MyList(ListModel model) {
    super(model);
    pcolor = makeColor();
    setLayoutOrientation(JList.HORIZONTAL_WRAP);
    setVisibleRowCount(0);
    setFixedCellWidth(62);
    setFixedCellHeight(62);
    setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    setCellRenderer(new ListCellRenderer() {
      public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        MyIcon icon = (MyIcon)getModel().getElementAt(index);
        icon.setSelected(isSelected);
        icon.setFocused(cellHasFocus);
        return icon;
      }
    });
    addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e){
        if(srcPoint==null) srcPoint = e.getPoint();
        Point destPoint = e.getPoint();
        polygon.reset();
        polygon.addPoint(srcPoint.x,  srcPoint.y);
        polygon.addPoint(destPoint.x, srcPoint.y);
        polygon.addPoint(destPoint.x, destPoint.y);
        polygon.addPoint(srcPoint.x,  destPoint.y);
        if(srcPoint.getX()==destPoint.getX() || srcPoint.getY()==destPoint.getY()) {
          line.setLine(srcPoint.getX(),srcPoint.getY(),
                       destPoint.getX(),destPoint.getY());
          setSelectedIndices(getIntersectsIcons(line));
        }else{
          setSelectedIndices(getIntersectsIcons(polygon));
        }
        repaint();
      }
    });
    addMouseListener(new MouseAdapter() {
      public void mouseReleased(MouseEvent e) {
        srcPoint = null;
        repaint();
      }
      public void mousePressed(MouseEvent e) {
        if(locationToIndex(e.getPoint())<0) {
          clearSelection();
          repaint();
        }else{
          int index = locationToIndex(e.getPoint());
          MyIcon icon = (MyIcon)getModel().getElementAt(index);
          Rectangle rect = getCellBounds(index,index);
          if(!rect.contains(e.getPoint())) {
            clearSelection();
            repaint();
          }
        }
      }
    });
  }
  public void paint(Graphics g) {
    super.paint(g);
    if(srcPoint==null) return;
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(SystemColor.activeCaption);
    g2d.drawPolygon(polygon);
    g2d.setComposite(alcomp);
    g2d.setColor(pcolor);
    g2d.fillPolygon(polygon);
  }
  private int[] getIntersectsIcons(Shape p) {
    ListModel model = getModel();
    Vector list = new Vector(model.getSize());
    for(int i=0;i<model.getSize();i++) {
      Rectangle r = MyList.this.getCellBounds(i,i);
      if(p.intersects(r)) {
        list.add(new Integer(i));
      }
    }
    int[] il = new int[list.size()];
    for(int i=0;i<list.size();i++) {
      il[i] = ((Integer)list.get(i)).intValue();
    }
    return il;
  }
  private Color makeColor() {
    int r = SystemColor.activeCaption.getRed();
    int g = SystemColor.activeCaption.getGreen();
    int b = SystemColor.activeCaption.getBlue();
    if(r>g) {
      if(r>b) {
        return new Color(r,0,0);
      }else{
        return new Color(0,0,b);
      }
    }else{
      if(g>b) {
        return new Color(0,g,0);
      }else{
        return new Color(0,0,b);
      }
    }
  }
}
  • &jnlp;
  • &jar;
  • &zip;

解説

JListにマウスリスナーを設定して、ドラッグに応じて矩形を描画しています。このとき、その矩形の内部にアイテムアイコンが重なる場合は、それを選択状態に変更しています。選択範囲が矩形にならずに直線になっている場合は、別途その直線と交差するアイテムを選択するようにしています。

JList内のアイテムの配置には、JList#setLayoutOrientation(JList.HORIZONTAL_WRAP)を使って、水平方向に整列された状態にしています。

参考リンク

コメント