package org.andork.swing.list; import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.border.EmptyBorder; import org.andork.awt.GridBagWizard; import org.andork.func.Bimapper; import org.andork.func.Bimappers; import org.andork.q.QArrayList; import org.andork.q.QList; import org.andork.swing.QuickTestFrame; public class QListEditor<T> extends JPanel { private static final long serialVersionUID = -7659154410942818791L; public static void main(String[] args) { QListEditor<String> view = new QListEditor<String>(Bimappers.<String> identity()); view.setModel(new QArrayList<>()); QuickTestFrame.frame(view).setVisible(true); } boolean listening; QList<T, ?> model; Bimapper<T, String> bimapper; JList<T> list; JScrollPane listScroller; JButton removeButton; JButton addButton; Action addAction; Action removeAction; JTextField textField; public QListEditor(Bimapper<T, String> bimapper) { this.bimapper = bimapper; setBorder(new EmptyBorder(5, 5, 5, 5)); initComponents(); initLayout(); initActions(); initListeners(); } @SuppressWarnings("serial") void initActions() { addAction = new AbstractAction("Add") { @Override public void actionPerformed(ActionEvent e) { if (model != null) { model.add(bimapper.unmap(textField.getText())); } textField.setText(""); } }; removeAction = new AbstractAction("Remove Selected") { @Override public void actionPerformed(ActionEvent e) { if (model != null) { int[] selectedIndices = list.getSelectedIndices(); for (int i = selectedIndices.length - 1; i >= 0; i--) { model.remove(selectedIndices[i]); } list.clearSelection(); } } }; } @SuppressWarnings("serial") void initComponents() { list = new JList<>(); list.setCellRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @SuppressWarnings("unchecked") String strValue = bimapper.map((T) value); return super.getListCellRendererComponent(list, strValue, index, isSelected, cellHasFocus); } }); listScroller = new JScrollPane(list); addButton = new JButton("Add"); removeButton = new JButton("Remove Selected"); textField = new JTextField(); } void initLayout() { GridBagWizard w = GridBagWizard.create(this); w.put(textField).xy(0, 0).fillx().weightx(1.0); w.put(addButton).rightOf(textField); w.put(listScroller).below(textField, addButton).fillboth().weighty(1.0); listScroller.setPreferredSize(new Dimension(200, 300)); w.put(removeButton).below(listScroller).fillx(); } void initListeners() { textField.setAction(addAction); addButton.setAction(addAction); removeButton.setAction(removeAction); list.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "removeItem"); list.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), "removeItem"); list.getActionMap().put("removeItem", removeAction); } public void setModel(QList<T, ?> model) { if (this.model != model) { this.model = model; list.setModel(model != null ? new QListListModel<>(model) : new DefaultListModel<>()); } } }