Skip to content

Commit

Permalink
ScrollPane: increase viewport width for rounded border to remove/redu…
Browse files Browse the repository at this point in the history
…ce gap between view and vertical scrollbar
  • Loading branch information
DevCharly committed Aug 27, 2023
1 parent 4041860 commit 0c604b1
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,26 @@ public void update( Graphics g, JComponent c ) {
paint( g, c );
}

@Override
public void paint( Graphics g, JComponent c ) {
Border viewportBorder = scrollpane.getViewportBorder();
if( viewportBorder != null ) {
Rectangle r = scrollpane.getViewportBorderBounds();
int padding = getBorderLeftRightPadding( scrollpane );
JScrollBar vsb = scrollpane.getVerticalScrollBar();
if( padding > 0 &&
vsb != null && vsb.isVisible() &&
scrollpane.getLayout() instanceof FlatScrollPaneLayout &&
((FlatScrollPaneLayout)scrollpane.getLayout()).canIncreaseViewportWidth( scrollpane ) )
{
boolean ltr = scrollpane.getComponentOrientation().isLeftToRight();
int extraWidth = Math.min( padding, vsb.getWidth() );
viewportBorder.paintBorder( scrollpane, g, r.x - (ltr ? 0 : extraWidth), r.y, r.width + extraWidth, r.height );
} else
viewportBorder.paintBorder( scrollpane, g, r.x, r.y, r.width, r.height );
}
}

/** @since 1.3 */
public static boolean isPermanentFocusOwner( JScrollPane scrollPane ) {
Component view = getView( scrollPane );
Expand Down Expand Up @@ -488,6 +508,13 @@ private static float getBorderArc( JScrollPane scrollPane ) {
: 0;
}

private static int getBorderLeftRightPadding( JScrollPane scrollPane ) {
Border border = scrollPane.getBorder();
return (border instanceof FlatScrollPaneBorder)
? ((FlatScrollPaneBorder)border).getLeftRightPadding( scrollPane )
: 0;
}

//---- class Handler ------------------------------------------------------

/**
Expand Down Expand Up @@ -533,23 +560,46 @@ public void layoutContainer( Container parent ) {
super.layoutContainer( parent );

JScrollPane scrollPane = (JScrollPane) parent;
Border border = scrollPane.getBorder();
int padding;
if( border instanceof FlatScrollPaneBorder &&
(padding = ((FlatScrollPaneBorder)border).getLeftRightPadding( scrollPane )) > 0 )
{
JScrollBar vsb = getVerticalScrollBar();
if( vsb != null && vsb.isVisible() ) {
// move vertical scrollbar to trailing edge
Insets insets = scrollPane.getInsets();
Rectangle r = vsb.getBounds();
int y = Math.max( r.y, insets.top + padding );
int y2 = Math.min( r.y + r.height, scrollPane.getHeight() - insets.bottom - padding );
boolean ltr = scrollPane.getComponentOrientation().isLeftToRight();

vsb.setBounds( r.x + (ltr ? padding : -padding), y, r.width, y2 - y );
int padding = getBorderLeftRightPadding( scrollPane );
if( padding > 0 && vsb != null && vsb.isVisible() ) {
// move vertical scrollbar to trailing edge
Insets insets = scrollPane.getInsets();
Rectangle r = vsb.getBounds();
int y = Math.max( r.y, insets.top + padding );
int y2 = Math.min( r.y + r.height, scrollPane.getHeight() - insets.bottom - padding );
boolean ltr = scrollPane.getComponentOrientation().isLeftToRight();

vsb.setBounds( r.x + (ltr ? padding : -padding), y, r.width, y2 - y );

// increase width of viewport, column header and horizontal scrollbar
if( canIncreaseViewportWidth( scrollPane ) ) {
int extraWidth = Math.min( padding, vsb.getWidth() );
resizeViewport( viewport, extraWidth, ltr );
resizeViewport( colHead, extraWidth, ltr );
resizeViewport( hsb, extraWidth, ltr );
}
}
}

boolean canIncreaseViewportWidth( JScrollPane scrollPane ) {
return scrollPane.getComponentOrientation().isLeftToRight()
? !isCornerVisible( upperRight ) && !isCornerVisible( lowerRight )
: !isCornerVisible( upperLeft ) && !isCornerVisible( lowerLeft );
}

private static boolean isCornerVisible( Component corner ) {
return corner != null &&
corner.getWidth() > 0 &&
corner.getHeight() > 0 &&
corner.isVisible();
}

private static void resizeViewport( Component c, int extraWidth, boolean ltr ) {
if( c == null )
return;

Rectangle vr = c.getBounds();
c.setBounds( vr.x - (ltr ? 0 : extraWidth), vr.y, vr.width + extraWidth, vr.height );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.MatteBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.*;
import com.formdev.flatlaf.FlatClientProperties;
Expand Down Expand Up @@ -212,6 +214,19 @@ private void arcSliderChanged() {
: "?" );
}

private void viewportBorderChanged() {
Border viewportBorder = viewportBorderCheckBox.isSelected()
? new CompoundBorder(
new MatteBorder( 1, 1, 0, 0, Color.red ),
new MatteBorder( 0, 0, 1, 1, Color.blue ) )
: null;
for( JScrollPane scrollPane : allJScrollPanes ) {
scrollPane.setViewportBorder( viewportBorder );
scrollPane.revalidate();
scrollPane.repaint();
}
}

private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
splitPane2 = new JSplitPane();
Expand Down Expand Up @@ -247,6 +262,7 @@ private void initComponents() {
cornersCheckBox = new JCheckBox();
columnHeaderCheckBox = new JCheckBox();
horizontalScrollBarCheckBox = new JCheckBox();
viewportBorderCheckBox = new JCheckBox();
rowHeaderCheckBox = new JCheckBox();
verticalScrollBarCheckBox = new JCheckBox();

Expand Down Expand Up @@ -437,6 +453,11 @@ private void initComponents() {
horizontalScrollBarCheckBox.addActionListener(e -> horizontalScrollBarChanged());
panel3.add(horizontalScrollBarCheckBox, "cell 4 0");

//---- viewportBorderCheckBox ----
viewportBorderCheckBox.setText("Viewport border");
viewportBorderCheckBox.addActionListener(e -> viewportBorderChanged());
panel3.add(viewportBorderCheckBox, "cell 2 1");

//---- rowHeaderCheckBox ----
rowHeaderCheckBox.setText("Row Header");
rowHeaderCheckBox.addActionListener(e -> rowHeaderChanged());
Expand Down Expand Up @@ -485,6 +506,7 @@ private void initComponents() {
private JCheckBox cornersCheckBox;
private JCheckBox columnHeaderCheckBox;
private JCheckBox horizontalScrollBarCheckBox;
private JCheckBox viewportBorderCheckBox;
private JCheckBox rowHeaderCheckBox;
private JCheckBox verticalScrollBarCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
JFDML JFormDesigner: "8.1.1.0.298" Java: "19.0.2" encoding: "UTF-8"

new FormModel {
contentType: "form/swing"
Expand Down Expand Up @@ -216,6 +216,13 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "viewportBorderCheckBox"
"text": "Viewport border"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "viewportBorderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "rowHeaderCheckBox"
"text": "Row Header"
Expand Down

0 comments on commit 0c604b1

Please sign in to comment.