001: /*
002: * Copyright (C) 2005 Jeff Tassin
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package com.jeta.swingbuilder.gui.handler;
020:
021: import java.awt.Component;
022: import java.awt.Point;
023: import java.awt.event.MouseEvent;
024:
025: import javax.swing.JOptionPane;
026: import javax.swing.SwingUtilities;
027:
028: import com.jeta.forms.gui.components.ComponentFactory;
029: import com.jeta.forms.gui.components.ComponentSource;
030: import com.jeta.forms.gui.form.FormComponent;
031: import com.jeta.forms.gui.form.GridCellEvent;
032: import com.jeta.forms.gui.form.GridComponent;
033: import com.jeta.forms.gui.form.GridView;
034: import com.jeta.open.i18n.I18N;
035: import com.jeta.swingbuilder.gui.commands.AddComponentCommand;
036: import com.jeta.swingbuilder.gui.commands.CommandUtils;
037: import com.jeta.swingbuilder.gui.commands.EditTextPropertyCommand;
038: import com.jeta.swingbuilder.gui.commands.MoveComponentCommand;
039: import com.jeta.swingbuilder.gui.editor.FormEditor;
040: import com.jeta.swingbuilder.gui.formmgr.FormManagerDesignUtils;
041:
042: /**
043: * Mouse event handler for a standard grid cell. This is for a cell that
044: * contains any component except a child form (i.e. GridView)
045: *
046: * @author Jeff Tassin
047: */
048: public class StandardCellHandler extends AbstractMouseHandler {
049: /** @directed */
050: private GridComponent m_cell;
051: private ComponentSource m_compsrc;
052:
053: /** ctor */
054: public StandardCellHandler(GridComponent comp,
055: ComponentSource compsrc) {
056: super (comp);
057: m_cell = comp;
058: m_compsrc = compsrc;
059: assert (m_cell != null);
060: assert (compsrc != null);
061: }
062:
063: /**
064: * @return true if the cell associated with this handler contains the mouse
065: * point for the given event.
066: */
067: private boolean containsMouse(MouseEvent e) {
068: Point local_pt = SwingUtilities.convertPoint((Component) e
069: .getSource(), e.getPoint(), m_cell.getParent());
070: if (local_pt.x >= m_cell.getCellX()
071: && local_pt.x < (m_cell.getCellX() + m_cell
072: .getCellWidth())
073: && local_pt.y >= m_cell.getCellY()
074: && local_pt.y < (m_cell.getCellY() + m_cell
075: .getCellHeight())) {
076: return true;
077: } else {
078: return false;
079: }
080: }
081:
082: /**
083: * @return the component under the given mouse. This can be different that
084: * the component associated with this handler if another component
085: * spans multiple cells and overlaps the cell occupied by this
086: * component.
087: */
088: private GridComponent getComponent(MouseEvent e) {
089: if (containsMouse(e)) {
090: GridView view = getView();
091: GridComponent gc = view.getOverlappingComponent(m_cell
092: .getColumn(), m_cell.getRow());
093: if (gc == null)
094: return m_cell;
095: else
096: return gc;
097: }
098: return null;
099: }
100:
101: /** @return the grid view associated with this handler */
102: public GridView getView() {
103: return m_cell.getParentView();
104: }
105:
106: /**
107: * MouseMotionListener implementation. Note that the source will always be
108: * the top level window. So, we need to convert the mouse point to the
109: * coordinates of our associated overlay window before any other operation.
110: */
111: public void mouseMoved(MouseEvent e) {
112: if (!m_compsrc.isSelectionTool() || isDragging()) {
113: GridComponent gc = getComponent(e);
114: if (gc != null) {
115: /**
116: * If the component is not the component associated with this
117: * handler, let's just forward the call to that component. The
118: * reason is the component might span multiple cells and it
119: * might be a child form.
120: */
121: if (gc != m_cell) {
122: gc.getMouseHandler().mouseMoved(e);
123: } else {
124: gc.setSelected(true);
125: }
126: }
127: }
128: }
129:
130: public void mousePressed(MouseEvent e) {
131: if (containsMouse(e)) {
132: FormEditor editor = FormEditor.getEditor(getView());
133: GridComponent gc = getComponent(e);
134: if (gc != null && editor != null) {
135: /**
136: * If the component is not the component associated with this
137: * handler, let's just forward the call to that component. The
138: * reason is the component might span multiple cells or it might
139: * be a child form.
140: */
141: if (gc != m_cell) {
142: gc.getMouseHandler().mousePressed(e);
143: } else {
144: if (m_compsrc.isSelectionTool()) {
145: gc.setSelected(true);
146: Component comp = gc.getBeanDelegate();
147: if (comp != null && e.getClickCount() == 1) {
148: setDragSource(this );
149: }
150: if (e.getClickCount() > 1) {
151: if ((e.getModifiers() & java.awt.event.InputEvent.CTRL_MASK) != 0) {
152: editComponentName(gc);
153: } else {
154: tryEditDefaultProperty(gc);
155: gc.fireGridCellEvent(new GridCellEvent(
156: GridCellEvent.EDIT_COMPONENT,
157: gc));
158: }
159: }
160: } else {
161: try {
162: ComponentFactory factory = m_compsrc
163: .getComponentFactory();
164: if (factory != null) {
165: final GridComponent comp = factory
166: .createComponent("", getView());
167: if (comp != null) {
168: /**
169: * Special case when adding a linked form we
170: * need to check if the target editor does
171: * not already contain that linked form
172: */
173: if (comp instanceof FormComponent) {
174: FormComponent fc = (FormComponent) comp;
175: if (fc.isLinked()) {
176: if (FormManagerDesignUtils
177: .containsForm(
178: editor
179: .getFormComponent(),
180: fc.getId())) {
181: String msg = I18N
182: .format(
183: "Only one instance of a linked form allowed per view.",
184: fc
185: .getId());
186: String title = I18N
187: .getLocalizedMessage("Error");
188: JOptionPane
189: .showMessageDialog(
190: editor,
191: msg,
192: title,
193: JOptionPane.ERROR_MESSAGE);
194: m_compsrc
195: .setSelectionTool();
196: return;
197: }
198: }
199: }
200:
201: AddComponentCommand cmd = new AddComponentCommand(
202: getView().getParentForm(),
203: comp, gc.getConstraints());
204: CommandUtils.invoke(cmd, editor);
205:
206: if (!e.isControlDown())
207: m_compsrc.setSelectionTool();
208:
209: GridView view = getView();
210: if (view != null)
211: view.deselectAll();
212:
213: javax.swing.SwingUtilities
214: .invokeLater(new Runnable() {
215: public void run() {
216: comp
217: .setSelected(true);
218: }
219: });
220: }
221: }
222: } catch (Exception e1) {
223: m_compsrc.setSelectionTool();
224: e1.printStackTrace();
225: }
226: }
227: }
228: }
229: }
230: }
231:
232: public void mouseReleased(MouseEvent e) {
233: if (containsMouse(e) && isDragging()) {
234: FormEditor editor = FormEditor.getEditor(getView());
235: GridComponent gc = getComponent(e);
236: if (gc != null && editor != null) {
237: /**
238: * If the component is not the component associated with this
239: * handler, let's just forward the call to that component. The
240: * reason is the component might span multiple cells or it might
241: * be a child form.
242: */
243: if (gc != m_cell) {
244: if (getDragSource() != this ) {
245: gc.getMouseHandler().mouseReleased(e);
246: }
247: } else {
248: if (getDragSource() != this ) {
249: GridComponent destComp = m_cell;
250: FormComponent destForm = getView()
251: .getParentForm();
252: GridComponent srcComp = getDragSource()
253: .getGridComponent();
254: FormComponent srcForm = FormComponent
255: .getParentForm(srcComp);
256: MoveComponentCommand cmd = new MoveComponentCommand(
257: destForm, destComp, srcForm, srcComp,
258: m_compsrc);
259: CommandUtils.invoke(cmd, editor);
260: m_compsrc.setSelectionTool();
261: srcComp.setSelected(true);
262: /**
263: * we need to do this in case the user tried to drag a
264: * top-level form from inside a JTabbedPane which is not
265: * allowed
266: */
267: destComp.setSelected(false);
268: }
269: }
270: }
271: }
272: }
273:
274: /** MouseMotionListener implemenation */
275: public void mouseDragged(MouseEvent e) {
276: mouseMoved(e);
277: // System.out.println( "StandMouseDragged..." );
278: }
279:
280: private void editComponentName(GridComponent gc) {
281: Component comp = gc.getBeanDelegate();
282: if (comp != null) {
283: String oldname = comp.getName();
284: String newvalue = javax.swing.JOptionPane
285: .showInputDialog(comp, I18N
286: .getLocalizedMessage("Set Name"), oldname);
287: if (newvalue != null) {
288: comp.setName(newvalue);
289: gc.fireGridCellEvent(new GridCellEvent(
290: GridCellEvent.EDIT_COMPONENT, gc,
291: GridCellEvent.COMPONENT_NAME_CHANGED));
292: }
293: }
294:
295: }
296:
297: /**
298: * Checks if the component has a getText and setText property. If so,
299: * lauches a JOptionPane to allow the user to change the property in place.
300: */
301: private void tryEditDefaultProperty(GridComponent gc) {
302: EditTextPropertyCommand.tryEditTextProperty(FormEditor
303: .getEditor(gc), FormComponent.getParentForm(gc), gc);
304: }
305:
306: }
|