Swing/LargeCellEditor の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/LargeCellEditor へ行く。
- Swing/LargeCellEditor の差分を削除
--- category: swing folder: LargeCellEditor title: JTableの編集にセルより大きなセルエディタを使用 tags: [JTable, JList, GlassPane] author: aterai pubdate: 2006-08-28T00:57:26+09:00 description: 通常のセルエディタではなく、セルより大きなアイコンを選択する為のセルエディタを使用してJTableを編集します。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTO6b-zTJI/AAAAAAAAAdI/UAROdzzun4k/s800/LargeCellEditor.png --- * 概要 [#summary] 通常のセルエディタではなく、セルより大きなアイコンを選択する為のセルエディタを使用して`JTable`を編集します。 #download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTO6b-zTJI/AAAAAAAAAdI/UAROdzzun4k/s800/LargeCellEditor.png) * サンプルコード [#sourcecode] #code(link){{ class IconTable extends JTable { private static final int XOFF = 4; private final JList<IconItem> editor; private final JComponent glassPane = new JComponent() { @Override public void setVisible(boolean flag) { super.setVisible(flag); setFocusTraversalPolicyProvider(flag); setFocusCycleRoot(flag); } @Override protected void paintComponent(Graphics g) { g.setColor(new Color(0x64_FF_FF_FF, true)); g.fillRect(0, 0, getWidth(), getHeight()); BufferedImage bufimg = new BufferedImage( getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = bufimg.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .15f)); g2.setPaint(Color.BLACK); Rectangle r = editor.getBounds(); for (int i = 0; i < XOFF; i++) { g2.fillRoundRect( r.x - i, r.y + XOFF, r.width + i + i, r.height - XOFF + i, 5, 5); } g2.dispose(); g.drawImage(bufimg, 0, 0, null); } }; protected IconTable(TableModel model, ListModel<IconItem> list) { super(model); setDefaultRenderer(Object.class, new IconTableCellRenderer()); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); initCellSize(50); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { startEditing(); } }); editor = new EditorFromList<>(list); editor.getInputMap(JComponent.WHEN_FOCUSED).put( KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel-editing"); editor.getActionMap().put("cancel-editing", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { cancelEditing(); } }); editor.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { Point p = e.getPoint(); IconItem item = editor.getModel().getElementAt(editor.locationToIndex(p)); setValueAt(item, getSelectedRow(), getSelectedColumn()); cancelEditing(); } }); glassPane.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { cancelEditing(); } }); glassPane.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy() { @Override public boolean accept(Component c) { return Objects.equals(c, editor); } }); glassPane.add(editor); glassPane.setVisible(false); } private void initCellSize(int size) { setRowHeight(size); JTableHeader tableHeader = getTableHeader(); tableHeader.setResizingAllowed(false); tableHeader.setReorderingAllowed(false); TableColumnModel m = getColumnModel(); for (int i = 0; i < m.getColumnCount(); i++) { TableColumn col = m.getColumn(i); col.setMinWidth(size); col.setMaxWidth(size); } setBorder(BorderFactory.createLineBorder(Color.BLACK)); } public void startEditing() { getRootPane().setGlassPane(glassPane); Dimension d = editor.getPreferredSize(); editor.setSize(d); int sr = getSelectedRow(); int sc = getSelectedColumn(); Rectangle r = getCellRect(sr, sc, true); Point p = SwingUtilities.convertPoint(this, r.getLocation(), glassPane); p.translate((r.width - d.width) / 2, (r.height - d.height) / 2); editor.setLocation(p); glassPane.setVisible(true); editor.setSelectedValue(getValueAt(sr, sc), true); editor.requestFocusInWindow(); } private void cancelEditing() { glassPane.setVisible(false); } } }} * 解説 [#explanation] 上記のサンプルでは、`JTable`のセルをクリックすると、そのセル上にセルエディタ(`JList`)を表示してアイコンの選択、変更が可能になります。 上記のサンプルでは、`JTable`のセルをクリックするとそのセル上にセルエディタ(`JList`)を表示してアイコンの選択、変更が可能になります。 - デフォルトの`TableCellEditor`は使用しないためすべてのセルを編集不可に設定 - セルをクリックしたときに`JRootPane`の`GlassPane`を可視化 -- この`GlassPane`にアイコンを選択するためのセルエディタとして`JList`を追加 -- `JList`の半透明の影なども`GlassPane`上に描画 -- `GlassPane`を使用しているため`JFrame`の外にセルエディタを描画できない --- `JTable`の周りに余白を設定することで回避 * 参考リンク [#reference] - [https://xp-style-icons.en.softonic.com/ XP Style Icons - Download] * コメント [#comment] #comment - 表示をアニメーションさせたり、音を出したりしても面白そうです。 -- &user(aterai); &new{2006-10-29 (日) 02:03:44}; #comment