From 9f420b45b98296234ea347709ffdac4ccfaf2636 Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Mon, 23 Dec 2024 23:05:12 +0100 Subject: [PATCH] Improve refactoring preview divider handling and tree navigation. - scroll only vertically on prev/next navigation - reset divider only if left panel is below minimal size - share divider location memory between refactoring views --- .../nbproject/project.properties | 2 +- .../spi/impl/CheckNodeListener.java | 15 +++++- .../spi/impl/RefactoringPanel.java | 53 ++++++++----------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/ide/refactoring.api/nbproject/project.properties b/ide/refactoring.api/nbproject/project.properties index 750ae2451d32..f7fc27aec475 100644 --- a/ide/refactoring.api/nbproject/project.properties +++ b/ide/refactoring.api/nbproject/project.properties @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. is.autoload=true -javac.source=1.8 +javac.release=17 javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml javadoc.title=Refactoring API diff --git a/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/CheckNodeListener.java b/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/CheckNodeListener.java index 3318fd4af225..907a8e827bdf 100644 --- a/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/CheckNodeListener.java +++ b/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/CheckNodeListener.java @@ -355,8 +355,21 @@ static void selectNextPrev(final boolean next, boolean isQuery, JTree tree) { } } while (!node.isLeaf()); tree.setSelectionRow(newRow); - tree.scrollRowToVisible(newRow); + verticalScrollRowToVisible(tree, newRow); CheckNodeListener.openDiff(node); } + /** + * Analog to {@link javax.swing.JTree#scrollRowToVisible(int)} but scrolls only vertically. + */ + private static void verticalScrollRowToVisible(JTree tree, int row) { + TreePath path = tree.getPathForRow(row); + if (path != null) { + tree.makeVisible(path); + Rectangle bounds = tree.getPathBounds(path); + bounds.setLocation(0, (int) bounds.getY()); + tree.scrollRectToVisible(bounds); + } + } + } // end CheckNodeListener diff --git a/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/RefactoringPanel.java b/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/RefactoringPanel.java index 2ff6566c40ac..9494ea171aa2 100644 --- a/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/RefactoringPanel.java +++ b/ide/refactoring.api/src/org/netbeans/modules/refactoring/spi/impl/RefactoringPanel.java @@ -107,6 +107,9 @@ public class RefactoringPanel extends JPanel implements FiltersManagerImpl.Filte private Action callback = null; private static final int MAX_ROWS = 50; + private static final int MIN_DIVIDER_LOCATION = 250; + /* last user modified divider position shared between all instances */ + private static int dividerPosMemory = -1; private transient JToggleButton logicalViewButton = null; private transient JToggleButton physicalViewButton = null; @@ -125,7 +128,6 @@ public class RefactoringPanel extends JPanel implements FiltersManagerImpl.Filte private FiltersManagerImpl filtersManager; private JComponent filterBar; private JPanel toolbars; - static Image PACKAGE_BADGE = ImageUtilities.loadImage( "org/netbeans/spi/java/project/support/ui/packageBadge.gif" ); // NOI18N @@ -179,6 +181,11 @@ private void initialize() { add(splitPane, BorderLayout.CENTER); splitPane.setRightComponent(new JLabel(org.openide.util.NbBundle.getMessage(RefactoringPanel.class, "LBL_Preview_not_Available"), SwingConstants.CENTER)); splitPane.setBorder(null); + splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, evt -> { + if (evt.getNewValue() instanceof Integer pos && pos > MIN_DIVIDER_LOCATION) { + RefactoringPanel.dividerPosMemory = pos; + } + }); // add panel with buttons JButton[] buttons = getButtons(); // there will be at least one button on panel @@ -706,7 +713,6 @@ private void refresh(final boolean showParametersPanel) { if (currentView == GRAPHICAL) { assert ui instanceof RefactoringCustomUI; assert customComponent != null; - RefactoringCustomUI cui = (RefactoringCustomUI) ui; this.left.remove(scrollPane); this.left.add(customComponent, BorderLayout.CENTER); UI.setComponentForRefactoringPreview(null); @@ -738,7 +744,7 @@ public void run() { final Map nodes = new HashMap(); if (isQuery && showParametersPanel) { - setupInstantTree(root, showParametersPanel); + setupInstantTree(root); } if (!isQuery) { @@ -897,8 +903,7 @@ private void setupTree(final CheckNode root, final boolean showParametersPanel, @Override public void run() { createTree(root); - - splitPane.setDividerLocation(0.3); + initDivider(); expandTreeIfNeeded(showParametersPanel, size); tree.setSelectionRow(0); @@ -910,6 +915,16 @@ public void run() { }); } + private void initDivider() { + if (splitPane.getDividerLocation() < MIN_DIVIDER_LOCATION) { + if (dividerPosMemory > MIN_DIVIDER_LOCATION) { + splitPane.setDividerLocation(dividerPosMemory); + } else { + splitPane.setDividerLocation(0.3); + } + } + } + private void expandTreeIfNeeded(boolean showParametersPanel, int size) { if (showParametersPanel) { if (size < MAX_ROWS) { @@ -1005,14 +1020,14 @@ private void createTree(TreeNode root) throws MissingResourceException { }); } - private void setupInstantTree(final CheckNode root, final boolean showParametersPanel) { + private void setupInstantTree(final CheckNode root) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { createTree(root); tree.setSelectionRow(0); - splitPane.setDividerLocation(0.3); + initDivider(); if (refactorButton != null) { refactorButton.requestFocusInWindow(); } else if (tree != null) { @@ -1213,30 +1228,6 @@ private void stopSearch() { cancelRequest.set(true); ui.getRefactoring().cancelRequest(); } - - private static String normalize(String input) { - int size = input.length(); - char[] c = new char[size]; - input.getChars(0, size, c, 0); - boolean wb = false; - int pos = 0; - char[] nc = new char[size]; - - for (int i = 0; i < size; i++) { - if (Character.isWhitespace(c[i])) { - if (!wb) { - nc[pos++] = ' '; - - wb = true; - } - } - else { - nc[pos++] = c[i]; - wb = false; - } - } - return new String(nc, 0, pos); - } /** Processes returned problems from refactoring operations and notifies * user (in case of non-fatal problems gives user a chance to continue or cancel).