001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.gui.property;
019:
020: import java.awt.BorderLayout;
021: import java.awt.Point;
022: import java.awt.Rectangle;
023: import java.awt.dnd.DnDConstants;
024: import java.awt.dnd.DropTarget;
025: import java.awt.dnd.DropTargetDragEvent;
026: import java.awt.dnd.DropTargetDropEvent;
027: import java.awt.dnd.DropTargetEvent;
028: import java.awt.dnd.DropTargetListener;
029: import java.awt.event.ActionEvent;
030: import java.awt.event.FocusAdapter;
031: import java.awt.event.FocusEvent;
032: import java.io.Serializable;
033: import java.util.logging.Logger;
034:
035: import javax.swing.AbstractAction;
036: import javax.swing.Action;
037: import javax.swing.JScrollPane;
038: import javax.swing.ListSelectionModel;
039:
040: import de.finix.contelligent.client.base.ComponentFactory;
041: import de.finix.contelligent.client.base.ComponentProperty;
042: import de.finix.contelligent.client.base.TypeProperty;
043: import de.finix.contelligent.client.event.ContelligentEvent;
044: import de.finix.contelligent.client.gui.AbstractComponentEditor;
045: import de.finix.contelligent.client.gui.ContelligentAction;
046: import de.finix.contelligent.client.i18n.Resources;
047:
048: public class PropertyEditor extends AbstractComponentEditor {
049:
050: public final static String DEVELOP = "develop";
051:
052: public final static String EDIT = "edit";
053:
054: public final static String SYSTEM = "system";
055:
056: public final static String META = "meta";
057:
058: public final static String COMPONENT = "component";
059:
060: private static Logger logger = Logger
061: .getLogger(PropertyEditor.class.getName());
062:
063: private PropertyTableModel propertyTableModel;
064:
065: private PropertyTable propertyTable;
066:
067: private String visibleGroup;
068:
069: private DeletePropertyAction deletePropertyAction = new DeletePropertyAction();
070:
071: public void init() {
072: update();
073:
074: propertyTable
075: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
076: propertyTable.getColumnModel().getColumn(0).setPreferredWidth(
077: 50);
078: propertyTable.getColumnModel().getColumn(1).setPreferredWidth(
079: 300);
080: propertyTable.setDropTarget(new DropTarget(this ,
081: new DropHandler(DnDConstants.ACTION_MOVE)));
082:
083: JScrollPane scrollPane = new JScrollPane(propertyTable);
084: scrollPane.getViewport().setOpaque(false);
085: scrollPane.setOpaque(false);
086: add(scrollPane, BorderLayout.CENTER);
087:
088: propertyTable.addFocusListener(new FocusAdapter() {
089: public void focusGained(FocusEvent e) {
090: getView().setActions(getActions());
091: }
092: });
093: }
094:
095: public void update() {
096: if (propertyTableModel == null) {
097: propertyTableModel = new PropertyTableModel(getComponent(),
098: visibleGroup);
099: propertyTableModel.setEditable(isEditable());
100: propertyTable = new PropertyTable(propertyTableModel);
101: } else {
102: propertyTableModel.updateData();
103: propertyTableModel.fireTableDataChanged();
104: }
105: }
106:
107: public void setEditable(boolean editable) {
108: super .setEditable(editable);
109: if (propertyTable != null)
110: propertyTable.stopEditing();
111: if (propertyTableModel != null)
112: propertyTableModel.setEditable(isEditable());
113: }
114:
115: public void setVisibleGroup(String visibleGroup) {
116: this .visibleGroup = visibleGroup;
117: }
118:
119: public void commit() {
120: setEditable(false);
121: ComponentFactory.getInstance().save(getComponent());
122: }
123:
124: public void rollback() {
125: setEditable(false);
126: super .rollback();
127: }
128:
129: public Action[] getActions() {
130: if (isEditable())
131: return new Action[] { deletePropertyAction };
132: else
133: return new Action[] {};
134: }
135:
136: protected void updateComponent() {
137: }
138:
139: protected void componentChanged(ContelligentEvent event) {
140: update();
141: }
142:
143: protected void childComponentAdded(ContelligentEvent event) {
144: }
145:
146: protected void childComponentRemoved(ContelligentEvent event) {
147: }
148:
149: protected void childComponentChanged(ContelligentEvent event) {
150: }
151:
152: protected void descendentComponentChanged(ContelligentEvent event) {
153: }
154:
155: public class DeletePropertyAction extends AbstractAction implements
156: ContelligentAction {
157: public DeletePropertyAction() {
158: super ("reset_action", Resources.deleteIcon);
159: putValue(ROLLOVER_ICON, Resources.deleteIconRollOver);
160: putValue(TYPE, PUSH_ACTION);
161: putValue(ACTION_TYPE, EDIT_ACTION);
162: putValue(MENU_TARGET, MENU);
163: putValue(BUTTON_TARGET, TOOLBAR);
164: }
165:
166: public void actionPerformed(ActionEvent e) {
167: int selectedRow = -1;
168: ComponentProperty property = null;
169:
170: // reset property to the type-property value
171: selectedRow = propertyTable.getSelectedRow();
172: property = (ComponentProperty) propertyTableModel
173: .getValueAt(selectedRow, 1);
174: property.setValue(property.getInitialValue());
175:
176: propertyTableModel.fireTableCellUpdated(selectedRow, 0);
177: propertyTableModel.fireTableCellUpdated(selectedRow, 1);
178: getComponent().setModified(true);
179: }
180: }
181:
182: /**
183: * A "fake" drop handler that simply activates the right table cell for path drops
184: * to path properties. Without this, you used to have to manually click into the
185: * property to make it receive events before dragging.
186: */
187: private class DropHandler implements DropTargetListener,
188: Serializable {
189: private int sourceActions;
190:
191: public DropHandler(int sourceActions) {
192: this .sourceActions = sourceActions;
193: }
194:
195: private boolean actionSupported(int action) {
196: return ((sourceActions & action) != 0);
197: }
198:
199: public void dragEnter(DropTargetDragEvent e) {
200: if (isDragOK(e)) {
201: e.acceptDrag(sourceActions);
202: } else {
203: e.rejectDrag();
204: }
205: }
206:
207: public void dragOver(DropTargetDragEvent e) {
208: if (isDragOK(e)) {
209: Point p = e.getLocation();
210: int scrollSpeed = 20;
211: Rectangle r = new Rectangle(p.x, p.y - scrollSpeed, 1,
212: scrollSpeed * 2);
213: propertyTable.scrollRectToVisible(r);
214: int dropRow = propertyTable.rowAtPoint(p);
215: int dropColumn = propertyTable.columnAtPoint(p);
216: e.acceptDrag(sourceActions);
217: propertyTable.editCellAt(dropRow, dropColumn);
218: } else {
219: e.rejectDrag();
220: }
221: }
222:
223: /**
224: * A utility method to determine where we allow drops. Currently this is only in the
225: * value column of path properties.
226: */
227: private boolean isDragOK(DropTargetDragEvent e) {
228: Point p = e.getLocation();
229: int dropRow = propertyTable.rowAtPoint(p);
230: int dropColumn = propertyTable.columnAtPoint(p);
231: ComponentProperty property = (ComponentProperty) propertyTableModel
232: .getValueAt(dropRow, dropColumn);
233: TypeProperty typeProperty = property.getTypeProperty();
234: if (typeProperty.getPropertyType()
235: .equals(TypeProperty.PATH)
236: && dropColumn == 1) {
237: return true;
238: } else {
239: return false;
240: }
241: }
242:
243: public void dragExit(DropTargetEvent e) {
244: // Intentionally left blank
245: }
246:
247: public void drop(DropTargetDropEvent e) {
248: // Intentionally left blank
249: }
250:
251: public void dropActionChanged(DropTargetDragEvent e) {
252: int dropAction = e.getDropAction();
253:
254: if (actionSupported(dropAction)) {
255: e.acceptDrag(dropAction);
256: } else {
257: e.rejectDrag();
258: }
259: }
260: }
261:
262: }
|