question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Existence of SplitPane-Handle isn't clear to the user

See original GitHub issue

Unless a user knows that a splitpane is present, it’s not possible to see it, as there’s currently no handle. I’d suggest adding a handle. We currently add three dots that use the same colors as the disabled font color.

We’d like to properly implement this though. We’ve been using this hack for a while and would like to contribute this. Would you be okay with that? If so, what color should we use for it and what should the size of the handle and the icons be?

This is the code we’ve been using and an image of what it looks like:

grafik

Icon:

public class SplitPaneDividerBorderIcon implements Icon
{
  private static final Color CIRCLE_COLOR  = UIManager.getColor( "Label.disabledForeground" );
  private static final int   CIRCLE_AMOUNT = 3;
  private static final int   SIZE          = SwingGuiUtils.scaleToDpi( 16 );
  //Wir haben 3 Kreise und wollen, dass dessen Durchmesser 25% der Breite des Icons entsprechen.
  private static final int            CIRCLE_SIZE     = SIZE / 4;
  private static final int            GAP             = (SIZE - (CIRCLE_SIZE * CIRCLE_AMOUNT)) / (CIRCLE_AMOUNT - 1);
  private static final RenderingHints RENDERING_HINTS = new RenderingHints(
      RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON );

  private final boolean vertical;
  private final int     height;
  private final int     width;

  /**
   * @param vertical true = vertical
   */
  public SplitPaneDividerBorderIcon( final boolean vertical )
  {
    this.vertical = vertical;
    height = vertical ? SIZE : (CIRCLE_SIZE * 3);
    width = vertical ? (CIRCLE_SIZE * 3) : SIZE;
  }

  @Override
  public void paintIcon( final Component c, final Graphics g, final int x, final int y )
  {
    if ( g instanceof Graphics2D )
    {
      ((Graphics2D) g).setRenderingHints( RENDERING_HINTS );
    }
    g.setColor( CIRCLE_COLOR );
    final Rectangle bounds = c.getBounds();
    int xPosition = bounds.width / 2 - (CIRCLE_SIZE / 2);
    int yPosition = bounds.height / 2 - (CIRCLE_SIZE / 2);
    if ( !vertical )
    {
      //Aus irgendeinem Grund ist dieses Icon nicht zentriert, daher rechnen wir ein Feel-Good-Wert hinzu.
      yPosition -= SwingGuiUtils.scaleToDpi( 8 );
      for ( int i = 0; i < CIRCLE_AMOUNT; i++ )
      {
        g.fillOval( xPosition, yPosition + (i * GAP + i * CIRCLE_SIZE), CIRCLE_SIZE, CIRCLE_SIZE );
      }
    }
    else
    {
      //Aus irgendeinem Grund ist dieses Icon nicht zentriert, daher rechnen wir ein Feel-Good-Wert hinzu.
      xPosition -= SwingGuiUtils.scaleToDpi( 8 );
      for ( int i = 0; i < CIRCLE_AMOUNT; i++ )
      {
        g.fillOval( xPosition + (i * GAP + i * CIRCLE_SIZE), yPosition, CIRCLE_SIZE, CIRCLE_SIZE );
      }
    }
  }

  @Override
  public int getIconHeight()
  {
    return height;
  }

  @Override
  public int getIconWidth()
  {
    return width;
  }
}

Border:

public static class SplitPaneDividerBorder implements Border
{
  private final Icon iconVertical;
  private final Icon iconHorizontal;

  private final Insets insets;

  public SplitPaneDividerBorder( final Icon iconVertical, final Icon iconHorizontal )
  {
    this.iconVertical = iconVertical;
    this.iconHorizontal = iconHorizontal;

    //Insets sind null, da der Border keine Größe haben soll, sondern lediglich zentriert ein Icon zeichnen soll.
    insets = new Insets( 0, 0, 0, 0 );
  }

