📄 mxgraphcomponent.java
字号:
} /** * */ public void startEditing() { startEditingAtCell(null); } /** * */ public void startEditingAtCell(Object cell) { startEditingAtCell(cell, null); } /** * */ public void startEditingAtCell(Object cell, EventObject trigger) { if (cell == null) { cell = graph.getSelectionCell(); if (cell != null && !graph.isCellEditable(cell)) { cell = null; } } if (cell != null) { eventSource.fireEvent(mxEvent.START_EDITING, new mxEventObject( new Object[] { cell, trigger })); cellEditor.startEditing(cell, trigger); } } /** * */ public String getEditingValue(Object cell, EventObject trigger) { return graph.convertValueToString(cell); } /** * */ public void stopEditing(boolean cancel) { cellEditor.stopEditing(cancel); } /** * Sets the label of the specified cell to the given value using * mxGraph.cellLabelChanged and fires mxEvent.LABEL_CHANGED while the * transaction is in progress. Returns the cell whose label was changed. * * @param cell Cell whose label should be changed. * @param newValue New value of the label. * @param trigger Optional event that triggered the change. */ public Object labelChanged(Object cell, Object newValue, EventObject trigger) { mxIGraphModel model = graph.getModel(); model.beginUpdate(); try { graph.cellLabelChanged(cell, newValue, graph.isAutoSizeCell(cell)); eventSource.fireEvent(mxEvent.LABEL_CHANGED, new mxEventObject( new Object[] { cell, newValue, trigger })); } finally { model.endUpdate(); } return cell; } /** * Returns the (unscaled) preferred size for the current page format * (scaled by pageScale). */ protected Dimension getPreferredSizeForPage() { return new Dimension((int) Math.round(pageFormat.getWidth() * pageScale * horizontalPageCount), (int) Math.round(pageFormat.getHeight() * pageScale * verticalPageCount)); } /** * Returns the vertical border between the page and the control. */ public int getVerticalPageBorder() { return (int) Math.round(pageFormat.getWidth() * pageScale); } /** * Returns the horizontal border between the page and the control. */ public int getHorizontalPageBorder() { return (int) Math.round(0.5 * pageFormat.getHeight() * pageScale); } /** * Returns the scaled preferred size for the current graph. */ protected Dimension getScaledPreferredSizeForGraph() { mxRectangle bounds = graph.getGraphBounds(); int border = graph.getBorder(); return new Dimension((int) Math.round(bounds.getWidth()) + border + 1, (int) Math.round(bounds.getHeight()) + border + 1); } /** * Should be called by a hook inside mxGraphView/mxGraph */ protected mxPoint getPageTranslate(double scale) { Dimension d = getPreferredSizeForPage(); Dimension bd = new Dimension(d); if (!preferPageSize) { bd.width += 2 * getHorizontalPageBorder(); bd.height += 2 * getVerticalPageBorder(); } double width = Math.max(bd.width, (getViewport().getWidth() - 8) / scale); double height = Math.max(bd.height, (getViewport().getHeight() - 8) / scale); double dx = Math.max(0, (width - d.width) / 2); double dy = Math.max(0, (height - d.height) / 2); return new mxPoint(dx, dy); } /** * Invoked after the component was resized to update the zoom if the * zoom policy is not none and/or update the translation of the diagram * if pageVisible and centerPage are true. */ public void zoomAndCenter() { if (zoomPolicy != ZOOM_POLICY_NONE) { // Centers only on the initial zoom call zoom(zoomPolicy == ZOOM_POLICY_PAGE, centerOnResize || zoomPolicy == ZOOM_POLICY_PAGE); centerOnResize = false; } else if (pageVisible && centerPage) { mxPoint translate = getPageTranslate(graph.getView().getScale()); graph.getView().setTranslate(translate); } else { getGraphControl().updatePreferredSize(); } } /** * Zooms into the graph by zoomFactor. */ public void zoomIn() { mxGraphView view = graph.getView(); double newScale = (double) ((int) (view.getScale() * 100 * zoomFactor)) / 100; if (newScale != view.getScale() && newScale > 0) { mxPoint translate = (pageVisible && centerPage) ? getPageTranslate(newScale) : new mxPoint(); graph.getView().scaleAndTranslate(newScale, translate.getX(), translate.getY()); if (keepSelectionVisibleOnZoom && !graph.isSelectionEmpty()) { getGraphControl().scrollRectToVisible( view.getBoundingBox(graph.getSelectionCells()) .getRectangle()); } else { maintainScrollBar(true, zoomFactor, centerZoom); maintainScrollBar(false, zoomFactor, centerZoom); } } } /** * Function: zoomOut * * Zooms out of the graph by <zoomFactor>. */ public void zoomOut() { mxGraphView view = graph.getView(); double newScale = (double) ((int) (view.getScale() * 100 / zoomFactor)) / 100; if (newScale >= 0.01) { mxPoint translate = (pageVisible && centerPage) ? getPageTranslate(newScale) : new mxPoint(); graph.getView().scaleAndTranslate(newScale, translate.getX(), translate.getY()); if (keepSelectionVisibleOnZoom && !graph.isSelectionEmpty()) { getGraphControl().scrollRectToVisible( view.getBoundingBox(graph.getSelectionCells()) .getRectangle()); } else { maintainScrollBar(true, 1 / zoomFactor, centerZoom); maintainScrollBar(false, 1 / zoomFactor, centerZoom); } } } /** * */ public void zoomTo(final double newScale, final boolean center) { mxGraphView view = graph.getView(); final double scale = view.getScale(); mxPoint translate = (pageVisible && centerPage) ? getPageTranslate(newScale) : new mxPoint(); graph.getView().scaleAndTranslate(newScale, translate.getX(), translate.getY()); // Causes two repaints on the scrollpane, namely one for the scale // change with the new preferred size and one for the change of // the scrollbar position. The latter cannot be done immediately // because the scrollbar keeps the value <= max - extent, and if // max is changed the value change will trigger a syncScrollPane // WithViewport in BasicScrollPaneUI, which will update the value // for the previous maximum (ie. it must be invoked later). SwingUtilities.invokeLater(new Runnable() { public void run() { maintainScrollBar(true, newScale / scale, center); maintainScrollBar(false, newScale / scale, center); } }); } /** * Function: zoomActual * * Resets the zoom and panning in the view. */ public void zoomActual() { mxPoint translate = (pageVisible && centerPage) ? getPageTranslate(1) : new mxPoint(); graph.getView() .scaleAndTranslate(1, translate.getX(), translate.getY()); if (isPageVisible()) { // Causes two repaints, see zoomTo for more details SwingUtilities.invokeLater(new Runnable() { public void run() { Dimension pageSize = getPreferredSizeForPage(); if (getViewport().getWidth() > pageSize.getWidth()) { scrollToCenter(true); } else { JScrollBar scrollBar = getHorizontalScrollBar(); if (scrollBar != null) { scrollBar .setValue((int) (scrollBar.getMaximum() / 3) - 4); } } if (getViewport().getHeight() > pageSize.getHeight()) { scrollToCenter(false); } else { JScrollBar scrollBar = getVerticalScrollBar(); if (scrollBar != null) { scrollBar .setValue((int) (scrollBar.getMaximum() / 4) - 4); } } } }); } } /** * */ public void zoom(final boolean page, final boolean center) { if (pageVisible && !zooming) { zooming = true; try { // Adds some extra space for the shadow and border double width = getViewport().getWidth() - 8; double height = getViewport().getHeight() - 8; Dimension d = getPreferredSizeForPage(); double pageWidth = d.width; double pageHeight = d.height; double scaleX = width / pageWidth; double scaleY = (page) ? height / pageHeight : scaleX; // Rounds the new scale to 5% steps final double newScale = (double) ((int) (Math.min(scaleX, scaleY) * 20)) / 20; if (newScale > 0) { mxGraphView graphView = graph.getView(); final double scale = graphView.getScale(); mxPoint translate = (centerPage) ? getPageTranslate(newScale) : new mxPoint(); graphView.scaleAndTranslate(newScale, translate.getX(), translate.getY()); // Causes two repaints, see zoomTo for more details final double factor = newScale / scale; SwingUtilities.invokeLater(new Runnable() { public void run() { if (center) { if (page) { scrollToCenter(true); scrollToCenter(false); } else { scrollToCenter(true); maintainScrollBar(false, factor, false); } } else if (factor != 1) { maintainScrollBar(true, factor, false); maintainScrollBar(false, factor, false); } } }); } } finally { zooming = false; } } } /** * */ protected void maintainScrollBar(boolean horizontal, double factor, boolean center) { JScrollBar scrollBar = (horizontal) ? getHorizontalScrollBar() : getVerticalScrollBar(); if (scrollBar != null) { BoundedRangeModel model = scrollBar.getModel(); int newValue = (int) Math.round(model.getValue() * factor) + (int) Math.round((center) ? (model.getExtent() * (factor - 1) / 2) : 0); model.setValue(newValue); } } /** * */ public void scrollToCenter(boolean horizontal) { JScrollBar scrollBar = (horizontal) ? getHorizontalScrollBar() : getVerticalScrollBar(); if (scrollBar != null) { final BoundedRangeModel model = scrollBar.getModel(); final int newValue = (int) ((model.getMaximum()) / 2) - model.getExtent() / 2; model.setValue(newValue); } } /** * Scrolls the graph so that it shows the given cell. * * @param cell */ public void scrollCellToVisible(Object cell) { mxCellState state = graph.getView().getState(cell); if (state != null) { scrollRectToVisible(state.getRectangle()); } } /** * * @param x * @param y * @return Returns the cell at the given location. */ public Object getCellAt(int x, int y) { return getCellAt(x, y, true); } /** * * @param x * @param y * @param hitSwimlaneContent * @return Returns the cell at the given location. */ public Object getCellAt(int x, int y, boolean hitSwimlaneContent) { return getCellAt(x, y, hitSwimlaneContent, null); } /** * Returns the bottom-most cell that intersects the given point (x, y) in * the cell hierarchy starting at the given parent. * * @param x X-coordinate of the location to be checked. * @param y Y-coordinate of the location to be checked. * @param parent <mxCell> that should be used as the root of the recursion. * Default is <defaultParent>. * @return Returns the child at the given location. */ public Object getCellAt(int x, int y, boolean hitSwimlaneContent, Object parent) { if (parent == null) { parent = graph.getDefaultParent(); } if (parent != null) { Point previousTranslate = canvas.getTranslate(); double previousScale = canvas.getScale(); try { canvas.setScale(graph.getView().getScale()); canvas.setTranslate(0, 0); mxIGraphModel model = graph.getModel(); mxGraphView view = graph.getView(); Rectangle hit = new Rectangle(x, y, 1, 1); int childCount = model.getChildCount(parent); for (int i = childCount - 1; i >= 0; i--) { Object cell = model.getChildAt(parent, i); Object result = getCellAt(x, y, hitSwimlaneContent, cell); if (result != null) { return result; } else if (graph.isCellVisible(cell)) { mxCellState state = view.getState(cell); if (state != null && canvas.intersects(this, hit, state) && (!graph.isSwimlane(cell) || hitSwimlaneContent || (transparentSwimlaneContent && !canvas .hitSwimlaneContent(this, state, x, y)))) { return cell; } } } } finally { canvas.setScale(previousScale); canvas.setTranslate(previousTranslate.x, previousTranslate.y); } } return null; } /** * */ public void setSwimlaneSelectionEnabled(boolean swimlaneSelectionEnabled) { boolean oldValue = this.swimlaneSelectionEnabled; this.swimlaneSelectionEnabled = swimlaneSelectionEnabled; firePropertyChange("swimlaneSelectionEnabled", oldValue, swimlaneSelectionEnabled); } /** * */ public boolean isSwimlaneSelectionEnabled() { return swimlaneSelectionEnabled; } /** * */ public Object[] selectRegion(Rectangle rect, MouseEvent e) { Object[] cells = getCells(rect); if (cells.length > 0) { selectCellsForEvent(cells, e); } else if (!graph.isSelectionEmpty() && !e.isConsumed()) { graph.clearSelection(); } return cells; } /** * * @param x * @param y * @param width * @param height * @return Returns the cells inside the given rectangle. */ public Object[] getCells(Rectangle rect) { return getCells(rect, null); } /** * Returns the children of the given parent that are contained in the given * rectangle (x, y, width, height). The result is added to the optional * result array, which is returned from the function. If no result array * is specified then a new array is created and returned. * * @param x X-coordinate of the rectangle. * @param y Y-coordinate of the rectangle. * @param width Width of the rectangle. * @param height Height of the rectangle. * @param parent <mxCell> whose children should be checked. Default is * <defaultParent>. * @return Returns the children inside the given rectangle. */ public Object[] getCells(Rectangle rect, Object parent) { Collection result = new ArrayList();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -