ScrollPane implemented (with focused border)

This commit is contained in:
Karl Tauber
2019-08-21 17:51:25 +02:00
parent b534cd5082
commit c5d37d86db
6 changed files with 146 additions and 23 deletions

View File

@@ -22,6 +22,8 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Paint;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicBorders;
import javax.swing.text.JTextComponent;
@@ -43,7 +45,7 @@ public class FlatBorder
float focusWidth = getFocusWidth();
float lineWidth = getLineWidth();
if( c.hasFocus() ) {
if( isFocused( c ) ) {
g2.setColor( UIManager.getColor( "Component.focusColor" ) );
FlatUIUtils.paintOutlineBorder( g2, x, y, width, height, focusWidth, lineWidth, 0 );
}
@@ -58,21 +60,30 @@ public class FlatBorder
private Paint getBorderColor( Component c ) {
boolean editable = !(c instanceof JTextComponent) || ((JTextComponent)c).isEditable();
return UIManager.getColor( c.isEnabled() && editable
? (c.hasFocus()
? (isFocused( c )
? "Component.focusedBorderColor"
: "Component.borderColor")
: "Component.disabledBorderColor" );
}
private boolean isFocused( Component c ) {
if( c instanceof JScrollPane ) {
JViewport viewport = ((JScrollPane)c).getViewport();
Component view = (viewport != null) ? viewport.getView() : null;
return (view != null) ? view.hasFocus() : false;
} else
return c.hasFocus();
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
float ow = getFocusWidth() + getLineWidth();
insets = super.getBorderInsets( c, insets );
insets.top = round( scale( (float) insets.top ) + ow );
insets.left = round( scale( (float) insets.left ) + ow );
insets.bottom = round( scale( (float) insets.bottom ) + ow );
insets.right = round( scale( (float) insets.right ) + ow );
insets.top = Math.round( scale( (float) insets.top ) + ow );
insets.left = Math.round( scale( (float) insets.left ) + ow );
insets.bottom = Math.round( scale( (float) insets.bottom ) + ow );
insets.right = Math.round( scale( (float) insets.right ) + ow );
return insets;
}

View File

@@ -82,10 +82,10 @@ public class FlatButtonBorder
float ow = getFocusWidth() + getLineWidth();
insets = super.getBorderInsets( c, insets );
insets.top = round( scale( (float) insets.top ) + ow );
insets.left = round( scale( (float) insets.left ) + ow );
insets.bottom = round( scale( (float) insets.bottom ) + ow );
insets.right = round( scale( (float) insets.right ) + ow );
insets.top = Math.round( scale( (float) insets.top ) + ow );
insets.left = Math.round( scale( (float) insets.left ) + ow );
insets.bottom = Math.round( scale( (float) insets.bottom ) + ow );
insets.right = Math.round( scale( (float) insets.right ) + ow );
return insets;
}

View File

@@ -104,13 +104,11 @@ public class FlatCheckBoxIcon
@Override
public int getIconWidth() {
// use Math.round(), instead of UIScale.round(), because this gives same
// icon size as scaled graphics used in paintIcon()
return Math.round( scale( 19f ) );
return scale( 19 );
}
@Override
public int getIconHeight() {
return Math.round( scale( 19f ) );
return scale( 19 );
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright 2019 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import java.awt.Component;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollPaneUI;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
*
* @author Karl Tauber
*/
public class FlatScrollPaneUI
extends BasicScrollPaneUI
{
private final Handler handler = new Handler();
public static ComponentUI createUI( JComponent c ) {
return new FlatScrollPaneUI();
}
@Override
protected void installListeners( JScrollPane c ) {
super.installListeners( c );
JViewport viewport = scrollpane.getViewport();
if( viewport != null )
viewport.addContainerListener( handler );
}
@Override
protected void uninstallListeners( JComponent c ) {
super.uninstallListeners( c );
JViewport viewport = scrollpane.getViewport();
if( viewport != null )
viewport.removeContainerListener( handler );
}
@Override
protected void updateViewport( PropertyChangeEvent e ) {
super.updateViewport( e );
JViewport oldViewport = (JViewport) (e.getOldValue());
JViewport newViewport = (JViewport) (e.getNewValue());
if( oldViewport != null ) {
oldViewport.removeContainerListener( handler );
Component oldView = oldViewport.getView();
if( oldView != null )
oldView.removeFocusListener( handler );
}
if( newViewport != null ) {
newViewport.addContainerListener( handler );
Component newView = newViewport.getView();
if( newView != null )
newView.addFocusListener( handler );
}
}
//---- class Handler ------------------------------------------------------
/**
* ContainerListener is added to JViewport to keep focus listener on view up-to-date.
* FocusListener is added to view for repainting when view gets focused.
*/
private class Handler
implements ContainerListener, FocusListener
{
@Override
public void componentAdded( ContainerEvent e ) {
e.getChild().addFocusListener( this );
}
@Override
public void componentRemoved( ContainerEvent e ) {
e.getChild().removeFocusListener( this );
}
@Override
public void focusGained( FocusEvent e ) {
scrollpane.repaint();
}
@Override
public void focusLost( FocusEvent e ) {
scrollpane.repaint();
}
}
}

View File

@@ -169,7 +169,7 @@ public class UIScale
}
public static int scale( int value ) {
return (scaleFactor == 1) ? value : round( value * scaleFactor );
return (scaleFactor == 1) ? value : Math.round( value * scaleFactor );
}
public static float unscale( float value ) {
@@ -177,14 +177,7 @@ public class UIScale
}
public static int unscale( int value ) {
return (scaleFactor == 1f) ? value : round( value / scaleFactor );
}
public static int round( float value ) {
// subtracting 0.01 gives "better" results in some cases
// e.g. 2px * 125% = 2px instead of 3px
// or 1px * 150% = 1px instead of 2px
return Math.round( value - 0.01f );
return (scaleFactor == 1f) ? value : Math.round( value / scaleFactor );
}
public static void scaleGraphics( Graphics2D g ) {

View File

@@ -22,6 +22,7 @@ FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI
LabelUI=com.formdev.flatlaf.ui.FlatLabelUI
PasswordFieldUI=com.formdev.flatlaf.ui.FlatPasswordFieldUI
RadioButtonUI=com.formdev.flatlaf.ui.FlatRadioButtonUI
ScrollPaneUI=com.formdev.flatlaf.ui.FlatScrollPaneUI
TextFieldUI=com.formdev.flatlaf.ui.FlatTextFieldUI
@@ -63,6 +64,11 @@ RadioButton.border=com.formdev.flatlaf.ui.FlatMarginBorder
RadioButton.icon=com.formdev.flatlaf.ui.FlatRadioButtonIcon
#---- ScrollPane ----
ScrollPane.border=com.formdev.flatlaf.ui.FlatBorder
#---- TextField ----
TextField.border=com.formdev.flatlaf.ui.FlatBorder