@@ -1382,7 +1382,10 @@ public static void centerOnParent(final Component parent, final Window dialog) {
13821382 dialog .setLocationRelativeTo (null );
13831383 return ;
13841384 }
1385- centerOnParent (parent .getBounds (), parent .getGraphicsConfiguration (), dialog );
1385+ final java .awt .Point screenLoc = parent .getLocationOnScreen ();
1386+ final Rectangle screenBounds = new Rectangle (screenLoc .x , screenLoc .y ,
1387+ parent .getWidth (), parent .getHeight ());
1388+ centerOnParent (screenBounds , parent .getGraphicsConfiguration (), dialog );
13861389 }
13871390
13881391 public static void centerOnParent (final Rectangle parentBounds , final Window dialog ) {
@@ -3495,6 +3498,30 @@ public static void expandAllNodes(final javax.swing.JTree tree) {
34953498 for (int i = 0 ; i < tree .getRowCount (); i ++) tree .expandRow (i );
34963499 }
34973500
3501+ public static void scrollToLastRow (final javax .swing .JTree tree ) {
3502+ int lastRow = tree .getRowCount () - 1 ;
3503+ if (lastRow >= 0 ) {
3504+ tree .scrollRowToVisible (lastRow );
3505+ }
3506+ }
3507+
3508+ public static void expandToLevel (final javax .swing .JTree tree , final int level ) {
3509+ final DefaultMutableTreeNode root = (DefaultMutableTreeNode ) tree .getModel ().getRoot ();
3510+ expandToLevel (tree , new TreePath (root ), level );
3511+ }
3512+
3513+ private static void expandToLevel (final javax .swing .JTree tree , final TreePath parentPath , final int level ) {
3514+ final DefaultMutableTreeNode node = (DefaultMutableTreeNode ) parentPath .getLastPathComponent ();
3515+ if (node .getLevel () < level ) {
3516+ tree .expandPath (parentPath );
3517+ final Enumeration <? extends TreeNode > children = node .children ();
3518+ while (children .hasMoreElements ()) {
3519+ final DefaultMutableTreeNode child = (DefaultMutableTreeNode ) children .nextElement ();
3520+ expandToLevel (tree , parentPath .pathByAddingChild (child ), level );
3521+ }
3522+ }
3523+ }
3524+
34983525 public static void collapseNodesOfSameLevel (final javax .swing .JTree tree , final TreePath path ) {
34993526 final DefaultMutableTreeNode root = (DefaultMutableTreeNode )tree .getModel ().getRoot ();
35003527 final DefaultMutableTreeNode node = (DefaultMutableTreeNode ) path .getLastPathComponent ();
@@ -3673,4 +3700,102 @@ else if (current instanceof Container) {
36733700 return null ;
36743701 }
36753702 }
3703+
3704+ public static class SplitPanes {
3705+
3706+ public static JSplitPane nonDraggableRightSplitPane () {
3707+ final JSplitPane splitPane = new JSplitPane (JSplitPane .HORIZONTAL_SPLIT );
3708+ splitPane .setOneTouchExpandable (true );
3709+ splitPane .putClientProperty ("JSplitPane.expandableSide" , "left" );
3710+ splitPane .putClientProperty (FlatClientProperties .STYLE ,
3711+ "style: plain;" +
3712+ "arrowType: triangle;" + //oneTouchArrowColor; oneTouchHoverArrowColor
3713+ "oneTouchHoverArrowColor: " + SNTColor .colorToString (getSelectionColor ()) + ";" +
3714+ "oneTouchArrowColor: " + SNTColor .colorToString (IconFactory .defaultColor ()) + ";" );
3715+ splitPane .setResizeWeight (1.0 ); // give all extra space to the left side
3716+ splitPane .setBorder (null );
3717+ // Non: resizable: reset cursor and vertically center the one-touch buttons along the divider's length
3718+ final javax .swing .plaf .basic .BasicSplitPaneDivider divider =
3719+ ((javax .swing .plaf .basic .BasicSplitPaneUI ) splitPane .getUI ()).getDivider ();
3720+ SplitPanes .applyDefaultCursor (divider );
3721+ SplitPanes .centerOneTouchButtons (splitPane , divider );
3722+ return splitPane ;
3723+ }
3724+
3725+ public static void applyDefaultCursor (final javax .swing .plaf .basic .BasicSplitPaneDivider divider ) {
3726+ divider .setCursor (java .awt .Cursor .getDefaultCursor ());
3727+ }
3728+
3729+ public static void centerOneTouchButtons (final javax .swing .JSplitPane splitPane ,
3730+ final javax .swing .plaf .basic .BasicSplitPaneDivider divider ) {
3731+ divider .setLayout (new java .awt .LayoutManager () {
3732+ @ Override
3733+ public void addLayoutComponent (final String name , final Component comp ) {
3734+ }
3735+
3736+ @ Override
3737+ public void removeLayoutComponent (final Component comp ) {
3738+ }
3739+
3740+ @ Override
3741+ public java .awt .Dimension preferredLayoutSize (final Container parent ) {
3742+ return null ;
3743+ }
3744+
3745+ @ Override
3746+ public java .awt .Dimension minimumLayoutSize (final Container parent ) {
3747+ return null ;
3748+ }
3749+
3750+ @ Override
3751+ public void layoutContainer (final Container parent ) {
3752+ // Replicate FlatDividerLayout's visibility logic: when a side
3753+ // is collapsed, show only the button that can restore it.
3754+ // Otherwise, respect the expandableSide client property.
3755+ final Component [] comps = parent .getComponents ();
3756+ final java .awt .Insets insets = splitPane .getInsets ();
3757+ final int loc = splitPane .getDividerLocation ();
3758+ final boolean horiz = splitPane .getOrientation () == javax .swing .JSplitPane .HORIZONTAL_SPLIT ;
3759+ final boolean leftCollapsed = horiz
3760+ ? loc <= insets .left
3761+ : loc <= insets .top ;
3762+ final boolean rightCollapsed = horiz
3763+ ? loc >= splitPane .getWidth () - divider .getWidth () - insets .right
3764+ : loc >= splitPane .getHeight () - divider .getHeight () - insets .bottom ;
3765+ for (int i = 0 ; i < comps .length ; i ++) {
3766+ if (!(comps [i ] instanceof javax .swing .JButton )) continue ;
3767+ if (leftCollapsed || rightCollapsed ) {
3768+ // Collapsed: show only the button that restores the collapsed side
3769+ comps [i ].setVisible (i == 0 ? !leftCollapsed : !rightCollapsed );
3770+ } else {
3771+ final Object expandSide = splitPane .getClientProperty (
3772+ FlatClientProperties .SPLIT_PANE_EXPANDABLE_SIDE );
3773+ if (FlatClientProperties .SPLIT_PANE_EXPANDABLE_SIDE_LEFT .equals (expandSide ))
3774+ comps [i ].setVisible (i > 0 );
3775+ else if (FlatClientProperties .SPLIT_PANE_EXPANDABLE_SIDE_RIGHT .equals (expandSide ))
3776+ comps [i ].setVisible (i == 0 );
3777+ }
3778+ }
3779+ // Collect visible buttons and center them vertically
3780+ final java .util .List <Component > buttons = new java .util .ArrayList <>();
3781+ for (final Component c : comps ) {
3782+ if (c instanceof javax .swing .JButton && c .isVisible ())
3783+ buttons .add (c );
3784+ }
3785+ if (buttons .isEmpty ()) return ;
3786+ final int divW = parent .getWidth ();
3787+ final int divH = parent .getHeight ();
3788+ final int btnW = Math .min (divW , buttons .getFirst ().getPreferredSize ().width );
3789+ final int btnH = buttons .getFirst ().getPreferredSize ().height ;
3790+ final int totalH = buttons .size () * btnH ;
3791+ int y = (divH - totalH ) / 2 ;
3792+ final int x = (divW - btnW ) / 2 ;
3793+ for (final Component btn : buttons ) {
3794+ btn .setBounds (x , y , btnW , btnH );
3795+ y += btnH ;
3796+ }
3797+ }
3798+ });
3799+ }
3800+ }
36763801}
0 commit comments