package org.japura.gui; import java.awt.Point; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.DefaultListSelectionModel; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.ListCellRenderer; import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import org.japura.gui.dnd.CheckListTransferHandler; import org.japura.gui.dnd.CheckListTransferable; import org.japura.gui.event.ListCheckListener; import org.japura.gui.event.ListEvent; import org.japura.gui.event.ListLockListener; import org.japura.gui.event.ListModelListener; import org.japura.gui.model.DefaultListCheckModel; import org.japura.gui.model.ListCheckModel; import org.japura.gui.renderer.CheckListRenderer; /** * List with CheckBoxes * <P> * Copyright (C) 2010-2014 Carlos Eduardo Leite de Andrade * <P> * This library is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * <P> * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * <P> * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <A * HREF="www.gnu.org/licenses/">www.gnu.org/licenses/</A> * <P> * For more information, contact: <A HREF="www.japura.org">www.japura.org</A> * <P> * * @author Carlos Eduardo Leite de Andrade */ public class CheckList extends JList{ private static final long serialVersionUID = 7562297704191604289L; private ListCheckModel model; private PopupMenuBuilder<CheckList> popupMenuBuilder; public CheckList() { InputMap im = getInputMap(JComponent.WHEN_FOCUSED); Action copyAction = new AbstractAction() { private static final long serialVersionUID = -7299012786614721676L; public void actionPerformed(ActionEvent e) { String str = CheckListTransferable.toString(getModel(), ", "); Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); cb.setContents(new StringSelection(str), null); } }; im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK), "Copy"); ActionMap am = getActionMap(); am.put("Copy", copyAction); setModel(new DefaultListCheckModel()); setCellRenderer(new CheckListRenderer()); super.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); MouseMotionListener[] mmls = getMouseMotionListeners(); for (MouseMotionListener mml : mmls) { // removeMouseMotionListener(mml); } MouseListener[] listeners = getMouseListeners(); for (MouseListener ml : listeners) { // removeMouseListener(ml); } setTransferHandler(new CheckListTransferHandler()); // ToolTipManager.sharedInstance().registerComponent(this); addMouseMotionListener(new MouseAdapter() { @Override public void mouseMoved(MouseEvent e) { updateSelection(e.getPoint()); } }); addMouseListener(new MouseAdapter() { @Override public void mouseExited(MouseEvent e) { updateSelection(null); } @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { int index = locationToIndex(e.getPoint()); if (index > -1) { Object obj = getModel().getElementAt(index); if (getModel().isLocked(obj) == false) { boolean checked = getModel().isChecked(obj); if (checked) { getModel().removeCheck(obj); } else { getModel().addCheck(obj); } fireActionListener(); } } } else if (SwingUtilities.isRightMouseButton(e) && getPopupMenuBuilder() != null) { JPopupMenu pm = getPopupMenuBuilder().buildPopupMenu(CheckList.this); if (pm != null) { pm.show(CheckList.this, e.getX(), e.getY()); } } } }); } public void addActionListener(ActionListener l) { listenerList.add(ActionListener.class, l); } public void removeActionListener(ActionListener l) { listenerList.remove(ActionListener.class, l); } public ActionListener[] getActionListeners() { return (ActionListener[]) (listenerList.getListeners(ActionListener.class)); } private void fireActionListener() { ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null, System.currentTimeMillis(), 0); for (ActionListener listener : getActionListeners()) { listener.actionPerformed(event); } } @Override public final void setSelectionModel(ListSelectionModel selectionModel) { super.setSelectionModel(new DefaultListSelectionModel()); } @Override public final void setSelectionMode(int selectionMode) { super.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } private void updateSelection(Point point) { if (point != null) { int index = locationToIndex(point); setSelectedIndex(index); } else { clearSelection(); } repaint(); } @Override public ListCheckModel getModel() { if (model == null) { setModel(new DefaultListCheckModel()); } return model; } @Override public void setCellRenderer(ListCellRenderer cellRenderer) { if (cellRenderer instanceof CheckListRenderer) { super.setCellRenderer(cellRenderer); } } public void setCellRenderer(CheckListRenderer cellRenderer) { super.setCellRenderer(cellRenderer); } @Override public CheckListRenderer getCellRenderer() { return (CheckListRenderer) super.getCellRenderer(); } public void setPopupMenuBuilder(PopupMenuBuilder<CheckList> popupMenuBuilder) { this.popupMenuBuilder = popupMenuBuilder; } public PopupMenuBuilder<CheckList> getPopupMenuBuilder() { return popupMenuBuilder; } @Override public void setModel(ListModel model) { if (model instanceof ListCheckModel) { setModel((ListCheckModel) model); } else { throw new IllegalArgumentException("model must be ListCheckModel"); } } public void setModel(ListCheckModel model) { if (model == null) { throw new IllegalArgumentException("model must be non null"); } ListCheckModel oldValue = this.model; this.model = model; if (oldValue != null) { firePropertyChange("model", oldValue, model); } model.addListModelListener(new ListModelListener() { @Override public void valueAdded(ListEvent e) { repaint(); } @Override public void valueRemoved(ListEvent e) { repaint(); } }); model.addListCheckListener(new ListCheckListener() { @Override public void addCheck(ListEvent event) { repaint(); } @Override public void removeCheck(ListEvent event) { repaint(); } }); model.addListLockListener(new ListLockListener() { @Override public void addLock(ListEvent event) { repaint(); } @Override public void removeLock(ListEvent event) { repaint(); } }); repaint(); } }