📄 gobject.java
字号:
package no.geosoft.cc.graphics;import java.util.ArrayList;import java.util.List;import java.util.Iterator;import java.util.Collection;import no.geosoft.cc.geometry.Region;import no.geosoft.cc.geometry.Rect;import no.geosoft.cc.geometry.Box;/** * Class representing a graphical object. The representation is * by actual geometry (GSegments) or in terms of sub objects (or both). * <p> * Typically GObject is extended and its draw() method is overloaded: * * <pre> * public class ClientGraphicsObject extends GObject * { * public ClientGraphicsObject() * { * // Prepare the graphics object here, i.e. add the * // GSegments and sub-GObjects it consists of, and * // set rendering style (GStyle) on the elements * // and add annotations (GText) and images (GImage). * } * * public void draw() * { * // Set geometry for all containing GSegments. * } * } * </pre> * * A top level GObject is inserted into the scene like this: * * <pre> * GScene scene = new GScene (window); * * GObject object = new ClientGraphicsObject(); * scene.add (object); * </pre> * * @author <a href="mailto:jacob.dreyer@geosoft.no">Jacob Dreyer</a> */ public class GObject implements GStyleListener{ private static final int FORWARD = -2; private static final int BACKWARD = -3; public static final int DATA_VISIBLE = 1; public static final int ANNOTATION_VISIBLE = 2; public static final int SYMBOLS_VISIBLE = 4; public static final int WIDGETS_VISIBLE = 8; public static final int VISIBLE = 15; public static final int DATA_INVISIBLE = 16; public static final int ANNOTATION_INVISIBLE = 32; public static final int SYMBOLS_INVISIBLE = 64; public static final int WIDGETS_INVISIBLE = 128; public static final int INVISIBLE = 240; private String name_; private Region region_; // Including all children private boolean isRegionValid_; // Has it been computed? private GObject parent_; // Immediate ancestor private int visibilityMask_; private List children_; // of GObject private GStyle style_; // As specified by application private GStyle actualStyle_; // Adjusted for inherits private List segments_; // of GSegment private boolean isDrawn_; private Object userData_; // Application defined /** * Create a graphical object with specified name. * * @param name Name of object. */ public GObject (String name) { name_ = name; parent_ = null; region_ = new Region(); children_ = new ArrayList(); isRegionValid_ = true; segments_ = null; visibilityMask_ = VISIBLE; isDrawn_ = false; style_ = null; actualStyle_ = new GStyle(); } /** * Create a new unnamed graphic object. */ public GObject() { this (null); } /** * Return name of this graphic object. * * @return Name of this graphic object. */ public String getName() { return name_; } /** * Set name of this graphic object. * * @param name New name of this graphic object. */ public void setName (String name) { name_ = name; } /** * Return scene of this graphic object. The scene defines the * world-to-device transformation. * * @return Scene of this graphic object (or null if the object is not * attached to a scene). */ public GScene getScene() { return parent_ != null ? getParent().getScene() : null; } /** * Conveience method for getting the transformation object of the * scene of this object. * * @return Transformation object for this graphic object (or null if the * object is not attached to a scene). */ public GTransformer getTransformer() { GScene scene = getScene(); return scene != null ? scene.getTransformer() : null; } /** * Return the window of this graphic object. * * @return Window of this graphic object (or null if this object is * not attached to a window). */ public GWindow getWindow() { GScene scene = getScene(); return scene != null ? scene.getWindow() : null; } /** * Return the region of this graphic object. The region is a union of * all children objects and the geometry of this object. * * @return The region of this graphic object. */ Region getRegion() { return region_; } /** * Return all segments of this graphic object. * * @return All segments of this object (or null if none). */ public List getSegments() { return segments_; } /** * Return first segment of this graphic object. Convenient if the caller * knows that it contains exactly one segment. * * @return First segment of this graphics object (or null if none). */ public GSegment getSegment() { return segments_ != null && segments_.size() > 0 ? (GSegment) segments_.get(0) : null; } /** * Return the current visibility mask for this object. * @see #setVisibility(int) * * @return Current visibility of this object. */ public int getVisibility() { return visibilityMask_; } /** * Set user data of this graphics object. * * @param userData User data of this graphics object. */ public void setUserData (Object userData) { userData_ = userData; } /** * Return user data of this graphics object. * * @return User data of this graphics object. */ public Object getUserData() { return userData_; } /** * Find sub object based on user data tag. Search from this (included) * and in entire sub tree, depth first. * * @param userData User data of child to find. * @return Requested object (or null if not found). */ public GObject find (Object userData) { if (userData_ == userData) return this; for (Iterator i = children_.iterator(); i.hasNext(); ) { GObject child = (GObject) i.next(); GObject found = child.find (userData); if (found != null) return found; } // Not found return null; } /** * Find a segment with specified user data. Start search in this node. * * @param userData User data of requested segment. * @return Segment (or null if not found). */ public GSegment findSegment (Object userData) { if (segments_ != null) { for (Iterator i = segments_.iterator(); i.hasNext(); ) { GSegment segment = (GSegment) i.next(); if (userData.equals (segment.getUserData())) return segment; } } if (children_ != null) { for (Iterator i = children_.iterator(); i.hasNext(); ) { GObject child = (GObject) i.next(); GSegment segment = child.findSegment (userData); if (segment != null) return segment; } } // Not found return null; } /** * Compute the region for this graphics object. * * @param visibilityMask Visibility of object. */ void computeRegion (int visibilityMask) { visibilityMask &= visibilityMask_; // Stop here if nothing is visible anyway if (visibilityMask == 0) return; // First compute regions for all children for (Iterator i = children_.iterator(); i.hasNext(); ) { GObject child = (GObject) i.next(); child.computeRegion (visibilityMask); } // The region of the scene is always valid if (this instanceof GScene) { isRegionValid_ = true; return; } // Then compute region as union of all children regions and // content of this object if (!isRegionValid_) { region_.clear(); // Children for (Iterator i = children_.iterator(); i.hasNext(); ) { GObject child = (GObject) i.next(); region_.union (child.region_); } // Graphics components at this level if (segments_ != null) { for (Iterator i = segments_.iterator(); i.hasNext(); ) { GSegment segment = (GSegment) i.next(); if (segment.isVisible()) region_.union (segment.getRectangle()); // Add text rectangles to region Collection texts = segment.getTexts(); if (texts != null) { for (Iterator j = texts.iterator(); j.hasNext(); ) { GPositional text = (GPositional) j.next(); region_.union (text.getRectangle()); } } // Add image rectangles to region Collection images = segment.getImages(); if (images != null) { for (Iterator j = images.iterator(); j.hasNext(); ) { GPositional image = (GPositional) j.next(); region_.union (image.getRectangle()); } } // Add component rectangles to region Collection components = segment.getComponents(); if (components != null) { for (Iterator j = components.iterator(); j.hasNext(); ) { GPositional component = (GPositional) j.next(); region_.union (component.getRectangle()); } } // Add vertex image rectangles to region GImage vertextImage = segment.getVertexImage(); if (vertextImage != null && segment.getNPoints() > 0) { Rect imageRectangle = vertextImage.getRectangle(); // The rectangle needs to be positioned for every point int[] x = segment.getX(); int[] y = segment.getY(); for (int j = 0; j < x.length; j++) { Rect rectangle = new Rect (imageRectangle); rectangle.x += x[j]; rectangle.y += y[j]; region_.union (rectangle); } } } } // It might be more efficient to continue with the extent only if (region_.getNRectangles() > 100) region_.collapse(); // This region is now OK, but parent region has to be updated isRegionValid_ = true; if (parent_ != null && !(parent_ instanceof GScene)) parent_.isRegionValid_ = false; } } /** * Flag the region of this graphics object as either valid or invalid. * * @param isValid True if region is valid, false if it is invalid. */ void flagRegionValid (boolean isValid) { isRegionValid_ = isValid; } /** * Add a sub object to this graphics object. * Use as: * * <ul> * <li>add (object, inFronOf (otherObject)); * <li>add (object, behind (otherObject)); * <li>add (object, front()); * <li>add (object, back()); * <li>add (object, 4); * <li>add (object); // Same as add (object, front()); * </ul> * * Add is performed on a parent node, adding child to self. * * @param child Object to add * @param position Position to add to */ public void add (GObject child, int position) { // Remove object from current location as it can only have one parent if (child.parent_ != null) child.parent_.remove (child); // Brain damage if (position > children_.size()) position = children_.size(); if (position < 0) position = 0; // Add to this object children_.add (position, child); child.parent_ = this; // child.window_ = window_; // child.view_ = view_; // Since we inherit from parent, style may have changed child.updateStyle(); // Adding stuff means we need to recompute stuff GScene scene = getScene(); if (scene != null) scene.setAnnotationValid (false); // Possibly isRegionValid_ = false; } /** * Add child object to this object. Add to front (on screen). * * @param child Child to add. */ public void add (GObject child) { add (child, front()); } /** * Move this object to the front of its siblings in its parent * object. If doesn't have a parent, this method has no effect. * This is a convenience shorthand of * getParent().reposition (this, getParent().front()); */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -