diff --git a/editor.lib/apichanges.xml b/editor.lib/apichanges.xml --- a/editor.lib/apichanges.xml +++ b/editor.lib/apichanges.xml @@ -107,6 +107,21 @@ + + Support for sticky windows in the editor + + + + + +

+ Support for Sticky Windows in the editor. JComponents can be + added to a layer on top of the editor. Components will + update their vertical position on editor changes. +

+
+ +
Document handling split diff --git a/editor.lib/nbproject/project.properties b/editor.lib/nbproject/project.properties --- a/editor.lib/nbproject/project.properties +++ b/editor.lib/nbproject/project.properties @@ -42,7 +42,7 @@ javac.compilerargs=-Xlint:unchecked javac.source=1.7 -spec.version.base=4.5.0 +spec.version.base=4.6.0 is.autoload=true javadoc.arch=${basedir}/arch.xml diff --git a/editor.lib/nbproject/project.xml b/editor.lib/nbproject/project.xml --- a/editor.lib/nbproject/project.xml +++ b/editor.lib/nbproject/project.xml @@ -50,6 +50,15 @@ org.netbeans.modules.editor.lib + org.netbeans.api.annotations.common + + + + 1 + 1.27 + + + org.netbeans.api.progress @@ -179,14 +188,6 @@ - org.openide.util.ui - - - - 9.3 - - - org.openide.util @@ -202,6 +203,14 @@ 8.0 + + org.openide.util.ui + + + + 9.3 + + diff --git a/editor.lib/src/org/netbeans/editor/EditorUI.java b/editor.lib/src/org/netbeans/editor/EditorUI.java --- a/editor.lib/src/org/netbeans/editor/EditorUI.java +++ b/editor.lib/src/org/netbeans/editor/EditorUI.java @@ -89,6 +89,7 @@ import org.netbeans.api.editor.settings.FontColorSettings; import org.netbeans.api.editor.settings.SimpleValueNames; import org.netbeans.editor.ext.ExtKit; +import org.netbeans.editor.ext.StickyWindowSupport; import org.netbeans.editor.ext.ToolTipSupport; import org.netbeans.modules.editor.lib.ColoringMap; import org.netbeans.modules.editor.lib.EditorExtPackageAccessor; @@ -273,6 +274,7 @@ private PreferenceChangeListener weakPrefsListener = null; private final DrawLayerList drawLayerList = new DrawLayerList(); + private StickyWindowSupport stickyWindowSupport; /** Construct extended UI for the use with a text component */ public EditorUI() { @@ -1771,6 +1773,13 @@ } return toolTipSupport; } + + public StickyWindowSupport getStickyWindowSupport() { + if(stickyWindowSupport == null) { + stickyWindowSupport = new StickyWindowSupport(this); + } + return stickyWindowSupport; + } public PopupManager getPopupManager() { if (popupManager == null) { diff --git a/editor.lib/src/org/netbeans/editor/ext/StickyWindowSupport.java b/editor.lib/src/org/netbeans/editor/ext/StickyWindowSupport.java new file mode 100644 --- /dev/null +++ b/editor.lib/src/org/netbeans/editor/ext/StickyWindowSupport.java @@ -0,0 +1,145 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2016 Sun Microsystems, Inc. + */ +package org.netbeans.editor.ext; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Point; +import java.awt.Rectangle; +import javax.swing.JComponent; +import javax.swing.JLayeredPane; +import javax.swing.SwingUtilities; +import javax.swing.text.JTextComponent; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.editor.EditorUI; +import org.netbeans.modules.editor.lib2.view.ViewHierarchy; +import org.netbeans.modules.editor.lib2.view.ViewHierarchyEvent; +import org.netbeans.modules.editor.lib2.view.ViewHierarchyListener; + +/** + * Support for Sticky Windows in the editor. JComponents can be added to a layer + * on top of the editor. Components will update their vertical position on editor + * changes. + * @author Ralph Benjamin Ruijs + * @since 4.6 + */ +public class StickyWindowSupport { + + private final EditorUI eui; + + StickyWindowSupport(final EditorUI eui) { + this.eui = eui; + ViewHierarchy.get(eui.getComponent()).addViewHierarchyListener(new ViewHierarchyListener() { + @Override + public void viewHierarchyChanged(ViewHierarchyEvent evt) { + JTextComponent editor = eui.getComponent(); + Container container = editor.getParent(); + if(container instanceof JLayeredPane && evt.isChangeY()) { + JLayeredPane pane = (JLayeredPane) container; + double deltaY = evt.deltaY(); + Component[] components = pane.getComponentsInLayer(JLayeredPane.PALETTE_LAYER); + Rectangle rv = null; + for (Component component : components) { + rv = component.getBounds(rv); + if(rv.getY() > evt.startY() || + rv.contains(new Point(rv.x, (int) evt.startY())) || + rv.contains(new Point(rv.x, (int) evt.endY()))) { + Point p = rv.getLocation(); + p.translate(0, (int) deltaY); + component.setLocation(p); + } + } + } + } + }); + } + + /** + * Add a sticky window to the editor. + * @param window the JComponent to add to the editor + */ + public void addWindow(JComponent window) { + JTextComponent component = eui.getComponent(); + Container container = component.getParent(); + if(container instanceof JLayeredPane) { + JLayeredPane pane = (JLayeredPane) container; + pane.add(window, JLayeredPane.PALETTE_LAYER); + window.setVisible(true); + } + } + + /** + * Convert a aPoint in root component coordinate system to the + * editor coordinate system. aPoint is assumed to be in the + * root component coordinate system of the editor. If conversion is not + * possible, return aPoint without any conversion. + * + * @param aPoint the Point to convert + * @return aPoint converted to editor coordinate system + */ + public @NonNull Point convertPoint(Point aPoint) { + Point value = aPoint; + JTextComponent component = eui.getComponent(); + Container container = component.getParent(); + if(container instanceof JLayeredPane) { + JLayeredPane pane = (JLayeredPane) container; + value = SwingUtilities.convertPoint(pane.getRootPane(), value, pane); + } + return value; + } + + /** + * Remove a sticky window from the editor. + * @param window the JComponent to remove + */ + public void removeWindow(JComponent window) { + JTextComponent component = eui.getComponent(); + Container container = component.getParent(); + if(container instanceof JLayeredPane) { + JLayeredPane pane = (JLayeredPane) container; + pane.remove(window); + pane.repaint(window.getBounds()); + } + } + + +}