/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package hr.fer.zemris.vhdllab.platform.ui.wizard.support; import hr.fer.zemris.vhdllab.service.ci.Port; import hr.fer.zemris.vhdllab.service.ci.PortDirection; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; import javax.swing.AbstractButton; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableCellEditor; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.IntRange; import org.jdesktop.swingx.autocomplete.ComboBoxCellEditor; import org.jdesktop.swingx.combobox.EnumComboBoxModel; import org.jdesktop.swingx.table.NumberEditorExt; import org.springframework.richclient.command.ActionCommand; import org.springframework.richclient.list.ComboBoxAutoCompletion; import org.springframework.richclient.table.BeanTableModel; import org.springframework.richclient.wizard.AbstractWizardPage; public class PortWizardPage extends AbstractWizardPage { private static final int DEFAULT_MINIMUM_PORT_COUNT = 0; private static final int DEFAULT_MAXIMUM_PORT_COUNT = 30; private static final String PAGE_ID = "newPorts"; protected JTable table; protected BeanTableModel model; protected ActionCommand addAction; protected ActionCommand removeAction; private int minimumPortCount = DEFAULT_MINIMUM_PORT_COUNT; private int maximumPortCount = DEFAULT_MAXIMUM_PORT_COUNT; private PortValidationReporter reporter; public PortWizardPage() { super(PAGE_ID); } public int getMinimumPortCount() { return minimumPortCount; } public void setMinimumPortCount(int minimumPortCount) { this.minimumPortCount = minimumPortCount; } public int getMaximumPortCount() { return maximumPortCount; } public void setMaximumPortCount(int maximumPortCount) { this.maximumPortCount = maximumPortCount; } @SuppressWarnings("unchecked") @Override protected JComponent createControl() { model = new BeanTableModel(Port.class, new ArrayList<Port>(), getMessageSource()) { private static final long serialVersionUID = 1L; @Override protected String[] createColumnPropertyNames() { return new String[] { "name", "direction", "from", "to" }; } @Override protected Class[] createColumnClasses() { return new Class[] { String.class, PortDirection.class, Integer.class, Integer.class }; } }; reporter = new PortValidationReporter(model, this, minimumPortCount, maximumPortCount); table = new JTable(model); table.setCellSelectionEnabled(true); table.getSelectionModel().addListSelectionListener( new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { removeAction.setEnabled(!table.getSelectionModel() .isSelectionEmpty()); } }); final JComboBox inComboBox = new JComboBox(new EnumComboBoxModel( PortDirection.class)); JTextField portName = new JTextField(); new ComboBoxAutoCompletion(inComboBox); table.getColumnModel().getColumn(0).setPreferredWidth(7); table.getColumnModel().getColumn(1).setCellEditor( new DefaultCellEditor(portName)); table.getColumnModel().getColumn(1).setPreferredWidth(120); table.getColumnModel().getColumn(2).setCellEditor( new ComboBoxCellEditor(inComboBox)); table.getColumnModel().getColumn(3) .setCellEditor(new NumberEditorExt()); table.getColumnModel().getColumn(4) .setCellEditor(new NumberEditorExt()); table.setPreferredScrollableViewportSize(new Dimension(300, 200)); table.addKeyListener(new EditComboBoxKeyHandler()); JScrollPane scrollPane = new JScrollPane(table); JPanel control = new JPanel(new BorderLayout()); control.add(createButtons(), BorderLayout.NORTH); control.add(scrollPane, BorderLayout.CENTER); return control; } @Override public void onAboutToShow() { super.onAboutToShow(); validate(); } private void validate() { reporter.validate(); } @SuppressWarnings("unchecked") public List<Port> getPorts() { if(table.isEditing()) { table.getCellEditor().stopCellEditing(); } return model.getRows(); } private Component createButtons() { addAction = new ActionCommand(PAGE_ID + ".addRow") { @Override protected void doExecuteCommand() { Port port = new Port(); port.setDirection(PortDirection.IN); model.addRow(port); } }; removeAction = new ActionCommand(PAGE_ID + ".removeRow") { @Override protected void onButtonAttached(AbstractButton button) { this.setEnabled(false); // remove action is initially disabled super.onButtonAttached(button); } @Override protected void doExecuteCommand() { int selectedRow = table.getSelectedRow(); if (selectedRow != -1) { TableCellEditor cellEditor = table.getCellEditor(); if (cellEditor != null) { cellEditor.stopCellEditing(); } model.remove(selectedRow); int rowToSelect = Math.min(selectedRow, model.getRowCount() - 1); if (rowToSelect != -1) { table.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect); } } } }; getCommandConfigurer().configure(addAction); getCommandConfigurer().configure(removeAction); JPanel buttonPanel = new JPanel(new FlowLayout()); buttonPanel.add(addAction.createButton()); buttonPanel.add(removeAction.createButton()); JPanel control = new JPanel(new BorderLayout()); control.add(buttonPanel, BorderLayout.WEST); return control; } protected class EditComboBoxKeyHandler extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SPACE) { int col = table.getSelectedColumn(); int row = table.getSelectedRow(); if (col != -1 && new IntRange(1, 2).containsInteger(col)) { table.editCellAt(row, col); Component editor = table.getEditorComponent(); if (editor != null) { editor.requestFocusInWindow(); } } } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { int lastRowIndex = model.getRowCount() - 1; if (table.getSelectionModel().isSelectedIndex(lastRowIndex)) { String name = (String) model.getValueAt(lastRowIndex, 1); if (!StringUtils.isEmpty(name)) { addAction.execute(); } } } } } }