f@0: /* f@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool f@0: f@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) f@0: f@0: This program is free software: you can redistribute it and/or modify f@0: it under the terms of the GNU General Public License as published by f@0: the Free Software Foundation, either version 3 of the License, or f@0: (at your option) any later version. f@0: f@0: This program is distributed in the hope that it will be useful, f@0: but WITHOUT ANY WARRANTY; without even the implied warranty of f@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the f@0: GNU General Public License for more details. f@0: f@0: You should have received a copy of the GNU General Public License f@0: along with this program. If not, see . f@0: */ f@0: package uk.ac.qmul.eecs.ccmi.gui; f@0: f@0: import java.awt.Dimension; f@0: import java.awt.Frame; f@0: import java.awt.GridBagLayout; f@0: import java.awt.event.ActionEvent; f@0: import java.awt.event.ActionListener; f@0: import java.awt.event.WindowAdapter; f@0: import java.awt.event.WindowEvent; f@0: import java.util.List; f@0: import java.util.ResourceBundle; f@0: import java.util.Set; f@0: f@0: import javax.swing.Box; f@0: import javax.swing.BoxLayout; f@0: import javax.swing.JButton; f@0: import javax.swing.JDialog; f@0: import javax.swing.JPanel; f@0: import javax.swing.JScrollPane; f@0: import javax.swing.JSeparator; f@0: import javax.swing.JTable; f@0: f@0: import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties; f@0: import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties.Modifiers; f@0: import uk.ac.qmul.eecs.ccmi.utils.GridBagUtilities; f@0: f@0: /** f@0: * A Dialog for editing the {@link NodeProperties} of a diagram node. f@0: * f@0: */ f@0: @SuppressWarnings("serial") f@0: public class PropertyEditorDialog extends JDialog { f@0: f@0: private PropertyEditorDialog(Frame parent){ f@0: super(parent, resources.getString("dialog.property_editor.title") , true); f@0: setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); f@0: f@0: addWindowListener(new WindowAdapter(){ f@0: @Override f@0: public void windowClosing(WindowEvent event){ f@0: result = null; f@0: dispose(); f@0: } f@0: }); f@0: f@0: listenerManager = new ListenerManager(); f@0: f@0: createComponents(); f@0: setContentPane(scrollPane); f@0: f@0: panel.setLayout(new GridBagLayout()); f@0: f@0: GridBagUtilities gridBagUtils = new GridBagUtilities(); f@0: panel.add(topSeparator,gridBagUtils.all()); f@0: f@0: int i = 0; f@0: for(String type : properties.getTypes()){ f@0: PropertyPanel propertyPanel = new PropertyPanel(type, properties.getValues(type), properties.getModifiers(type)); f@0: panel.add(propertyPanel,gridBagUtils.all()); f@0: propertyPanels[i++] = propertyPanel; f@0: } f@0: f@0: if(!properties.getTypes().isEmpty()) f@0: panel.add(bottomSeparator, gridBagUtils.all()); f@0: buttonPanel.add(okButton); f@0: buttonPanel.add(cancelButton); f@0: panel.add(buttonPanel, gridBagUtils.all()); f@0: f@0: okButton.addActionListener(listenerManager); f@0: cancelButton.addActionListener(listenerManager); f@0: pack(); f@0: } f@0: f@0: /** f@0: * A static method to show a {@code PropertyEditorDialog}. Via this dialog a user can f@0: * specify the entries of a {@code NodeProperties} object and their modifiers, if any have been f@0: * defined during the template creation. f@0: * f@0: * @param parent The parent {@code Frame} of the dialog f@0: * @param properties an instance of {@code NodeProeprties} whose value will be shown in the dialog f@0: * for the user to edit f@0: * @return a reference to {@code properties} containing the new values entered by the user or f@0: * {@code null} if the user presses the cancel button or closes the window. f@0: */ f@0: public static NodeProperties showDialog(Frame parent, NodeProperties properties){ f@0: if(properties == null) f@0: throw new IllegalArgumentException(resources.getString("dialog.property_editor.error.property_null")); f@0: PropertyEditorDialog.properties = properties; f@0: dialog = new PropertyEditorDialog(parent); f@0: dialog.setLocationRelativeTo(parent); f@0: dialog.setVisible(true); f@0: return result; f@0: } f@0: f@0: private void createComponents(){ f@0: panel = new JPanel(); f@0: buttonPanel = new JPanel(); f@0: propertyPanels = new PropertyPanel[PropertyEditorDialog.properties.getTypes().size()]; f@0: scrollPane = new JScrollPane( f@0: panel, f@0: JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, f@0: JScrollPane.HORIZONTAL_SCROLLBAR_NEVER f@0: ); f@0: bottomSeparator = new JSeparator(); f@0: topSeparator = new JSeparator(); f@0: okButton = new JButton(resources.getString("dialog.ok_button")); f@0: cancelButton = new JButton(resources.getString("dialog.cancel_button")); f@0: } f@0: f@0: private JPanel panel; f@0: private JPanel buttonPanel; f@0: private PropertyPanel[] propertyPanels; f@0: private JScrollPane scrollPane; f@0: private JSeparator topSeparator; f@0: private JSeparator bottomSeparator; f@0: private JButton okButton; f@0: private JButton cancelButton; f@0: private ListenerManager listenerManager; f@0: f@0: private static PropertyEditorDialog dialog; f@0: private static NodeProperties properties; f@0: private static NodeProperties result; f@0: private static ResourceBundle resources = ResourceBundle.getBundle(EditorFrame.class.getName()); f@0: f@0: private class PropertyPanel extends JPanel{ f@0: public PropertyPanel(String propertyType, List values, final Modifiers modifiers ){ f@0: setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); f@0: model = new PropertyTableModel(propertyType, values, modifiers); f@0: if(modifiers != null) f@0: for(int i=0; i< values.size(); i++){ f@0: model.setIndexesAt(i, modifiers.getIndexes(i)); f@0: } f@0: table = new JTable(model); f@0: table.setPreferredScrollableViewportSize(new Dimension(250, 70)); f@0: table.setFillsViewportHeight(true); f@0: f@0: add(new JScrollPane(table)); f@0: /* we can edit modifiers only if one or more modifier types have been defined for this property type */ f@0: if(!modifiers.isNull()){ f@0: editModifiers = new JButton(resources.getString("dialog.property_editor.edit_modifiers_button")); f@0: editModifiers.setAlignmentX(RIGHT_ALIGNMENT); f@0: add(editModifiers); f@0: editModifiers.addActionListener(new ActionListener(){ f@0: @Override f@0: public void actionPerformed(ActionEvent arg0) { f@0: int row = table.getSelectedRow(); f@0: if((row == -1)||(row == model.getRowCount()-1)) f@0: return; f@0: Set indexes; f@0: f@0: indexes = ModifierEditorDialog.showDialog(PropertyEditorDialog.this, modifiers.getTypes(), model.getIndexesAt(row)); f@0: model.setIndexesAt(row, indexes); f@0: } f@0: }); f@0: } f@0: add(Box.createRigidArea(new Dimension(0,5))); f@0: } f@0: f@0: JTable table; f@0: PropertyTableModel model; f@0: JButton editModifiers; f@0: } f@0: f@0: private class ListenerManager implements ActionListener{ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: Object source = evt.getSource(); f@0: if(source.equals(okButton)){ f@0: for(int i=0; i