  @Override
  public void paintBorder( final @Nullable Component component, final @Nullable Graphics graphics,
                           final int x, final int y, final int width, final int height )
  {
    if ( component instanceof BasicSplitPaneDivider )
    {
      final BasicSplitPaneDivider divider = (BasicSplitPaneDivider) component;
      final int orientation = getDividerOrientation( divider );

      if ( orientation == JSplitPane.VERTICAL_SPLIT )
      {
        iconVertical.paintIcon( divider, graphics, 0, 0 );
      }
      else if ( orientation == JSplitPane.HORIZONTAL_SPLIT )
      {
        iconHorizontal.paintIcon( divider, graphics, 0, 0 );
      }
    }
  }

  private static int getDividerOrientation( final BasicSplitPaneDivider divider )
  {
    final int orientation;
    if ( divider.getParent() instanceof JSplitPane )
    {
      final JSplitPane parentSplitPane = (JSplitPane) divider.getParent();
      orientation = parentSplitPane.getOrientation();
    }
    else
    {
      throw new UnsupportedOperationException( "Ein SplitPaneDivider braucht eine SplitPane." );
    }

    return orientation;
  }

  @Override
  public Insets getBorderInsets( final @Nullable Component c )
  {
    return insets;
  }


  @Override
  public boolean isBorderOpaque()
  {
    return true;
  }
}

To use it:

    final Icon iconVertical = new SplitPaneDividerBorderIcon( true );
    final Icon iconHorizontal = new SplitPaneDividerBorderIcon( false );
    UIManager.put( "SplitPaneDivider.border", new SplitPaneDividerBorder( iconVertical, iconHorizontal ) );
    UIManager.put( "SplitPane.dividerSize", iconVertical.getIconWidth() );

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:14 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
DevCharlycommented, Nov 16, 2020

The splitpane divider grip is implemented in commit 18d8c7d086f190df8020f0a8ffa105664a938b2c.

image

@Bios-Marcel the divider width is still 5px, but the dots are smaller than in your code. However you can configure the dot size, dot count, dot gap and dot color:

https://github.com/JFormDesigner/FlatLaf/blob/18d8c7d086f190df8020f0a8ffa105664a938b2c/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties#L535-L540

Following code makes divider wider, dots larger and use 4 dots:

UIManager.put( "SplitPane.dividerSize", 9 );
UIManager.put( "SplitPaneDivider.gripDotCount", 4 );
UIManager.put( "SplitPaneDivider.gripDotSize", 4 );
UIManager.put( "SplitPaneDivider.gripGap", 3 );

image

To disable divider grip use:

UIManager.put( "SplitPaneDivider.style", "plain" );
1reaction
DevCharlycommented, Nov 16, 2020

@Bios-Marcel thanks for the offer. FlatLaf development definitely could need some sponsoring 😃 Until now I’ve financed it alone… Please contact me at info (at) formdev (dot) com. Thanks.

@j-dimension found and answered you Email. Thx.

Read more comments on GitHub >

github_iconTop Results From Across the Web

jsplitpane - Java SplitPaneDemo not working? - Stack Overflow
The demo works just fine. It's your modification(s) that don't work :) This does work: /* * Copyright (c) 1995, 2008, Oracle and/or...
Read more >
How to Use Split Panes - Oracle Help Center
A JSplitPane displays two components, either side by side or one on top of the other. By dragging the divider that appears between...
Read more >
SplitPane in JavaFX 2.0 - FX Experience
We've introduced a SplitPane control in JavaFX 2.0, and today I thought I'd point out an interesting subtlety in the API.
Read more >
[RFE] Split pane in same window for side-by-side proof reading
With "split pane", the panes are really easy to manage and it's super ... sense to create the feature, which actually already in...
Read more >
1063742 - Implement split-pane Remote Tabs home panel for tablets
2) The list of synced tabs shown to tablet users does not follow yuan's mocks (see ... It's not clear if we want...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found