1 /* 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles; 33 34 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController; 35 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.TableViewDesignInfoX; 36 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.AbstractGesture; 37 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.mouse.ResizeTableColumnGesture; 38 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; 39 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; 40 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask; 41 import java.util.List; 42 import javafx.geometry.Bounds; 43 import javafx.geometry.Point2D; 44 import javafx.scene.Cursor; 45 import javafx.scene.Group; 46 import javafx.scene.Node; 47 import javafx.scene.control.TableColumn; 48 import javafx.scene.control.TableView; 49 import javafx.scene.paint.Color; 50 import javafx.scene.shape.Line; 51 52 /** 53 * 54 * 55 */ 56 public class TableViewHandles extends AbstractNodeHandles<Node> { 57 58 private final Group grips = new Group(); 59 60 public TableViewHandles(ContentPanelController contentPanelController, 61 FXOMInstance fxomInstance) { 62 super(contentPanelController, fxomInstance, Node.class); 63 assert fxomInstance.getSceneGraphObject() instanceof TableView; 64 65 getRootNode().getChildren().add(grips); // Above handles 66 } 67 68 public TableView<?> getTableView() { 69 return (TableView<?>) getSceneGraphObject(); 70 } 71 72 /* 73 * AbstractNodeHandles 74 */ 75 @Override 76 protected void layoutDecoration() { 77 super.layoutDecoration(); 78 79 // Adjusts the number of grip lines to the number of dividers 80 adjustGripCount(); 81 82 // Updates grip positions 83 for (int i = 0, count = getTableView().getColumns().size(); i < count; i++) { 84 layoutGrip(i); 85 } 86 } 87 88 @Override 89 public AbstractGesture findGesture(Node node) { 90 91 final AbstractGesture result; 92 93 final int gripIndex = grips.getChildren().indexOf(node); 94 if (gripIndex != -1) { 95 final DesignHierarchyMask m = new DesignHierarchyMask(getFxomInstance()); 96 final FXOMObject columnObject = m.getSubComponentAtIndex(gripIndex); 97 assert columnObject instanceof FXOMInstance; 98 result = new ResizeTableColumnGesture(getContentPanelController(), 99 (FXOMInstance)columnObject); 100 } else { 101 result = super.findGesture(node); 102 } 103 104 return result; 105 } 106 107 108 /* 109 * Private 110 */ 111 112 private void adjustGripCount() { 113 final int columnCount = getTableView().getColumns().size(); 114 final List<Node> gripChildren = grips.getChildren(); 115 116 while (gripChildren.size() < columnCount) { 117 gripChildren.add(makeGripLine()); 118 } 119 while (gripChildren.size() > columnCount) { 120 gripChildren.remove(gripChildren.size()-1); 121 } 122 } 123 124 private Line makeGripLine() { 125 final Line result = new Line(); 126 result.setStrokeWidth(SELECTION_HANDLES_SIZE); 127 result.setStroke(Color.TRANSPARENT); 128 result.setCursor(Cursor.H_RESIZE); 129 attachHandles(result); 130 return result; 131 } 132 133 private void layoutGrip(int gripIndex) { 134 assert grips.getChildren().get(gripIndex) instanceof Line; 135 136 final TableColumn<?,?> tc = getTableView().getColumns().get(gripIndex); 137 if (tc.isVisible()) { 138 final TableViewDesignInfoX di = new TableViewDesignInfoX(); 139 final Bounds b = di.getColumnHeaderBounds(tc); 140 final double startX = b.getMaxX(); 141 final double startY = b.getMinY(); 142 final double endY = b.getMaxY(); 143 144 final boolean snapToPixel = true; 145 final Point2D startPoint = sceneGraphObjectToDecoration(startX, startY, snapToPixel); 146 final Point2D endPoint = sceneGraphObjectToDecoration(startX, endY, snapToPixel); 147 148 final Line gripLine = (Line) grips.getChildren().get(gripIndex); 149 gripLine.setVisible(true); 150 gripLine.setManaged(true); 151 gripLine.setStartX(startPoint.getX()); 152 gripLine.setStartY(startPoint.getY()); 153 gripLine.setEndX(endPoint.getX()); 154 gripLine.setEndY(endPoint.getY()); 155 } else { 156 final Line gripLine = (Line) grips.getChildren().get(gripIndex); 157 gripLine.setVisible(false); 158 gripLine.setManaged(false); 159 } 160 } 161 162 163 /* 164 * Wrapper to avoid the 'leaking this in constructor' warning emitted by NB. 165 */ 166 private void attachHandles(Node node) { 167 attachHandles(node, this); 168 } 169 }