Merge remote-tracking branch 'origin/main' into styling

This commit is contained in:
Karl Tauber
2021-09-14 19:02:21 +02:00
25 changed files with 1562 additions and 245 deletions

View File

@@ -21,10 +21,15 @@ plugins {
`flatlaf-publish`
}
val sigtest = configurations.create( "sigtest" )
dependencies {
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" )
testImplementation( "org.junit.jupiter:junit-jupiter-params" )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
// https://github.com/jtulach/netbeans-apitest
sigtest( "org.netbeans.tools:sigtest-maven-plugin:1.4" )
}
java {
@@ -59,10 +64,60 @@ tasks {
archiveBaseName.set( "flatlaf" )
}
check {
dependsOn( "sigtestCheck" )
}
test {
useJUnitPlatform()
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
register( "sigtestGenerate" ) {
group = "verification"
dependsOn( "jar" )
doLast {
ant.withGroovyBuilder {
"taskdef"(
"name" to "sigtest",
"classname" to "org.netbeans.apitest.Sigtest",
"classpath" to sigtest.asPath )
"sigtest"(
"action" to "generate",
"fileName" to "${project.name}-sigtest.txt",
"classpath" to jar.get().outputs.files.asPath,
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
"version" to version,
"release" to "1.8", // Java version
"failonerror" to "true" )
}
}
}
register( "sigtestCheck" ) {
group = "verification"
dependsOn( "jar" )
doLast {
ant.withGroovyBuilder {
"taskdef"(
"name" to "sigtest",
"classname" to "org.netbeans.apitest.Sigtest",
"classpath" to sigtest.asPath )
"sigtest"(
"action" to "check",
"fileName" to "${project.name}-sigtest.txt",
"classpath" to jar.get().outputs.files.asPath,
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
"version" to version,
"release" to "1.8", // Java version
"failonerror" to "true" )
}
}
}
}
flatlafPublish {

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.CellRendererPane;
import javax.swing.ComboBoxEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.InputMap;
import javax.swing.JButton;
@@ -362,33 +361,25 @@ public class FlatComboBoxUI
}
@Override
protected ComboBoxEditor createEditor() {
ComboBoxEditor comboBoxEditor = super.createEditor();
protected void configureEditor() {
super.configureEditor();
Component editor = comboBoxEditor.getEditorComponent();
if( editor instanceof JTextField ) {
JTextField textField = (JTextField) editor;
textField.setColumns( editorColumns );
// assign a non-null and non-javax.swing.plaf.UIResource border to the text field,
// otherwise it is replaced with default text field border when switching LaF
// because javax.swing.plaf.basic.BasicComboBoxEditor.BorderlessTextField.setBorder()
// uses "border instanceof javax.swing.plaf.basic.BasicComboBoxEditor.UIResource"
// instead of "border instanceof javax.swing.plaf.UIResource"
textField.setBorder( BorderFactory.createEmptyBorder() );
// remove default text field border from editor
Border border = textField.getBorder();
if( border == null || border instanceof UIResource ) {
// assign a non-null and non-javax.swing.plaf.UIResource border to the text field,
// otherwise it is replaced with default text field border when switching LaF
// because javax.swing.plaf.basic.BasicComboBoxEditor.BorderlessTextField.setBorder()
// uses "border instanceof javax.swing.plaf.basic.BasicComboBoxEditor.UIResource"
// instead of "border instanceof javax.swing.plaf.UIResource"
textField.setBorder( BorderFactory.createEmptyBorder() );
}
}
return comboBoxEditor;
}
@Override
protected void configureEditor() {
super.configureEditor();
// remove default text field border from editor
if( editor instanceof JTextField && ((JTextField)editor).getBorder() instanceof FlatTextBorder )
((JTextField)editor).setBorder( BorderFactory.createEmptyBorder() );
// explicitly make non-opaque
if( editor instanceof JComponent )
((JComponent)editor).setOpaque( false );
@@ -782,6 +773,9 @@ public class FlatComboBoxUI
protected void configurePopup() {
super.configurePopup();
// make opaque to avoid that background shines thru border (e.g. at 150% scaling)
setOpaque( true );
Border border = UIManager.getBorder( "PopupMenu.border" );
if( border != null )
setBorder( border );
@@ -818,6 +812,21 @@ public class FlatComboBoxUI
return height;
}
@Override
public void show( Component invoker, int x, int y ) {
// Java 8: fix y coordinate if popup is shown above the combobox
// (already fixed in Java 9+ https://bugs.openjdk.java.net/browse/JDK-7072653)
if( y < 0 && !SystemInfo.isJava_9_orLater ) {
Border popupBorder = getBorder();
if( popupBorder != null ) {
Insets insets = popupBorder.getBorderInsets( this );
y -= insets.top + insets.bottom;
}
}
super.show( invoker, x, y );
}
@Override
protected void paintChildren( Graphics g ) {
super.paintChildren( g );

View File

@@ -283,6 +283,9 @@ public class FlatInternalFrameUI
//---- class FlatBorderListener -------------------------------------------
/**
* @since 1.6
*/
protected class FlatBorderListener
extends BorderListener
{

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Container;
import java.awt.Rectangle;
import java.awt.Window;
import java.beans.PropertyChangeListener;
@@ -24,7 +25,6 @@ import java.util.List;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeListener;
import com.formdev.flatlaf.FlatClientProperties;
@@ -76,6 +76,11 @@ public class FlatNativeWindowBorder
if( !isSupported() )
return null;
// do nothing if root pane has a parent that is not a window (e.g. a JInternalFrame)
Container parent = rootPane.getParent();
if( parent != null && !(parent instanceof Window) )
return null;
// Check whether root pane already has a window, which is the case when
// switching from another LaF to FlatLaf.
// Also check whether the window is displayable, which is required to install
@@ -83,9 +88,8 @@ public class FlatNativeWindowBorder
// If the window is not displayable, then it was probably closed/disposed but not yet removed
// from the list of windows that AWT maintains and returns with Window.getWindows().
// It could be also be a window that is currently hidden, but may be shown later.
Window window = SwingUtilities.windowForComponent( rootPane );
if( window != null && window.isDisplayable() )
install( window );
if( parent instanceof Window && parent.isDisplayable() )
install( (Window) parent );
// Install FlatLaf native window border, which must be done late,
// when the native window is already created, because it needs access to the window.
@@ -174,9 +178,9 @@ public class FlatNativeWindowBorder
return;
// uninstall native window border
Window window = SwingUtilities.windowForComponent( rootPane );
if( window != null )
uninstall( window );
Container parent = rootPane.getParent();
if( parent instanceof Window )
uninstall( (Window) parent );
}
private static void uninstall( Window window ) {

View File

@@ -18,9 +18,11 @@ package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseEvent;
@@ -223,9 +225,27 @@ public class FlatSliderUI
if( slider.getOrientation() == JSlider.VERTICAL )
return -1;
// use default font (instead of slider font) because the slider font size
// may be different to label font size, but we want align the track/thumb with labels
Font font = UIManager.getFont( "defaultFont" );
if( font == null )
font = slider.getFont();
FontMetrics fm = slider.getFontMetrics( font );
// calculate track y coordinate and height
// (not using field trackRect here because slider size may be [0,0]
// and field trackRect may have invalid values in this case)
Insets insets = slider.getInsets();
int thumbHeight = getThumbSize().height;
int contentHeight = height - insets.top - insets.bottom - focusInsets.top - focusInsets.bottom;
int centerSpacing = thumbHeight
+ (slider.getPaintTicks() ? getTickLength() : 0)
+ (slider.getPaintLabels() ? getHeightOfTallestLabel() : 0);
int trackY = insets.top + focusInsets.top + (contentHeight - centerSpacing - 1) / 2;
int trackHeight = thumbHeight;
// compute a baseline so that the track is vertically centered
FontMetrics fm = slider.getFontMetrics( slider.getFont() );
return trackRect.y + Math.round( (trackRect.height - fm.getHeight()) / 2f ) + fm.getAscent() - 1;
return trackY + Math.round( (trackHeight - fm.getHeight()) / 2f ) + fm.getAscent() - 1;
}
@Override

View File

@@ -219,15 +219,7 @@ public class FlatSpinnerUI
@Override
protected JComponent createEditor() {
JComponent editor = super.createEditor();
// explicitly make non-opaque
editor.setOpaque( false );
JTextField textField = getEditorTextField( editor );
if( textField != null )
textField.setOpaque( false );
updateEditorPadding();
updateEditorColors();
configureEditor( editor );
return editor;
}
@@ -235,8 +227,19 @@ public class FlatSpinnerUI
protected void replaceEditor( JComponent oldEditor, JComponent newEditor ) {
super.replaceEditor( oldEditor, newEditor );
configureEditor( newEditor );
removeEditorFocusListener( oldEditor );
addEditorFocusListener( newEditor );
}
/** @since 1.6 */
protected void configureEditor( JComponent editor ) {
// explicitly make non-opaque
editor.setOpaque( false );
JTextField textField = getEditorTextField( editor );
if( textField != null )
textField.setOpaque( false );
updateEditorPadding();
updateEditorColors();

View File

@@ -25,6 +25,7 @@ import java.awt.Insets;
import java.awt.geom.Rectangle2D;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.JTableHeader;
@@ -45,7 +46,7 @@ public class FlatTableHeaderBorder
{
protected Color separatorColor = UIManager.getColor( "TableHeader.separatorColor" );
protected Color bottomSeparatorColor = UIManager.getColor( "TableHeader.bottomSeparatorColor" );
protected boolean showLastVerticalLine = UIManager.getBoolean( "TableHeader.showLastVerticalLine" );
/** @since 1.6 */ protected boolean showTrailingVerticalLine = UIManager.getBoolean( "TableHeader.showTrailingVerticalLine" );
public FlatTableHeaderBorder() {
super( UIManager.getInsets( "TableHeader.cellMargins" ) );
@@ -138,15 +139,23 @@ public class FlatTableHeaderBorder
}
protected boolean hideTrailingVerticalLine( JTableHeader header ) {
if( showLastVerticalLine )
if( showTrailingVerticalLine )
return false;
// do not hide if table header is not a child of a scroll pane
Container viewport = header.getParent();
Container viewportParent = (viewport != null) ? viewport.getParent() : null;
if( !(viewportParent instanceof JScrollPane) )
return true;
return false;
JScrollBar vsb = ((JScrollPane)viewportParent).getVerticalScrollBar();
// do not hide if table header is not the column header of the scroll pane
JScrollPane scrollPane = (JScrollPane) viewportParent;
JViewport columnHeader = scrollPane.getColumnHeader();
if( viewport != columnHeader )
return false;
// hide if vertical scroll bar is not shown
JScrollBar vsb = scrollPane.getVerticalScrollBar();
if( vsb == null || !vsb.isVisible() )
return true;

View File

@@ -66,7 +66,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TableHeader.cellMargins Insets
* @uiDefault TableHeader.separatorColor Color
* @uiDefault TableHeader.bottomSeparatorColor Color
* @uiDefault TableHeader.showLastVerticalLine boolean
* @uiDefault TableHeader.showTrailingVerticalLine boolean
*
* <!-- FlatAscendingSortIcon and FlatDescendingSortIcon -->
*

View File

@@ -75,7 +75,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Table.rowHeight int
* @uiDefault Table.showHorizontalLines boolean
* @uiDefault Table.showVerticalLines boolean
* @uiDefault Table.showLastVerticalLine boolean
* @uiDefault Table.showTrailingVerticalLine boolean
* @uiDefault Table.intercellSpacing Dimension
* @uiDefault Table.selectionInactiveBackground Color
* @uiDefault Table.selectionInactiveForeground Color
@@ -98,7 +98,7 @@ public class FlatTableUI
{
protected boolean showHorizontalLines;
protected boolean showVerticalLines;
protected boolean showLastVerticalLine;
/** @since 1.6 */ protected boolean showTrailingVerticalLine;
protected Dimension intercellSpacing;
@Styleable protected Color selectionBackground;
@@ -135,7 +135,7 @@ public class FlatTableUI
showHorizontalLines = UIManager.getBoolean( "Table.showHorizontalLines" );
showVerticalLines = UIManager.getBoolean( "Table.showVerticalLines" );
showLastVerticalLine = UIManager.getBoolean( "Table.showLastVerticalLine" );
showTrailingVerticalLine = UIManager.getBoolean( "Table.showTrailingVerticalLine" );
intercellSpacing = UIManager.getDimension( "Table.intercellSpacing" );
selectionBackground = UIManager.getColor( "Table.selectionBackground" );
@@ -392,9 +392,10 @@ public class FlatTableUI
}
protected boolean hideLastVerticalLine() {
if( showLastVerticalLine )
if( showTrailingVerticalLine )
return false;
// do not hide if table is not a child of a scroll pane
Container viewport = SwingUtilities.getUnwrappedParent( table );
Container viewportParent = (viewport != null) ? viewport.getParent() : null;
if( !(viewportParent instanceof JScrollPane) )

View File

@@ -70,9 +70,10 @@ public class JBRCustomDecorations
return null;
// check whether root pane already has a parent, which is the case when switching LaF
Window window = SwingUtilities.windowForComponent( rootPane );
if( window != null ) {
FlatNativeWindowBorder.install( window );
Container parent = rootPane.getParent();
if( parent != null ) {
if( parent instanceof Window )
FlatNativeWindowBorder.install( (Window) parent );
return null;
}
@@ -110,9 +111,9 @@ public class JBRCustomDecorations
// since it is actually not possible to uninstall JBR decorations,
// simply reduce titleBarHeight so that it is still possible to resize window
// and remove hitTestSpots
Window window = SwingUtilities.windowForComponent( rootPane );
if( window != null )
setHasCustomDecoration( window, false );
Container parent = rootPane.getParent();
if( parent instanceof Window )
setHasCustomDecoration( (Window) parent, false );
}
static boolean hasCustomDecoration( Window window ) {

View File

@@ -628,7 +628,7 @@ TabbedPane.closeCrossLineWidth = {float}1
Table.rowHeight = 20
Table.showHorizontalLines = false
Table.showVerticalLines = false
Table.showLastVerticalLine = false
Table.showTrailingVerticalLine = false
Table.consistentHomeEndKeyBehavior = true
Table.intercellSpacing = {dimension}0,0
Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatBorder
@@ -658,7 +658,7 @@ TableHeader.cellBorder = com.formdev.flatlaf.ui.FlatTableHeaderBorder
TableHeader.cellMargins = 2,3,2,3
TableHeader.focusCellBackground = $TableHeader.background
TableHeader.background = @textComponentBackground
TableHeader.showLastVerticalLine = false
TableHeader.showTrailingVerticalLine = false
#---- TextArea ----