| /***************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 |
| * |
| * https://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 org.apache.cayenne.modeler.editor; |
| |
| import org.apache.cayenne.configuration.DataChannelDescriptor; |
| import org.apache.cayenne.configuration.event.ProcedureEvent; |
| import org.apache.cayenne.configuration.event.ProcedureParameterEvent; |
| import org.apache.cayenne.configuration.event.ProcedureParameterListener; |
| import org.apache.cayenne.dba.TypesMapping; |
| import org.apache.cayenne.map.Procedure; |
| import org.apache.cayenne.map.ProcedureParameter; |
| import org.apache.cayenne.map.event.MapEvent; |
| import org.apache.cayenne.modeler.Application; |
| import org.apache.cayenne.modeler.ProjectController; |
| import org.apache.cayenne.modeler.action.ActionManager; |
| import org.apache.cayenne.modeler.action.CopyProcedureParameterAction; |
| import org.apache.cayenne.modeler.action.CreateProcedureParameterAction; |
| import org.apache.cayenne.modeler.action.CutProcedureParameterAction; |
| import org.apache.cayenne.modeler.action.PasteAction; |
| import org.apache.cayenne.modeler.action.RemoveProcedureParameterAction; |
| import org.apache.cayenne.modeler.event.ProcedureDisplayEvent; |
| import org.apache.cayenne.modeler.event.ProcedureDisplayListener; |
| import org.apache.cayenne.modeler.event.ProcedureParameterDisplayEvent; |
| import org.apache.cayenne.modeler.event.TablePopupHandler; |
| import org.apache.cayenne.modeler.pref.TableColumnPreferences; |
| import org.apache.cayenne.modeler.util.CayenneAction; |
| import org.apache.cayenne.modeler.util.CayenneCellEditor; |
| import org.apache.cayenne.modeler.util.CayenneTable; |
| import org.apache.cayenne.modeler.util.ModelerUtil; |
| import org.apache.cayenne.modeler.util.PanelFactory; |
| import org.apache.cayenne.modeler.util.UIUtil; |
| import org.apache.cayenne.modeler.util.combo.AutoCompletion; |
| import org.apache.cayenne.swing.components.LimitedTextField; |
| import org.apache.cayenne.swing.components.image.FilteredIconFactory; |
| |
| import javax.swing.Icon; |
| import javax.swing.JButton; |
| import javax.swing.JComboBox; |
| import javax.swing.JMenuItem; |
| import javax.swing.JPanel; |
| import javax.swing.JPopupMenu; |
| import javax.swing.JToolBar; |
| import javax.swing.SwingConstants; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| import javax.swing.table.DefaultTableCellRenderer; |
| import javax.swing.table.TableColumn; |
| import java.awt.BorderLayout; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.EventObject; |
| import java.util.List; |
| |
| public class ProcedureParameterTab extends JPanel implements ProcedureParameterListener, |
| ProcedureDisplayListener, ExistingSelectionProcessor, ActionListener { |
| |
| protected ProjectController eventController; |
| |
| protected CayenneTable table; |
| protected TableColumnPreferences tablePreferences; |
| protected JButton removeParameterButton; |
| protected JButton moveUp; |
| protected JButton moveDown; |
| |
| /** |
| * By now popup menu items are made similar to toolbar button. (i.e. all |
| * functionality is here) This should be probably refactored as Action. |
| */ |
| protected JMenuItem removeParameterMenu; |
| protected JMenuItem moveUpMenu; |
| protected JMenuItem moveDownMenu; |
| |
| public ProcedureParameterTab(ProjectController eventController) { |
| this.eventController = eventController; |
| |
| init(); |
| |
| eventController.addProcedureDisplayListener(this); |
| eventController.addProcedureParameterListener(this); |
| |
| table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { |
| |
| public void valueChanged(ListSelectionEvent e) { |
| processExistingSelection(e); |
| } |
| }); |
| |
| moveDown.addActionListener(this); |
| moveUp.addActionListener(this); |
| |
| moveDownMenu.addActionListener(this); |
| moveUpMenu.addActionListener(this); |
| } |
| |
| protected void init() { |
| setLayout(new BorderLayout()); |
| |
| JToolBar toolBar = new JToolBar(); |
| toolBar.setFloatable(false); |
| |
| ActionManager actionManager = Application.getInstance().getActionManager(); |
| toolBar.add(actionManager.getAction(CreateProcedureParameterAction.class).buildButton(1)); |
| removeParameterButton = actionManager.getAction(RemoveProcedureParameterAction.class).buildButton(3); |
| toolBar.add(removeParameterButton); |
| toolBar.addSeparator(); |
| |
| Icon up = ModelerUtil.buildIcon("icon-up.png"); |
| Icon down = ModelerUtil.buildIcon("icon-down.png"); |
| |
| moveUp = new CayenneAction.CayenneToolbarButton(null, 1); |
| moveUp.setIcon(up); |
| moveUp.setDisabledIcon(FilteredIconFactory.createDisabledIcon(up)); |
| moveUp.setToolTipText("Move Parameter Up"); |
| toolBar.add(moveUp); |
| |
| moveDown = new CayenneAction.CayenneToolbarButton(null, 3); |
| moveDown.setIcon(down); |
| moveDown.setDisabledIcon(FilteredIconFactory.createDisabledIcon(down)); |
| moveDown.setToolTipText("Move Parameter Down"); |
| toolBar.add(moveDown); |
| |
| toolBar.addSeparator(); |
| toolBar.add(actionManager.getAction(CutProcedureParameterAction.class).buildButton(1)); |
| toolBar.add(actionManager.getAction(CopyProcedureParameterAction.class).buildButton(2)); |
| toolBar.add(actionManager.getAction(PasteAction.class).buildButton(3)); |
| |
| add(toolBar, BorderLayout.NORTH); |
| |
| // Create table with two columns and no rows. |
| table = new CayenneTable(); |
| |
| tablePreferences = new TableColumnPreferences( |
| this.getClass(), |
| "procedure/parameterTable"); |
| |
| // Create and install a popup |
| JPopupMenu popup = new JPopupMenu(); |
| |
| removeParameterMenu = actionManager.getAction( |
| RemoveProcedureParameterAction.class).buildMenu(); |
| |
| popup.add(removeParameterMenu); |
| popup.addSeparator(); |
| |
| moveUpMenu = new JMenuItem("Move Parameter Up", up); |
| moveDownMenu = new JMenuItem("Move Parameter Down", down); |
| |
| popup.add(moveUpMenu); |
| popup.add(moveDownMenu); |
| |
| popup.addSeparator(); |
| popup.add(actionManager.getAction(CutProcedureParameterAction.class).buildMenu()); |
| popup |
| .add(actionManager |
| .getAction(CopyProcedureParameterAction.class) |
| .buildMenu()); |
| popup.add(actionManager.getAction(PasteAction.class).buildMenu()); |
| |
| TablePopupHandler.install(table, popup); |
| |
| add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER); |
| |
| actionManager.setupCutCopyPaste( |
| table, |
| CutProcedureParameterAction.class, |
| CopyProcedureParameterAction.class); |
| } |
| |
| public void processExistingSelection(EventObject e) { |
| if (e instanceof ChangeEvent) { |
| table.clearSelection(); |
| } |
| |
| ProcedureParameter[] parameters = new ProcedureParameter[0]; |
| boolean enableUp = false; |
| boolean enableDown = false; |
| boolean enableRemoveButton = false; |
| |
| int selectedRow = table.getSelectedRow(); |
| if (selectedRow >= 0) { |
| enableRemoveButton = true; |
| ProcedureParameterTableModel model = (ProcedureParameterTableModel) table.getModel(); |
| |
| int[] sel = table.getSelectedRows(); |
| parameters = new ProcedureParameter[sel.length]; |
| |
| for (int i = 0; i < sel.length; i++) { |
| parameters[i] = model.getParameter(sel[i]); |
| } |
| |
| if (sel.length == 1) { |
| // scroll table |
| UIUtil.scrollToSelectedRow(table); |
| |
| int rowCount = table.getRowCount(); |
| if (rowCount > 1) { |
| if (selectedRow > 0) { |
| enableUp = true; |
| } |
| if (selectedRow < (rowCount - 1)) { |
| enableDown = true; |
| } |
| } |
| } |
| } |
| |
| removeParameterButton.setEnabled(enableRemoveButton); |
| moveUp.setEnabled(enableUp); |
| moveDown.setEnabled(enableDown); |
| |
| syncButtons(); |
| |
| ProcedureParameterDisplayEvent ppde = new ProcedureParameterDisplayEvent( |
| this, |
| parameters, |
| eventController.getCurrentProcedure(), |
| eventController.getCurrentDataMap(), |
| (DataChannelDescriptor) eventController.getProject().getRootNode()); |
| eventController.fireProcedureParameterDisplayEvent(ppde); |
| } |
| |
| /** |
| * Invoked when currently selected Procedure object is changed. |
| */ |
| public void currentProcedureChanged(ProcedureDisplayEvent e) { |
| Procedure procedure = e.getProcedure(); |
| if (procedure != null && e.isProcedureChanged()) { |
| rebuildTable(procedure); |
| } |
| } |
| |
| /** |
| * Selects a specified parameters. |
| */ |
| public void selectParameters(ProcedureParameter[] parameters) { |
| ModelerUtil.updateActions( |
| parameters.length, |
| RemoveProcedureParameterAction.class, |
| CutProcedureParameterAction.class, |
| CopyProcedureParameterAction.class |
| ); |
| |
| ProcedureParameterTableModel model = (ProcedureParameterTableModel) table.getModel(); |
| |
| List<ProcedureParameter> listAttrs = model.getObjectList(); |
| int[] newSel = new int[parameters.length]; |
| |
| for (int i = 0; i < parameters.length; i++) { |
| newSel[i] = listAttrs.indexOf(parameters[i]); |
| } |
| |
| table.select(newSel); |
| } |
| |
| protected void rebuildTable(Procedure procedure) { |
| ProcedureParameterTableModel model = new ProcedureParameterTableModel( |
| procedure, |
| eventController, |
| this); |
| |
| table.setModel(model); |
| table.setRowHeight(25); |
| table.setRowMargin(3); |
| |
| // number column tweaking |
| TableColumn numberColumn = table.getColumnModel() |
| .getColumn(ProcedureParameterTableModel.PARAMETER_NUMBER); |
| DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); |
| renderer.setHorizontalAlignment(SwingConstants.CENTER); |
| numberColumn.setCellRenderer(renderer); |
| |
| TableColumn typesColumn = table.getColumnModel() |
| .getColumn(ProcedureParameterTableModel.PARAMETER_TYPE); |
| JComboBox typesEditor = Application.getWidgetFactory() |
| .createComboBox(TypesMapping.getDatabaseTypes(), true); |
| AutoCompletion.enable(typesEditor); |
| typesColumn.setCellEditor(Application.getWidgetFactory() |
| .createCellEditor(typesEditor)); |
| |
| // direction column tweaking |
| TableColumn directionColumn = table.getColumnModel() |
| .getColumn(ProcedureParameterTableModel.PARAMETER_DIRECTION); |
| JComboBox directionEditor = Application.getWidgetFactory() |
| .createComboBox(ProcedureParameterTableModel.PARAMETER_DIRECTION_NAMES, false); |
| directionEditor.setEditable(false); |
| directionColumn.setCellEditor(new CayenneCellEditor(directionEditor)); |
| |
| TableColumn precisionColumn = table.getColumnModel().getColumn(ProcedureParameterTableModel.PARAMETER_PRECISION); |
| LimitedTextField limitedPrecisionField = new LimitedTextField(10); |
| precisionColumn.setCellEditor(Application.getWidgetFactory().createCellEditor(limitedPrecisionField)); |
| |
| TableColumn lengthColumn = table.getColumnModel().getColumn(ProcedureParameterTableModel.PARAMETER_LENGTH); |
| LimitedTextField limitedLengthField = new LimitedTextField(10); |
| lengthColumn.setCellEditor(Application.getWidgetFactory().createCellEditor(limitedLengthField)); |
| |
| moveUp.setEnabled(false); |
| moveDown.setEnabled(false); |
| |
| tablePreferences.bind(table, null, null, null); |
| } |
| |
| public void procedureParameterAdded(ProcedureParameterEvent e) { |
| rebuildTable(e.getParameter().getProcedure()); |
| table.select(e.getParameter()); |
| } |
| |
| public void procedureParameterChanged(ProcedureParameterEvent e) { |
| table.select(e.getParameter()); |
| } |
| |
| public void procedureParameterRemoved(ProcedureParameterEvent e) { |
| ProcedureParameterTableModel model = (ProcedureParameterTableModel) table.getModel(); |
| int ind = model.getObjectList().indexOf(e.getParameter()); |
| model.removeRow(e.getParameter()); |
| table.select(ind); |
| } |
| |
| public void actionPerformed(ActionEvent e) { |
| ProcedureParameterTableModel model = (ProcedureParameterTableModel) table.getModel(); |
| ProcedureParameter parameter = model.getParameter(table.getSelectedRow()); |
| |
| int index = -1; |
| |
| if (e.getSource() == moveUp || e.getSource() == moveUpMenu) { |
| index = model.moveRowUp(parameter); |
| } else if (e.getSource() == moveDown || e.getSource() == moveDownMenu) { |
| index = model.moveRowDown(parameter); |
| } |
| |
| if (index >= 0) { |
| table.select(index); |
| |
| // note that 'setCallParameters' is donw by copy internally |
| parameter.getProcedure().setCallParameters(model.getObjectList()); |
| eventController.fireProcedureEvent( |
| new ProcedureEvent(this, parameter.getProcedure(), MapEvent.CHANGE) |
| ); |
| } |
| } |
| |
| /** |
| * Synchronizes state of toolbar and popup menu buttons |
| */ |
| private void syncButtons() { |
| removeParameterMenu.setEnabled(removeParameterButton.isEnabled()); |
| moveUpMenu.setEnabled(moveUp.isEnabled()); |
| moveDownMenu.setEnabled(moveDown.isEnabled()); |
| } |
| } |