Popupeditor pour un jtable

Description

Il s'agit d'une classe permettant d'éditer une cellule de JTable sous la forme d'un PopupMenu.
Le PopupMenu contient des checkBoxMenuItem permettant de sélectionner plusieurs éléments en même temps, et présélectionnés selon la valeur de la cellule.

Source / Exemple :


package popup;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class PopupEditor extends AbstractCellEditor implements TableCellEditor,
        PropertyChangeListener {

    private TableCellRenderer renderer;

    private JXPopupMenu popupMenu = new JXPopupMenu();

    private JButton validate = makeButton("\u21B5", Color.GREEN.darker(),
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    stopCellEditing();
                }
            });

    private JButton cancel = makeButton("X", Color.RED, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            cancelCellEditing();
        }
    });

    private JPanel panelButtons;

    protected JXCheckBoxMenuItem[] checkBoxMenuItems;

    private static final MouseListener mouseListener = new MouseAdapter() {
    };

    public PopupEditor(TableCellRenderer renderer, Object[] items) {
        this.renderer = renderer;

        panelButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        panelButtons.add(validate);
        panelButtons.add(cancel);

        setChoosableItems(items);
    }

    protected JButton makeButton(String text, Color color,
            ActionListener listener) {
        JButton button = new JButton(text);
        button.setForeground(color);
        button.setBorder(BorderFactory.createRaisedBevelBorder());
        button.setFocusPainted(false);
        button.addActionListener(listener);
        return button;
    }

    public boolean stopCellEditing() {
        popupMenu.close();
        return super.stopCellEditing();
    }

    public void cancelCellEditing() {
        popupMenu.close();
        super.cancelCellEditing();
    }

    public void setChoosableItems(Object[] items) {
        popupMenu.removeAll();

        this.checkBoxMenuItems = new JXCheckBoxMenuItem[items.length];
        for (int i = 0; i < items.length; i++) {
            JXCheckBoxMenuItem menuItem = new JXCheckBoxMenuItem(items[i]);
            checkBoxMenuItems[i] = menuItem;
            popupMenu.add(menuItem);
        }

        popupMenu.addSeparator();
        popupMenu.add(panelButtons);
        popupMenu.pack();
        popupMenu.setPackSize(popupMenu.getPreferredSize());
    }

    public Object getCellEditorValue() {
        List list = new ArrayList();
        for (int i = 0; i < checkBoxMenuItems.length; i++) {
            JXCheckBoxMenuItem menuItem = checkBoxMenuItems[i];
            if (menuItem.isSelected()) {
                list.add(menuItem.getItem());
            }
        }
        return list.toArray();
    }

    protected void setCellEditorValue(Object value) {
        for (int i = 0; i < checkBoxMenuItems.length; i++) {
            JXCheckBoxMenuItem menuItem = checkBoxMenuItems[i];
            menuItem.setSelected(false);
        }

        if (value != null) {
            Object[] values = (Object[]) value;
            for (int i = 0; i < checkBoxMenuItems.length; i++) {
                JXCheckBoxMenuItem menuItem = checkBoxMenuItems[i];
                for (int j = 0; j < values.length; j++) {
                    if (values [j] != null && menuItem.getItem().equals(values [j])) {
                        menuItem.setSelected(true);
                        break;
                    }
                }
            }
        }
    }

    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getOldValue() == this && evt.getNewValue() == null) {
            popupMenu.close();
        }
    }

    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        table.removePropertyChangeListener("tableCellEditor", this);
        table.addPropertyChangeListener("tableCellEditor", this);

        setCellEditorValue(value);

        Rectangle rect = table.getCellRect(row, column, false);
        Dimension size = popupMenu.getPackSize();
        popupMenu.setPreferredSize(new Dimension(Math.max(rect.width,
                size.width), size.height));
        popupMenu.show(table, rect.x, rect.y + rect.height);

        Component comp = renderer.getTableCellRendererComponent(table, value,
                isSelected, false, row, column);
        comp.removeMouseListener(mouseListener);
        comp.addMouseListener(mouseListener);
        return comp;
    }

    private static class JXPopupMenu extends JPopupMenu {

        private Dimension packSize;

        private boolean closeable;

        public Dimension getPackSize() {
            return packSize;
        }

        public void setPackSize(Dimension packSize) {
            this.packSize = packSize;
        }

        public void close() {
            closeable = true;
            setVisible(false);
        }

        public void setVisible(boolean b) {
            if (b || closeable) {
                super.setVisible(b);
                closeable = false;
            }
        }
    }

    private static class JXCheckBoxMenuItem extends JCheckBoxMenuItem {

        private Object item;

        public JXCheckBoxMenuItem(Object item) {
            super(item.toString());
            this.item = item;
        }

        public Object getItem() {
            return item;
        }
    }

}

package popup;

import javax.swing.table.DefaultTableCellRenderer;

public class ArrayTableCellRenderer extends DefaultTableCellRenderer {

    private String separator;

    public ArrayTableCellRenderer() {
        this(null);
    }

    public ArrayTableCellRenderer(String separator) {
        this.separator = separator != null ? separator : " ";
    }

    protected void setValue(Object value) {
        if (value != null) {
            value = format((Object[]) value);
        }
        super.setValue(value);
    }

    protected Object format(Object[] values) {
        boolean separate = false;
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < values.length; i++) {
            if (values[i] != null) {
                if (separate) {
                    sb.append(getSeparator());
                }
                sb.append(values[i]);
                separate = true;
            }
        }
        return sb;
    }

    public String getSeparator() {
        return separator;
    }

    public void setSeparator(String separator) {
        this.separator = separator;
    }
}

package popup;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class TestPopupEditor extends JFrame {

    public TestPopupEditor() {
        Object[] couleurs = { "Blanc", "Rouge", "Vert", "Bleu", "Jaune", "Noir" };
        Object[] formes = { "Rond", "Carré", "Triangle" };
        Object[] poids = { "1kg", "2kg", "3kg", "4kg", "5kg" };

        JTable jTable = new JTable(new Object[][] {
                new Object[] { new Object[] { "Rouge", "Vert" }, null, null },
                new Object[] { null, new Object[] { "Carré", "Triangle" },
                        new Object[] { "1kg", "2kg" } }, new Object[3] },
                new String[] { "Couleurs", "Formes", "Poids" });

        jTable.setDefaultRenderer(Object.class, new ArrayTableCellRenderer());

        TableCellRenderer popupRenderer = new ArrayTableCellRenderer();
        jTable.getColumnModel().getColumn(0).setCellEditor(
                new PopupEditor(popupRenderer, couleurs));
        jTable.getColumnModel().getColumn(1).setCellEditor(
                new PopupEditor(popupRenderer, formes));
        jTable.getColumnModel().getColumn(2).setCellEditor(
                new PopupEditor(popupRenderer, poids));

        getContentPane().add(new JScrollPane(jTable));
        setSize(600, 300);
        setVisible(true);
    }

    public static void main(String[] args) {
        new TestPopupEditor();
    }
}

Conclusion :


Merci de vos commentaires !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.