001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form.layoutsupport;
043:
044: import java.awt.*;
045: import java.beans.*;
046: import org.openide.nodes.*;
047: import org.netbeans.modules.form.codestructure.*;
048:
049: /**
050: * Main interface for working with various layouts of visual containers
051: * in Form Editor. An implementations of this interface should hold some
052: * metadata representing the layout, be able to set up live components and
053: * containers (according to the metadata), handle code generation and
054: * persistence, provide drag&drop and resizing support, etc.
055: * This interface is very general, it is not recommended to implement it
056: * directly. There is a default implementation - AbstractLayoutSupport - which
057: * provides most of the necessary functionality, assuming that the supported
058: * layout works with certain patterns and rules.
059: *
060: * @see LayoutConstraints
061: * @see LayoutSupportContext
062: *
063: * @author Tomas Pavek
064: */
065:
066: public interface LayoutSupportDelegate {
067:
068: /** Bit flag indicating possible component resizing in upper direction. */
069: final int RESIZE_UP = 1;
070: /** Bit flag indicating possible component resizing in down direction. */
071: final int RESIZE_DOWN = 2;
072: /** Bit flag indicating possible component resizing in left direction. */
073: final int RESIZE_LEFT = 4;
074: /** Bit flag indicating possible component resizing in right direction. */
075: final int RESIZE_RIGHT = 8;
076:
077: /** Initialization of the layout delegate before the first use.
078: * There are three types of initialization which must be supported:
079: * (1) default initialization for an empty (newly created) layout
080: * (lmInstance == null, fromCode == false),
081: * (2) initialization from an already existing instance of LayoutManager
082: * (lmInstance != null, fromCode == false),
083: * (3) initialization from persistent code structure,
084: * (lmInstance == null, fromCode == true).
085: * @param layoutContext provides a necessary context information for the
086: * layout delegate
087: * @param lmInstance LayoutManager instance for initialization (may be null)
088: * @param fromCode indicates whether to initialize from code structure
089: * @exception any Exception occurred during initialization
090: */
091: void initialize(LayoutSupportContext layoutContext,
092: LayoutManager lmInstance, boolean fromCode)
093: throws Exception;
094:
095: /** Gets the supported layout manager or container class. Container class
096: * is returned if the delegate is "dedicated" to some special container
097: * rather than to a layout manager used generally for any container.
098: * @return the class supported by this delegate
099: * @see isDedicated method
100: */
101: Class getSupportedClass();
102:
103: /** States whether this delegate class is dedicted to some special
104: * container layout.
105: * @return true if the delegates supports just certain container only,
106: * false if the delegates supports a layout manager for use in
107: * any container
108: * @see getSupportedClass method
109: */
110: boolean isDedicated();
111:
112: /** For dedicated supports: check whether given default container instance
113: * is empty.
114: * @param cont default instance of Container
115: * @return true if the container can be used as default (empty) instance
116: * with this layout support
117: */
118: boolean checkEmptyContainer(Container cont);
119:
120: /** Indicates whether the layout should be presented as a node in Component
121: * Inspector (for setting properties). The node is provided for layout
122: * managers typically (except null layou), and not for dedicated containers
123: * support.
124: * @return whether a node should be created for the layout
125: */
126: boolean shouldHaveNode();
127:
128: /** Provides a localized display name for the layout node (to be used in
129: * Component Inspector and Palette).
130: * @return display name of supported layout
131: */
132: String getDisplayName();
133:
134: /** Provides an icon to be used for the layout node in Component
135: * Inspector. Only 16x16 color icon is required.
136: * @param type is one of BeanInfo constants: ICON_COLOR_16x16,
137: * ICON_COLOR_32x32, ICON_MONO_16x16, ICON_MONO_32x32
138: * @return icon to be displayed for node in Component Inspector,
139: * null if no icon is provided
140: */
141: Image getIcon(int type);
142:
143: /** This method returns properties of the supported layout (so of some
144: * LayoutManager implementation class typically). These properties are
145: * editable by the user in Component Inspector when layout node is
146: * selected. These are not properties of individual component constraints
147: * (see LayoutConstraints.getProperties() for that).
148: * @return properties of supported layout
149: */
150: Node.PropertySet[] getPropertySets();
151:
152: /** Returns a class of a customizer for the layout manager being used as
153: * a JavaBean. The class should be a java.awt.Component and
154: * java.beans.Customizer. Such a customizer is usually provided with the
155: * layout bean itself, specified in BeanInfo class. When the customizer is
156: * to be used, it is instantiated and given the reference layout manager
157: * instance (using Customizer.setObject(...) method).
158: * Note: If the layout delegate provides special customizer from
159: * getSupportCustomizer() method, it should still return its class here so
160: * it is apparent that there is some customizer provided.
161: * @return layout customizer class, null if no customizer is provided
162: */
163: Class getCustomizerClass();
164:
165: /** Returns an instance of a special customizer provided by the layout
166: * delegate. This customizer need not implement java.beans.Customizer,
167: * because its creation is under full control of the layout delegate - and
168: * vice versa, the customizer can have full control over the layout
169: * delegate (unlike the bean customizer which operates only with layout
170: * manager bean instance).
171: * Note: If the layout delegate provides the customizer here, the class of
172: * the customizer should be also returned from getCustomizerClass() method.
173: * @return instance of layout support customizer
174: */
175: Component getSupportCustomizer();
176:
177: /** Gets the complete code for setting up the layout (including adding
178: * components).
179: * @return whole container's layout code
180: */
181: CodeGroup getLayoutCode();
182:
183: /** Gets code for setting up one component's constraints and adding the
184: * component to the layout (container).
185: * @return one component's layout code
186: */
187: CodeGroup getComponentCode(int index);
188:
189: /** Gets CodeExpression object representing one component.
190: * @param index index of the component in the layout
191: * @return CodeExpression for a component
192: */
193: CodeExpression getComponentCodeExpression(int index);
194:
195: /** Gets number of components in the layout.
196: * @return number of components in the layout
197: */
198: int getComponentCount();
199:
200: /** This method is called to accept new components before they are added
201: * to the layout (by calling addComponents method). It may adjust the
202: * constraints, or refuse the components by throwing a RuntimeException
203: * (e.g. IllegalArgumentException). It's up to the delagate to display an
204: * error or warning message, the exception is not reported outside.
205: * To accept any components simply do nothing here.
206: * @param compExpressions array of CodeExpression objects representing the
207: * components to be accepted
208: * @param constraints array of layout constraints of the components, may
209: * contain nulls
210: * @param index position at which the components are to be added (inserted);
211: * -1 means that the components will be added at the end
212: * @exception RunTimeException to refuse components
213: */
214: void acceptNewComponents(CodeExpression[] compExpressions,
215: LayoutConstraints[] constraints, int index);
216:
217: /** This method is called after a property of the layout is changed by
218: * the user. The delagate implementation may check whether the layout is
219: * valid after the change and throw PropertyVetoException if the change
220: * should be reverted. It's up to the delagate to display an error or
221: * warning message, the exception is not reported outside. To accept any
222: * changes simply do nothing here.
223: * @param ev PropertyChangeEvent object describing the change
224: */
225: void acceptContainerLayoutChange(PropertyChangeEvent ev)
226: throws PropertyVetoException;
227:
228: /** This method is called after a constraint property of some component
229: * is changed by the user. The delegate implementation may check if the
230: * layout is valid after the change and throw PropertyVetoException if the
231: * change should be reverted. It's up to the delagate to display an error
232: * or warning message, the exception is not reported outside. To accept
233: * any changes simply do nothing here.
234: * @param index index of the component in the layout
235: * @param ev PropertyChangeEvent object describing the change
236: */
237: void acceptComponentLayoutChange(int index, PropertyChangeEvent ev)
238: throws PropertyVetoException;
239:
240: /** Adds new components to the layout. (This is intended just at the
241: * metadata level, no real components are added in fact.)
242: * @param compExpressions array of CodeExpression objects representing the
243: * components to be added
244: * @param constraints array of layout constraints of the components, may
245: * contain nulls
246: * @param index position at which the components should be added (inserted);
247: * if -1, the components should be added at the end
248: */
249: void addComponents(CodeExpression[] compExpressions,
250: LayoutConstraints[] constraints, int index);
251:
252: /** Removes one component from the layout (at metadata level).
253: * @param index index of the component in the layout
254: */
255: void removeComponent(int index);
256:
257: /** Removes all components from the layout (at metadata level).
258: */
259: void removeAll();
260:
261: /** Indicates whether there's some change in the layout in comparison
262: * with the default layout of given container. If there's no change, no
263: * code needs to be delegate (e.g. default FlowLayout in JPanel).
264: * Note this is related to the container layout only, not to components.
265: * @param defaultContainer instance of the default container to compare with
266: * @param defaultContainerDelegate effective container delegate of the
267: * default container (e.g. like content pane of JFrame)
268: * @return whether the current layout is different from the default one
269: */
270: boolean isLayoutChanged(Container defaultContainer,
271: Container defaultContainerDelegate);
272:
273: /** Gets layout constraints for a component at the given index.
274: * @param index index of the component in the layout
275: * @return layout constraints of given component
276: */
277: LayoutConstraints getConstraints(int index);
278:
279: /** This method is called when switching layout - giving an opportunity to
280: * convert the previous constrainst of components to constraints of the new
281: * layout (this layout). This method needs to do nothing if there's no
282: * reasonable conversion possible (addComponents method receives null
283: * constraints then).
284: * @param previousConstraints [input] layout constraints of components in
285: * the previous layout
286: * @param currentConstraints [output] array of converted constraints for
287: * the new layout - to be filled
288: * @param components [input] real components in a real container having the
289: * previous layout
290: */
291: void convertConstraints(LayoutConstraints[] previousConstraints,
292: LayoutConstraints[] currentConstraints,
293: Component[] components);
294:
295: /** Sets up the layout (without adding components) on a real container,
296: * according to the internal metadata representation.
297: * @param container instance of a real container to be set
298: * @param containerDelegate effective container delegate of the container
299: * (e.g. like content pane of JFrame)
300: */
301: void setLayoutToContainer(Container container,
302: Container containerDelegate);
303:
304: /** Adds real components to given container (according to layout
305: * constraints stored for the components).
306: * @param container instance of a real container to be added to
307: * @param containerDelegate effective container delegate of the container
308: * (e.g. like content pane of JFrame)
309: * @param components components to be added
310: * @param index position at which to add the components to container
311: */
312: void addComponentsToContainer(Container container,
313: Container containerDelegate, Component[] components,
314: int index);
315:
316: /** Removes a real component from a real container.
317: * @param container instance of a real container
318: * @param containerDelegate effective container delegate of the container
319: * (e.g. like content pane of JFrame)
320: * @param component component to be removed
321: * @return whether it was possible to remove the component (some containers
322: * may not support removing individual components reasonably)
323: */
324: boolean removeComponentFromContainer(Container container,
325: Container containerDelegate, Component component);
326:
327: /** Removes all components from given real container.
328: * @param container instance of a real container to be cleared
329: * @param containerDelegate effective container delegate of the container
330: * (e.g. like content pane of JFrame)
331: * @return whether it was possible to clear the container (some containers
332: * may not support this)
333: */
334: boolean clearContainer(Container container,
335: Container containerDelegate);
336:
337: /** This method is called when user clicks on the container in form
338: * designer. The layout delegate may do something with the container,
339: * e.g. for JTabbedPane it might switch the selected TAB.
340: * @param p Point of click in the container
341: * @param real instance of the container when the click occurred
342: * @param containerDelegate effective container delegate of the container
343: * (e.g. like content pane of JFrame)
344: */
345: void processMouseClick(Point p, Container container,
346: Container containerDelegate);
347:
348: /** This method is called when a component is selected in Component
349: * Inspector. If the layout delegate is interested in such information,
350: * it should store it and use it e.g. in arrangeContainer method.
351: * @param index position (index) of the selected component in container
352: */
353: void selectComponent(int index);
354:
355: /** In this method, the layout delegate has a chance to "arrange" real
356: * container instance additionally - some other way that cannot be
357: * done through layout properties and added components. For example, the
358: * selected component index can be applied here (see delegates for
359: * CardLayout and JTabbedPane).
360: * @param container instance of a real container to be arranged
361: * @param containerDelegate effective container delegate of the container
362: * (e.g. like content pane of JFrame)
363: */
364: void arrangeContainer(Container container,
365: Container containerDelegate);
366:
367: /** This method should calculate layout constraints for a component dragged
368: * over a container (or just for mouse cursor being moved over container,
369: * without any component). This method is useful for "constraints oriented"
370: * layout managers (like e.g. BorderLayout or GridBagLayout).
371: * @param container instance of a real container over/in which the
372: * component is dragged
373: * @param containerDelegate effective container delegate of the container
374: * (e.g. like content pane of JFrame)
375: * @param component the real component being dragged, can be null
376: * @param index position (index) of the component in its container;
377: * -1 if there's no dragged component
378: * @param posInCont position of mouse in the container delegate
379: * @param posInComp position of mouse in the dragged component; null if
380: * there's no dragged component
381: * @return new LayoutConstraints object corresponding to the position of
382: * the component in the container; may return null if the layout
383: * does not use component constraints, or if default constraints
384: * should be used
385: */
386: LayoutConstraints getNewConstraints(Container container,
387: Container containerDelegate, Component component,
388: int index, Point posInCont, Point posInComp);
389:
390: /** This method should calculate position (index) for a component dragged
391: * over a container (or just for mouse cursor being moved over container,
392: * without any component). This method is useful for layout managers that
393: * don't use component constraints (like e.g. FlowLayout or GridLayout)
394: * @param container instance of a real container over/in which the
395: * component is dragged
396: * @param containerDelegate effective container delegate of the container
397: * (e.g. like content pane of JFrame)
398: * @param component the real component being dragged, can be null
399: * @param index position (index) of the component in its container;
400: * -1 if there's no dragged component
401: * @param posInCont position of mouse in the container delegate
402: * @param posInComp position of mouse in the dragged component; null if
403: * there's no dragged component
404: * @return index corresponding to the position of the component in the
405: * container; may return -1 if the layout rather uses component
406: * constraints, or if a default index should be used
407: */
408: int getNewIndex(Container container, Container containerDelegate,
409: Component component, int index, Point posInCont,
410: Point posInComp);
411:
412: /** This method should paint a feedback for a component dragged over
413: * a container (or just for mouse cursor being moved over container,
414: * without any component). In principle, it should present given component
415: * layout constraints or index graphically.
416: * @param container instance of a real container over/in which the
417: * component is dragged
418: * @param containerDelegate effective container delegate of the container
419: * (e.g. like content pane of JFrame) - here the feedback is painted
420: * @param component the real component being dragged, can be null
421: * @param newConstraints component layout constraints to be presented
422: * @param newIndex component's index position to be presented
423: * (if newConstraints == null)
424: * @param g Graphics object for painting (with color and line style set)
425: * @return whether any feedback was painted (may return false if the
426: * constraints or index are invalid, or if the painting is not
427: * implemented)
428: */
429: boolean paintDragFeedback(Container container,
430: Container containerDelegate, Component component,
431: LayoutConstraints newConstraints, int newIndex, Graphics g);
432:
433: /** Provides resizing options for given component. It can combine the
434: * bit-flag constants RESIZE_UP, RESIZE_DOWN, RESIZE_LEFT, RESIZE_RIGHT.
435: * @param container instance of a real container in which the
436: * component is to be resized
437: * @param containerDelegate effective container delegate of the container
438: * (e.g. like content pane of JFrame)
439: * @param component real component to be resized
440: * @param index position of the component in its container
441: * @return resizing options for the component; 0 if no resizing is possible
442: */
443: int getResizableDirections(Container container,
444: Container containerDelegate, Component component, int index);
445:
446: /** This method should calculate layout constraints for a component being
447: * resized.
448: * @param container instance of a real container in which the
449: * component is resized
450: * @param containerDelegate effective container delegate of the container
451: * (e.g. like content pane of JFrame)
452: * @param component real component being resized
453: * @param index position of the component in its container
454: * @param originalBounds original bounds of the resized component.
455: * @param sizeChanges Insets object with size differences
456: * @param posInCont position of mouse in the container delegate
457: * @return component layout constraints for resized component; null if
458: * resizing is not possible or not implemented
459: */
460: LayoutConstraints getResizedConstraints(Container container,
461: Container containerDelegate, Component component,
462: int index, Rectangle originalBounds, Insets sizeChanges,
463: Point posInCont);
464:
465: /** Cloning method - creates a copy of the layout delegate.
466: * @param targetContext LayoutSupportContext for the new layout delegate
467: * @param compExpressions array of CodeExpression objects representing the
468: * components for the new layout delegate (corresponding to the
469: * current ones)
470: * @return cloned layout delegate instance
471: */
472: LayoutSupportDelegate cloneLayoutSupport(
473: LayoutSupportContext targetContext,
474: CodeExpression[] targetComponents);
475: }
|