📄 mxgraphcomponent.java
字号:
* * @param event * @return Returns true if the given event is constrained. */ public boolean isConstrainedEvent(MouseEvent event) { return (event != null) ? event.isShiftDown() : false; } /** * Note: This is not used during drag and drop operations due to * limitations of the underlying API. To enable this for move * operations set dragEnabled to false. * * @param event * @return Returns true if the given event is constrained. */ public boolean isForceMarqueeEvent(MouseEvent event) { return (event != null) ? event.isAltDown() : false; } /** * */ public mxPoint snapScaledPoint(mxPoint pt) { return snapScaledPoint(pt, 0, 0); } /** * */ public mxPoint snapScaledPoint(mxPoint pt, double dx, double dy) { if (pt != null) { double scale = graph.getView().getScale(); mxPoint trans = graph.getView().getTranslate(); pt .setX((graph.snap(pt.getX() / scale - trans.getX() + dx / scale) + trans.getX()) * scale - dx); pt .setY((graph.snap(pt.getY() / scale - trans.getY() + dy / scale) + trans.getY()) * scale - dy); } return pt; } /** * Prints the specified page on the specified graphics using * <code>pageForm</code> for the page format. * * @param g * The graphics to paint the graph on. * @param printFormat * The page format to use for printing. * @param page * The page to print * @return Returns {@link Printable#PAGE_EXISTS} or * {@link Printable#NO_SUCH_PAGE}. */ public int print(Graphics g, PageFormat printFormat, int page) { int result = NO_SUCH_PAGE; // Gets the current state of the view mxGraphView view = graph.getView(); // Stores the old state of the view boolean eventsEnabled = view.isEventsEnabled(); mxPoint translate = view.getTranslate(); // Disables firing of scale events so that there is no // repaint or update of the original graph while pages // are being printed view.setEventsEnabled(false); // Uses the view to create temporary cell states for each cell mxTemporaryCellStates tempStates = new mxTemporaryCellStates(view, 1 / pageScale); try { view.setTranslate(new mxPoint(0, 0)); mxGraphics2DCanvas canvas = createCanvas(); canvas.setGraphics((Graphics2D) g); view.revalidate(); Dimension pSize = graph.getGraphBounds().getRectangle().getSize(); int w = (int) (printFormat.getWidth() * pageScale); int h = (int) (printFormat.getHeight() * pageScale); int cols = (int) Math.max(Math.ceil((double) (pSize.width - 5) / (double) w), 1); int rows = (int) Math.max(Math.ceil((double) (pSize.height - 5) / (double) h), 1); if (page < cols * rows) { int dx = (int) ((page % cols) * printFormat.getWidth()); int dy = (int) ((page % rows) * printFormat.getHeight()); g.translate(-dx, -dy); g.setClip(dx, dy, (int) (dx + printFormat.getWidth()), (int) (dy + printFormat.getHeight())); graph.draw(canvas); result = PAGE_EXISTS; } } finally { view.setTranslate(translate); tempStates.destroy(); view.setEventsEnabled(eventsEnabled); } return result; } /** * */ public mxInteractiveCanvas getCanvas() { return canvas; } /** * */ public BufferedImage getTripleBuffer() { return tripleBuffer; } /** * Hook for subclassers to replace the graphics canvas for rendering and * and printing. This must be overridden to return a custom canvas if there * are any custom shapes. */ public mxInteractiveCanvas createCanvas() { return new mxInteractiveCanvas(); } /** * * @param state Cell state for which a handler should be created. * @return Returns the handler to be used for the given cell state. */ public mxCellHandler createHandler(mxCellState state) { if (graph.getModel().isVertex(state.getCell())) { return new mxVertexHandler(this, state); } else if (graph.getModel().isEdge(state.getCell())) { mxEdgeStyleFunction style = graph.getView().getEdgeStyle(state, null, null); if (graph.isLoop(state) || style == mxEdgeStyle.ElbowConnector || style == mxEdgeStyle.SideToSide || style == mxEdgeStyle.TopToBottom) { return new mxElbowEdgeHandler(this, state); } return new mxEdgeHandler(this, state); } return new mxCellHandler(this, state); } // // Heavyweights // /** * Hook for subclassers to create the array of heavyweights for the given * state. */ public Component[] createComponents(mxCellState state) { return null; } /** * */ public void insertComponent(mxCellState state, Component c) { getGraphControl().add(c, 0); } /** * */ public void removeComponent(Component c, Object cell) { if (c.getParent() != null) { c.getParent().remove(c); } } /** * */ public void updateComponent(mxCellState state, Component c) { int x = (int) state.getX(); int y = (int) state.getY(); int width = (int) state.getWidth(); int height = (int) state.getHeight(); Dimension s = c.getMinimumSize(); if (s.width > width) { x -= (s.width - width) / 2; width = s.width; } if (s.height > height) { y -= (s.height - height) / 2; height = s.height; } c.setBounds(x, y, width, height); } /** * */ public void updateComponents() { Object root = graph.getModel().getRoot(); Hashtable result = updateComponents(root); // Components now contains the mappings which are no // longer used, the result contains the new mappings removeAllComponents(components); components = result; if (!overlays.isEmpty()) { result = updateCellOverlays(root); // Overlays now contains the mappings from cells which // are no longer in the model, the result contains the // mappings from cells which still exists, regardless // from whether a state exists for a particular cell removeAllOverlays(overlays); overlays = result; } } /** * */ public void removeAllComponents(Hashtable map) { Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Component[] c = (Component[]) entry.getValue(); for (int i = 0; i < c.length; i++) { removeComponent(c[i], entry.getKey()); } } } /** * */ public void removeAllOverlays(Hashtable map) { Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); mxICellOverlay[] c = (mxICellOverlay[]) entry.getValue(); for (int i = 0; i < c.length; i++) { removeCellOverlayComponent(c[i], entry.getKey()); } } } /** * */ public Hashtable updateComponents(Object cell) { Hashtable result = new Hashtable(); Component[] c = (Component[]) components.remove(cell); mxCellState state = getGraph().getView().getState(cell); if (state != null) { if (c == null) { c = createComponents(state); if (c != null) { for (int i = 0; i < c.length; i++) { insertComponent(state, c[i]); } } } if (c != null) { result.put(cell, c); for (int i = 0; i < c.length; i++) { updateComponent(state, c[i]); } } } int childCount = getGraph().getModel().getChildCount(cell); for (int i = 0; i < childCount; i++) { result.putAll(updateComponents(getGraph().getModel().getChildAt( cell, i))); } return result; } // // Validation and overlays // /** * Validates the graph by validating each descendant of the given cell or * the root of the model. Context is an object that contains the validation * state for the complete validation run. The validation errors are * attached to their cells using <setWarning>. This function returns true * if no validation errors exist in the graph. */ public String validateGraph() { return validateGraph(graph.getModel().getRoot(), new Hashtable()); } /** * Validates the graph by validating each descendant of the given cell or * the root of the model. Context is an object that contains the validation * state for the complete validation run. The validation errors are * attached to their cells using <setWarning>. This function returns true * if no validation errors exist in the graph. * * @param cell Cell to start the validation recursion. * @param context Object that represents the global validation state. */ public String validateGraph(Object cell, Hashtable context) { mxIGraphModel model = graph.getModel(); mxGraphView view = graph.getView(); boolean isValid = true; int childCount = model.getChildCount(cell); for (int i = 0; i < childCount; i++) { Object tmp = model.getChildAt(cell, i); Hashtable ctx = context; if (graph.isValidRoot(tmp)) { ctx = new Hashtable(); } String warn = validateGraph(tmp, ctx); if (warn != null) { String html = warn.replaceAll("\n", "<br>"); int len = html.length(); setCellWarning(tmp, html.substring(0, Math.max(0, len - 4))); } else { setCellWarning(tmp, null); } isValid = isValid && warn == null; } StringBuffer warning = new StringBuffer(); // Adds error for invalid children if collapsed (children invisible) if (graph.isCellCollapsed(cell) && !isValid) { warning.append(mxResources.get("containsValidationErrors", "Contains Validation Errors") + "\n"); } // Checks edges and cells using the defined multiplicities if (model.isEdge(cell)) { String tmp = graph.getEdgeValidationError(cell, model.getTerminal( cell, true), model.getTerminal(cell, false)); if (tmp != null) { warning.append(tmp); } } else { String tmp = graph.getCellValidationError(cell); if (tmp != null) { warning.append(tmp); } } // Checks custom validation rules String err = graph.validateCell(cell, context); if (err != null) { warning.append(err); } // Updates the display with the warning icons before any potential // alerts are displayed if (model.getParent(cell) == null) { view.validate(); } return (warning.length() > 0 || !isValid) ? warning.toString() : null; } /** * Adds an overlay for the specified cell. This method fires an * addoverlay event and returns the new overlay. * * @param cell Cell to add the overlay for. * @param overlay Overlay to be added for the cell. */ public mxICellOverlay addCellOverlay(Object cell, mxICellOverlay overlay) { mxICellOverlay[] arr = getCellOverlays(cell); if (arr == null) { arr = new mxICellOverlay[] { overlay }; } else { mxICellOverlay[] arr2 = new mxICellOverlay[arr.length + 1]; System.arraycopy(arr, 0, arr2, 0, arr.length); arr2[arr.length] = overlay; arr = arr2; } overlays.put(cell, arr); mxCellState state = graph.getView().getState(cell); if (state != null) { updateCellOverlayComponent(state, overlay); } eventSource.fireEvent(mxEvent.ADD_OVERLAY, new mxEventObject( new Object[] { cell, overlay })); return overlay; } /** * Returns the array of overlays for the given cell or null, if * no overlays are defined. * * @param cell Cell whose overlays should be returned. */ public mxICellOverlay[] getCellOverlays(Object cell) { return (mxICellOverlay[]) overlays.get(cell); } /** * Removes and returns the given overlay from the given cell. This * method fires a removeoverlay event. If no overlay is given, then all * overlays are removed using removeOverlays. * * @param cell Cell whose overlay should be removed. * @param overlay Optional overlay to be removed. */ public mxICellOverlay removeCellOverlay(Object cell, mxICellOverlay overlay) { if (overlay == null) { removeCellOverlays(cell); } else { mxICellOverlay[] arr = getCellOverlays(cell); if (arr != null) { List list = Arrays.asList(arr); if (list.remove(overlay)) { removeCellOverlayComponent(overlay, cell); } arr = (mxICellOverlay[]) list.toArray(); overlays.put(cell, arr); } } return overlay; } /** * Removes all overlays from the given cell. This method * fires a removeoverlay event for each removed overlay and returns * the array of overlays that was removed from the cell. * * @param cell Cell whose overlays should be removed. */ public mxICellOverlay[] removeCellOverlays(Object cell) { mxICellOverlay[] ovls = (mxICellOverlay[]) overlays.remove(cell); if (ovls != null) { // Removes the overlays from the cell hierarchy for (int i = 0; i < ovls.length; i++) { removeCellOverlayComponent(ovls[i], cell); } } return ovls; } /** * Notified when an overlay has been removed from the graph. This * implementation removes the given overlay from its parent if it is a * component inside a component hierarchy. */ protected void removeCellOverlayComponent(mxICellOverlay overlay, Object cell) { if (overlay instanceof Component) { Component comp = (Component) overlay; if (comp.getParent() != null) { comp.setVisible(false); comp.getParent().remove(comp); eventSource.fireEvent(mxEvent.REMOVE_OVERLAY, new mxEventObject(new Object[] { cell, overlay })); } } } /** * Notified when an overlay has been removed from the graph. This * implementation removes the given overlay from its parent if it is a * component inside a component hierarchy. */ protected void updateCellOverlayComponent(mxCellState state, mxICellOverlay overlay) { if (overlay instanceof Component) { Component comp = (Component) overlay;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -