From e37bd8b9c4b339255eba3b1e3be85944f9251927 Mon Sep 17 00:00:00 2001 From: malenkov Date: Thu, 24 Jan 2013 18:06:24 +0400 Subject: [PATCH] 8003400: JTree scrolling problem when using large model in WindowsLookAndFeel Reviewed-by: alexsch --- .../javax/swing/plaf/basic/BasicTreeUI.java | 25 +++- .../swing/JTree/8003400/Test8003400.java | 109 ++++++++++++++++++ 2 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 test/javax/swing/JTree/8003400/Test8003400.java diff --git a/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java index 497c0d6ca..3d39cf6a8 100644 --- a/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java +++ b/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java @@ -1879,6 +1879,20 @@ public class BasicTreeUI extends TreeUI visRect.x -= i.left; visRect.y -= i.top; } + // we should consider a non-visible area above + Component component = SwingUtilities.getUnwrappedParent(tree); + if (component instanceof JViewport) { + component = component.getParent(); + if (component instanceof JScrollPane) { + JScrollPane pane = (JScrollPane) component; + JScrollBar bar = pane.getHorizontalScrollBar(); + if ((bar != null) && bar.isVisible()) { + int height = bar.getHeight(); + visRect.y -= height; + visRect.height += height; + } + } + } preferredSize.width = treeState.getPreferredWidth(visRect); } else { @@ -4504,7 +4518,7 @@ public class BasicTreeUI extends TreeUI } } - private void home(JTree tree, BasicTreeUI ui, int direction, + private void home(JTree tree, final BasicTreeUI ui, int direction, boolean addToSelection, boolean changeSelection) { // disable moving of lead unless in discontiguous mode @@ -4514,7 +4528,7 @@ public class BasicTreeUI extends TreeUI changeSelection = true; } - int rowCount = ui.getRowCount(tree); + final int rowCount = ui.getRowCount(tree); if (rowCount > 0) { if(direction == -1) { @@ -4566,6 +4580,13 @@ public class BasicTreeUI extends TreeUI ui.setLeadSelectionPath(ui.getPathForRow(tree, rowCount - 1), true); } + if (ui.isLargeModel()){ + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ui.ensureRowsAreVisible(rowCount - 1, rowCount - 1); + } + }); + } } } } diff --git a/test/javax/swing/JTree/8003400/Test8003400.java b/test/javax/swing/JTree/8003400/Test8003400.java new file mode 100644 index 000000000..f2102f8b1 --- /dev/null +++ b/test/javax/swing/JTree/8003400/Test8003400.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8003400 + * @summary Tests that JTree shows the last row + * @author Sergey Malenkov + * @run main/othervm Test8003400 + * @run main/othervm Test8003400 reverse + * @run main/othervm Test8003400 system + * @run main/othervm Test8003400 system reverse + */ + +import sun.awt.SunToolkit; + +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.tree.DefaultMutableTreeNode; + +public class Test8003400 { + + private static final String TITLE = "Test JTree with a large model"; + private static List OBJECTS = Arrays.asList(TITLE, "x", "y", "z"); + private static JScrollPane pane; + + public static void main(String[] args) throws Exception { + for (String arg : args) { + if (arg.equals("reverse")) { + Collections.reverse(OBJECTS); + } + if (arg.equals("system")) { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + } + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + + JTree tree = new JTree(root); + tree.setLargeModel(true); + tree.setRowHeight(16); + + JFrame frame = new JFrame(TITLE); + frame.add(pane = new JScrollPane(tree)); + frame.setSize(200, 100); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setVisible(true); + + for (String object : OBJECTS) { + root.add(new DefaultMutableTreeNode(object)); + } + tree.expandRow(0); + } + }); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(500); + new Robot().keyPress(KeyEvent.VK_END); + toolkit.realSync(500); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JTree tree = (JTree) pane.getViewport().getView(); + Rectangle inner = tree.getRowBounds(tree.getRowCount() - 1); + Rectangle outer = SwingUtilities.convertRectangle(tree, inner, pane); + outer.y += tree.getRowHeight() - 1 - pane.getVerticalScrollBar().getHeight(); + // error reporting only for automatic testing + if (null != System.getProperty("test.src", null)) { + SwingUtilities.getWindowAncestor(pane).dispose(); + if (outer.y != 0) { + throw new Error("TEST FAILED: " + outer.y); + } + } + } + }); + } +} -- GitLab