Skip to content

Commit

Permalink
Tree: improved support for JTree.getPathForLocation(int x, int y) i…
Browse files Browse the repository at this point in the history
…n wide selection (issue #373)

this is experimental and disabled by default; enable with:
`UIManager.put( "FlatLaf.experimental.tree.widePathForLocation", true );`
  • Loading branch information
DevCharly committed Aug 12, 2021
1 parent 7bc9be6 commit 268fe15
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
20 changes: 20 additions & 0 deletions flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ private void repaintWideDropLocation(JTree.DropLocation loc) {
tree.repaint( 0, r.y, tree.getWidth(), r.height );
}

@Override
public Rectangle getPathBounds( JTree tree, TreePath path ) {
Rectangle bounds = super.getPathBounds( tree, path );

// If this method was invoked from JTree.getPathForLocation(int x, int y) to check whether
// the location is within tree node bounds, then return the bounds of a wide node.
// This changes the behavior of JTree.getPathForLocation(int x, int y) and
// JTree.getRowForLocation(int x, int y), which now return the path/row even
// if [x,y] is in the wide row area outside of the actual tree node.
if( bounds != null &&
isWideSelection() &&
UIManager.getBoolean( "FlatLaf.experimental.tree.widePathForLocation" ) &&
StackUtils.wasInvokedFrom( JTree.class.getName(), "getPathForLocation", 5 ) )
{
bounds.x = 0;
bounds.width = tree.getWidth();
}
return bounds;
}

/**
* Same as super.paintRow(), but supports wide selection and uses
* inactive selection background/foreground if tree is not focused.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -39,6 +40,7 @@
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatMenuArrowIcon;
Expand Down Expand Up @@ -69,6 +71,7 @@ public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatComponents2Test" );
frame.useApplyComponentOrientation = true;
UIManager.put( "FlatLaf.experimental.tree.widePathForLocation", true );
frame.showFrame( FlatComponents2Test::new );
} );
}
Expand Down Expand Up @@ -378,6 +381,23 @@ private void treePaintSelectionChanged() {
tree.putClientProperty( FlatClientProperties.TREE_PAINT_SELECTION, paintSelection );
}

private void treeMouseClicked( MouseEvent e ) {
JTree tree = (JTree) e.getSource();
int x = e.getX();
int y = e.getY();

TreePath path = tree.getPathForLocation( x, y );
TreePath closestPath = tree.getClosestPathForLocation( x, y );
int row = tree.getRowForLocation( x, y );
int closestRow = tree.getClosestRowForLocation( x, y );

System.out.println( "---- tree mouseClicked " + x + "," + y + " ----" );
System.out.println( " path: " + path );
System.out.println( "closest path: " + closestPath );
System.out.println( " row: " + row );
System.out.println( "closest row: " + closestRow );
}

@Override
public void applyComponentOrientation( ComponentOrientation o ) {
super.applyComponentOrientation( o );
Expand Down Expand Up @@ -605,6 +625,12 @@ private void initComponents() {
//---- tree1 ----
tree1.setShowsRootHandles(true);
tree1.setEditable(true);
tree1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
treeMouseClicked(e);
}
});
scrollPane3.setViewportView(tree1);
}
add(scrollPane3, "cell 1 2");
Expand All @@ -614,6 +640,12 @@ private void initComponents() {

//---- tree2 ----
tree2.setEnabled(false);
tree2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
treeMouseClicked(e);
}
});
scrollPane4.setViewportView(tree2);
}
add(scrollPane4, "cell 2 2");
Expand Down Expand Up @@ -655,12 +687,28 @@ private void initComponents() {

//======== scrollPane5 ========
{

//---- xTree1 ----
xTree1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
treeMouseClicked(e);
}
});
scrollPane5.setViewportView(xTree1);
}
add(scrollPane5, "cell 1 3");

//======== scrollPane6 ========
{

//---- checkBoxTree1 ----
checkBoxTree1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
treeMouseClicked(e);
}
});
scrollPane6.setViewportView(checkBoxTree1);
}
add(scrollPane6, "cell 2 3");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"

new FormModel {
contentType: "form/swing"
Expand Down Expand Up @@ -185,6 +185,7 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.MouseListener", "mouseClicked", "treeMouseClicked", true ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
Expand All @@ -197,6 +198,7 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.MouseListener", "mouseClicked", "treeMouseClicked", true ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 2"
Expand Down Expand Up @@ -255,6 +257,7 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.MouseListener", "mouseClicked", "treeMouseClicked", true ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
Expand All @@ -266,6 +269,7 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.MouseListener", "mouseClicked", "treeMouseClicked", true ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 3"
Expand Down

0 comments on commit 268fe15

Please sign in to comment.