@Override
public void setSelectionPath(TreePath path) {
super.setSelectionPath(path);
scrollPathToVisible(path);
}
Некоторые узлы имеют длинные имена. Когда такой узел выбран, его JScrollPane выполняет как вертикальную, так и горизонтальную прокрутку.


Мне было поручено отключить горизонтальную прокрутку.
В моей попытке решения (см. фрагмент ниже) я обманом заставил Swing поверить, что он должен показывать другой прямоугольник, чем тот, который на самом деле соответствует выбранному узлу. Однако самая сложная часть — получить «текущие» X и ширину. Если вы жестко закодируете их как нули, как я, горизонтальная полоса прокрутки будет сбрасываться в начало каждый раз, когда происходит выбор, даже если полоса находится посередине.
Думаю, могут быть и другие пути.
Как я могу достичь своей цели?
Java 8.
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
public class SimpleTreeDemo {
public static void main(String[] args) {
Container mainPanel = createMainPanel();
JFrame frame = new JFrame("Tree Demo");
frame.setContentPane(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static Container createMainPanel() {
JScrollPane panel = new JScrollPane();
panel.setViewportView(createTree());
Dimension smallDimension = new Dimension(200, 100);
panel.setPreferredSize(smallDimension);
return panel;
}
private static Component createTree() {
JTree tree = new TreeEx(createRoot());
tree.setShowsRootHandles(true);
return tree;
}
private static TreeNode createRoot() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
root.add(new DefaultMutableTreeNode("Short child"));
root.add(new DefaultMutableTreeNode("Loooooooooooooooooooooooooooooooooooong child"));
return root;
}
private static class TreeEx extends JTree {
public TreeEx(TreeNode root) {
super(root);
}
@Override
public void setSelectionPath(TreePath path) {
super.setSelectionPath(path);
scrollPathToVisible(path);
}
@Override
public void scrollPathToVisible(TreePath path) {
// mostly a copy-pasted super-method
if (path == null) return;
makeVisible(path);
Rectangle bounds = buildVerticalBounds(path);
if (bounds == null) return;
scrollRectToVisible(bounds);
if (accessibleContext == null) return;
((AccessibleJTree) accessibleContext).fireVisibleDataPropertyChange();
}
private Rectangle buildVerticalBounds(TreePath path) {
Rectangle requestedPath = getPathBounds(path);
if (requestedPath == null) return null;
requestedPath.setLocation(getCurrentX(), (int) requestedPath.getLocation().getY());
requestedPath.setSize(getCurrentWidth(), (int) requestedPath.getSize().getHeight());
return requestedPath;
}
// in theory, by correctly implementing the following two methods, one can achieve the desired functionality
private int getCurrentX() {
return 0;
}
private int getCurrentWidth() {
return 0;
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... cally-only
Мобильная версия