Swing/RubberBanding の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/RubberBanding へ行く。
- Swing/RubberBanding の差分を削除
--- category: swing folder: RubberBanding title: JListのアイテムを範囲指定で選択 tags: [JList, MouseListener, MouseMotionListener] author: aterai pubdate: 2006-08-14T01:35:31+09:00 description: JListのアイテムをラバーバンドで範囲指定して選択します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTSd-lu2aI/AAAAAAAAAi0/AQTsBqR1OUc/s800/RubberBanding.png hreflang: href: https://java-swing-tips.blogspot.com/2008/10/using-rubber-band-selection-in-jlist.html lang: en --- * 概要 [#summary] `JList`のアイテムをラバーバンドで範囲指定して選択します。 #download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTSd-lu2aI/AAAAAAAAAi0/AQTsBqR1OUc/s800/RubberBanding.png) * サンプルコード [#sourcecode] #code(link){{ class RubberBandSelectionList<E extends ListItem> extends JList<E> { private static final AlphaComposite ALPHA = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .1f); private RubberBandListCellRenderer<E> renderer; private Color polygonColor; public RubberBandSelectionList(ListModel<E> model) { super(model); } @Override public void updateUI() { setSelectionForeground(null); setSelectionBackground(null); setCellRenderer(null); if (renderer == null) { renderer = new RubberBandListCellRenderer<E>(); } else { removeMouseMotionListener(renderer); removeMouseListener(renderer); } super.updateUI(); EventQueue.invokeLater(new Runnable() { @Override public void run() { setCellRenderer(renderer); addMouseMotionListener(renderer); addMouseListener(renderer); setLayoutOrientation(JList.HORIZONTAL_WRAP); setVisibleRowCount(0); setFixedCellWidth(62); setFixedCellHeight(62); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); } EventQueue.invokeLater(() -> { setCellRenderer(renderer); addMouseMotionListener(renderer); addMouseListener(renderer); setLayoutOrientation(JList.HORIZONTAL_WRAP); setVisibleRowCount(0); setFixedCellWidth(62); setFixedCellHeight(62); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); }); Color c = getSelectionBackground(); int r = c.getRed(); int g = c.getGreen(); int b = c.getBlue(); polygonColor = r > g ? r > b ? new Color(r, 0, 0) : new Color(0, 0, b) : g > b ? new Color(0, g, 0) : new Color(0, 0, b); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (renderer != null && renderer.polygon != null) { Graphics2D g2 = (Graphics2D) g.create(); g2.setPaint(getSelectionBackground()); g2.draw(renderer.polygon); g2.setComposite(ALPHA); g2.setPaint(polygonColor); g2.fill(renderer.polygon); g2.dispose(); } } } }} * 解説 [#explanation] 上記のサンプルでは、`JList`にマウスリスナーを設定してドラッグに応じた矩形を描画しています。 - `JList`内のアイテムの配置は`JList#setLayoutOrientation(JList.HORIZONTAL_WRAP)`メソッドを使っているため水平方向で整列される - ラバーバンド矩形内部に重なるアイテムアイコンを検索しそれを`JList#setSelectedIndices(int[])`で選択状態に変更 -- %%選択範囲が矩形にならずに直線になっている場合は別途その直線と交差するアイテムを選択%% `Polygon`ではなく`Path2D`を使用することでこれを回避 -- `JDK 1.8.0`以降なら以下を`l.setSelectedIndices(IntStream.range(0, l.getModel().getSize()).filter(i -> p.intersects(l.getCellBounds(i, i))).toArray());`で置き換え可能 #code{{ private int[] getIntersectsIcons(JList l, Shape p) { ListModel model = l.getModel(); List<Integer> list = new ArrayList<>(model.getSize()); for (int i = 0; i < model.getSize(); i++) { Rectangle r = l.getCellBounds(i, i); if (p.intersects(r)) { list.add(i); } } // JDK 1.8.0以降のstreamでList<Integer>をプリミティブなint配列に変換: // return list.stream().mapToInt(i -> i).toArray(); int[] il = new int[list.size()]; for (int i = 0; i < list.size(); i++) { il[i] = list.get(i); } return il; } }} * 参考リンク [#reference] - [https://community.oracle.com/thread/1378164 Swing - Can someone optimise the following code ?] - [https://xp-style-icons.en.softonic.com/ XP Style Icons - Download] - [[JListのアイテムをラバーバンドで複数選択、ドラッグ&ドロップで並べ替え>Swing/DragSelectDropReordering]] -- このラバーバンドで選択したアイテムを実際にドラッグして並べ替えるサンプル * コメント [#comment] #comment - 点線のアニメーション: [http://programamemo2.blogspot.com/2007/08/java.html プログラマメモ2: java ラバーバンドを表現するためのした調べ] -- &user(aterai); &new{2008-08-01 (金) 16:24:28}; - スクリーンショットなどを更新 -- &user(aterai); &new{2008-10-06 (月) 21:29:19}; #comment