From 4b4837e3a1b7442766f760780669980065cf87bf Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 10:04:48 +0100 Subject: [PATCH 01/46] IntelliJ Themes Demo: updated Hiberbee theme (used IJThemesUpdater) (issue #26) --- .../demo/intellijthemes/Hiberbee.theme.json | 468 +++++++++--------- 1 file changed, 243 insertions(+), 225 deletions(-) diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json index 4ec97633..66ed770d 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json @@ -1,17 +1,29 @@ { "author": "Vlad Volkov", "colors": { - "border": "#434343", - "focused": "#5a5a5a", - "separator": "#434343", - "background": "#191919", - "paneBackground": "#252525", - "lightBackground": "#323232", - "headerBackground": "#3c3c3c", - "darkerForeground": "#7d7d7d", - "foreground": "#c8c8c8", - "shadow": "#252525", - "accent": "#FFC83C" + "accent": "#FFC83C", + "greyDot15": "#d8d8d8", + "greyDot25": "#bfbfbf", + "greyDot33": "#aaaaaa", + "greyDot50": "#7d7d7d", + "greyDot65": "#5a5a5a", + "greyDot70": "#4d4d4d", + "greyDot75": "#434343", + "greyDot80": "#323232", + "greyDot85": "#252525", + "greyDot90": "#191919", + "navyDot85": "#191d21", + "navyDot90": "#1f2021", + "lightBlue": "#90dae6", + "green": "#5B8021", + "red": "#800040", + "desaturatedBlue": "#1e282d", + "desaturatedOrange": "#8049117f", + "transparentGreen": "#5B80217f", + "transparentRed": "#8000407f", + "transparentYellow": "#8066357f", + "transparentViolet": "#9478F67f", + "yellow": "#806635" }, "dark": true, "editorScheme": "/Hiberbee.xml", @@ -31,7 +43,7 @@ "Objects.Yellow": "#f7cd46", "Objects.Green": "#78b756", "Objects.Purple": "#9478f6", - "Objects.BlackText": "#4b4b4b", + "Objects.BlackText": "#4d4d4d", "Objects.Blue": "#49b0f1", "Objects.YellowDark": "#fd971f", "Objects.GreenAndroid": "#78c856" @@ -39,76 +51,78 @@ }, "name": "Hiberbee", "ui": { - "ActionButton.hoverBackground": "separator", - "ActionButton.hoverBorderColor": "focused", - "ActionButton.pressedBackground": "focused", - "Borders.ContrastBorderColor": "separator", - "Borders.color": "border", + "ActionButton.hoverBackground": "greyDot65", + "ActionButton.hoverBorderColor": "greyDot50", + "ActionButton.pressedBackground": "greyDot65", + "Borders.ContrastBorderColor": "greyDot65", + "ActionButton.pressedBorderColor": "lightBlue", + "Borders.color": "greyDot65", "Button.arc": "5", - "Button.background": "lightBackground", - "Button.default.endBackground": "lightBackground", - "Button.default.endBorderColor": "border", - "Button.default.focusColor": "headerBackground", - "Button.default.focusedBorderColor": "accent", - "Button.default.foreground": "accent", - "Button.default.shadowColor": "shadow", - "Button.default.startBackground": "lightBackground", - "Button.default.startBorderColor": "border", - "Button.endBackground": "lightBackground", - "Button.endBorderColor": "border", + "Button.background": "greyDot80", + "Button.default.endBackground": "greyDot80", + "Button.default.endBorderColor": "greyDot65", + "Button.default.startBorderColor": "greyDot65", + "Button.default.focusColor": "greyDot50", + "Button.default.focusedBorderColor": "lightBlue", + "Button.default.foreground": "greyDot25", + "Button.default.shadowColor": "navyDot90", + "Button.default.startBackground": "greyDot80", + "Button.endBackground": "greyDot80", + "Button.startBorderColor": "greyDot65", + "Button.endBorderColor": "greyDot65", "Button.focusedBorderColor": "accent", - "Button.foreground": "foreground", - "Button.shadowColor": "shadow", + "Button.foreground": "greyDot25", + "Button.shadowColor": "navyDot90", "Button.shadowWidth": "0", - "Button.startBackground": "lightBackground", - "Button.startBorderColor": "border", - "CheckBox.background": "lightBackground", - "CheckBoxMenuItem.background": "lightBackground", - "CheckBoxMenuItem.disabledBackground": "darkBackground", + "Button.startBackground": "greyDot80", + "CheckBox.background": "greyDot80", + "CheckBoxMenuItem.background": "greyDot80", + "CheckBoxMenuItem.disabledBackground": "greyDot85", "CheckBoxMenuItem.selectionForeground": "accent", - "ComboBox.ArrowButton.disabledIconColor": "separator", + "ComboBox.ArrowButton.disabledIconColor": "greyDot50", "ComboBox.ArrowButton.iconColor": "accent", - "ComboBox.ArrowButton.nonEditableBackground": "separator", - "ComboBox.background": "lightBackground", + "ComboBox.ArrowButton.nonEditableBackground": "greyDot70", + "ComboBox.background": "greyDot80", "ComboBox.modifiedItemForeground": "accent", - "ComboBox.nonEditableBackground": "headerBackground", - "ComboPopup.border": "0,0,0,0,4b4b4b", - "CompletionPopup.foreground": "foreground", + "ComboBox.nonEditableBackground": "greyDot75", + "ComboPopup.border": "1,1,1,1,5a5a5a", + "CompletionPopup.foreground": "greyDot25", "CompletionPopup.matchForeground": "accent", - "CompletionPopup.selectionBackground": "separator", - "CompletionPopup.selectionInactiveBackground": "lightBackground", + "CompletionPopup.selectionBackground": "navyDot85", + "CompletionPopup.selectionInactiveBackground": "greyDot80", "Component.arc": "5", - "Component.borderColor": "focused", - "Component.errorFocusColor": "#501428", - "Component.focusColor": "#595959", + "Component.borderColor": "greyDot65", + "Component.errorFocusColor": "red", + "Component.focusColor": "accent", "Component.focusWidth": "0", - "Component.focusedBorderColor": "#666666", - "Component.hoverIconColor": "foreground", - "Component.iconColor": "accent", - "Component.inactiveErrorFocusColor": "#3c0a14", - "Component.inactiveWarningFocusColor": "#4b3219", - "Component.warningFocusColor": "#966432", - "Counter.background": "lightBackground", - "Counter.foreground": "foreground", - "Debugger.Variables.evaluatingExpressionForeground": "#6782cd", - "Debugger.Variables.changedValueForeground": "#F9D778", - "DebuggerPopup.borderColor": "border", - "DefaultTabs.background": "lightBackground", - "DefaultTabs.hoverBackground": "#191C21", + "Component.focusedBorderColor": "greyDot50", + "Component.hoverIconColor": "accent", + "Component.iconColor": "lightBlue", + "Component.inactiveErrorFocusColor": "transparentRed", + "Component.inactiveWarningFocusColor": "transparentYellow", + "Component.warningFocusColor": "yellow", + "Counter.background": "greyDot80", + "Counter.foreground": "greyDot25", + "Debugger.Variables.changedValueForeground": "accent", + "Debugger.Variables.evaluatingExpressionForeground": "lightBlue", + "DebuggerPopup.borderColor": "greyDot65", + "DefaultTabs.background": "greyDot80", + "DefaultTabs.borderColor": "greyDot65", + "DefaultTabs.hoverBackground": "navyDot85", "DefaultTabs.underlineColor": "accent", "DefaultTabs.underlineHeight": 1, - "DefaultTabs.underlinedTabBackground": "border", - "DefaultTabs.underlinedTabForeground": "accent", - "DragAndDrop.areaBackground": "#666666", - "DragAndDrop.areaForeground": "foreground", - "Editor.background": "background", - "Editor.foreground": "foreground", - "EditorPane.background": "lightBackground", + "DefaultTabs.underlinedTabBackground": "greyDot75", + "DefaultTabs.underlinedTabForeground": "lightBlue", + "DragAndDrop.areaBackground": "greyDot75", + "DragAndDrop.areaForeground": "greyDot25", + "Editor.background": "greyDot90", + "Editor.foreground": "greyDot25", + "EditorPane.background": "greyDot80", "EditorPane.caretForeground": "accent", - "EditorPane.foreground": "foreground", - "EditorPane.inactiveBackground": "paneBackground", - "EditorPane.inactiveForeground": "#808080", - "EditorPane.selectionBackground": "#191C21", + "EditorPane.foreground": "greyDot25", + "EditorPane.inactiveBackground": "greyDot85", + "EditorPane.inactiveForeground": "greyDot50", + "EditorPane.selectionBackground": "navyDot85", "EditorPane.selectionForeground": "accent", "EditorTabs.underlineHeight": 1, "FileColor.Blue": "#23282d", @@ -117,188 +131,192 @@ "FileColor.Rose": "#2d2323", "FileColor.Violet": "#2D232D", "FileColor.Yellow": "#2d2d23", - "GutterTooltip.infoForeground": "darkerForeground", - "InplaceRefactoringPopup.borderColor": "focused", - "Label.background": "lightBackground", - "Link.activeForeground": "#7da5f0", + "GutterTooltip.infoForeground": "greyDot50", + "InplaceRefactoringPopup.borderColor": "lightBlue", + "Label.background": "greyDot80", + "Link.activeForeground": "lightBlue", "Link.hoverForeground": "accent", - "Link.pressedForeground": "#6782cd", - "Link.visitedForeground": "foreground", - "List.background": "lightBackground", - "List.selectionBackground": "#23262B", + "Link.pressedForeground": "lightBlue", + "Link.visitedForeground": "greyDot25", + "List.background": "greyDot80", + "List.selectionBackground": "navyDot85", "List.selectionForeground": "accent", - "MemoryIndicator.allocatedBackground": "#0a3c14", - "MemoryIndicator.usedBackground": "#320a19", - "Menu.acceleratorForeground": "foreground", + "MemoryIndicator.allocatedBackground": "green", + "MemoryIndicator.usedBackground": "red", + "Menu.acceleratorForeground": "greyDot25", "Menu.acceleratorSelectionForeground": "accent", - "Menu.background": "lightBackground", - "Menu.foreground": "foreground", + "Menu.background": "greyDot80", + "Menu.borderColor": "greyDot65", + "Menu.foreground": "greyDot25", "Menu.selectionForeground": "accent", - "Menu.separatorColor": "separator", - "MenuBar.selectionBackground": "focused", - "MenuBar.shadow": "shadow", + "Menu.separatorColor": "greyDot65", + "MenuBar.borderColor": "greyDot65", + "MenuBar.selectionBackground": "navyDot85", + "MenuBar.shadow": "navyDot90", "MenuItem.selectionForeground": "accent", - "Notification.MoreButton.background": "paneBackground", - "Notification.MoreButton.innerBorderColor": "separator", - "Notification.ToolWindow.errorBackground": "#37160b", - "Notification.ToolWindow.errorBorderColor": "#ed6b88", - "Notification.ToolWindow.errorForeground": "#e1e1e1", - "Notification.ToolWindow.informativeBackground": "#3c5014", - "Notification.ToolWindow.informativeBorderColor": "#556914", - "Notification.ToolWindow.informativeForeground": "darkerForeground", - "Notification.ToolWindow.warningBackground": "#372c0b", - "Notification.ToolWindow.warningBorderColor": "accent", - "Notification.ToolWindow.warningForeground": "#e1e1e1", - "Notification.background": "paneBackground", - "Notification.errorBackground": "#37160b", - "Notification.errorBorderColor": "#ed6b88", - "Notification.errorForeground": "foreground", - "Notification.foreground": "foreground", - "OptionPane.background": "lightBackground", - "OptionPane.foreground": "foreground", - "Panel.background": "lightBackground", - "Panel.foreground": "foreground", - "ParameterInfo.background": "paneBackground", - "ParameterInfo.currentOverloadBackground": "foreground", + "Notification.MoreButton.background": "greyDot85", + "Notification.MoreButton.innerBorderColor": "greyDot65", + "Notification.ToolWindow.errorBackground": "red", + "Notification.ToolWindow.errorBorderColor": "greyDot50", + "Notification.ToolWindow.errorForeground": "greyDot15", + "Notification.ToolWindow.informativeBackground": "#304000", + "Notification.ToolWindow.informativeBorderColor": "greyDot65", + "Notification.ToolWindow.informativeForeground": "greyDot15", + "Notification.ToolWindow.warningBackground": "yellow", + "Notification.ToolWindow.warningBorderColor": "greyDot65", + "Notification.ToolWindow.warningForeground": "greyDot15", + "Notification.background": "greyDot85", + "Notification.errorBackground": "red", + "Notification.errorBorderColor": "greyDot65", + "Notification.errorForeground": "greyDot15", + "Notification.foreground": "greyDot25", + "OptionPane.background": "greyDot80", + "OptionPane.foreground": "greyDot25", + "Panel.background": "greyDot80", + "Panel.foreground": "greyDot25", + "ParameterInfo.background": "greyDot85", + "ParameterInfo.currentOverloadBackground": "lightBlue", "ParameterInfo.currentParameterForeground": "accent", - "ParameterInfo.foreground": "foreground", - "ParameterInfo.infoForeground": "darkerForeground", - "ParameterInfo.lineSeparatorColor": "separator", - "Plugins.Button.installBackground": "lightBackground", - "Plugins.Button.installBorderColor": "border", - "Plugins.Button.installFillBackground": "lightBackground", - "Plugins.Button.installFillForeground": "foreground", + "ParameterInfo.foreground": "greyDot25", + "ParameterInfo.infoForeground": "greyDot33", + "ParameterInfo.lineSeparatorColor": "greyDot70", + "Plugins.Button.installBackground": "greyDot80", + "Plugins.Button.installBorderColor": "greyDot65", + "Plugins.Button.installFillBackground": "greyDot80", + "Plugins.Button.installFillForeground": "greyDot25", "Plugins.Button.installForeground": "accent", - "Plugins.SearchField.background": "headerBackground", - "Plugins.SectionHeader.background": "headerBackground", - "Plugins.SectionHeader.foreground": "foreground", - "Plugins.Tab.hoverBackground": "paneBackground", - "Plugins.Tab.selectedBackground": "#191C21", - "Plugins.background": "lightBackground", - "Plugins.disabledForeground": "darkerForeground", - "Plugins.lightSelectionBackground": "separator", - "Plugins.tagBackground": "paneBackground", - "Plugins.tagForeground": "foreground", - "Popup.Advertiser.background": "paneBackground", - "Popup.Advertiser.foreground": "darkerForeground", - "Popup.Header.activeBackground": "headerBackground", - "Popup.Header.inactiveBackground": "paneBackground", - "Popup.paintBorder": false, - "PopupMenu.background": "lightBackground", - "PopupMenu.foreground": "foreground", - "PopupMenu.selectionBackground": "#191C21", - "PopupMenu.selectionForeground": "accent", + "Plugins.SearchField.background": "greyDot75", + "Plugins.SectionHeader.background": "greyDot75", + "Plugins.SectionHeader.foreground": "greyDot25", + "Plugins.Tab.hoverBackground": "navyDot85", + "Plugins.Tab.selectedBackground": "greyDot85", + "Plugins.background": "greyDot80", + "Plugins.disabledForeground": "greyDot50", + "Plugins.lightSelectionBackground": "greyDot70", + "Plugins.tagBackground": "greyDot85", + "Plugins.tagForeground": "greyDot25", + "Popup.Advertiser.background": "greyDot85", + "Popup.Advertiser.foreground": "greyDot50", + "Popup.Header.activeBackground": "greyDot75", + "Popup.Header.inactiveBackground": "greyDot85", + "Popup.paintBorder": true, + "PopupMenu.background": "greyDot80", + "PopupMenu.foreground": "greyDot25", + "PopupMenu.selectionBackground": "navyDot85", + "PopupMenu.selectionForeground": "lightBlue", "PopupMenuSeparator.stripeWidth": 1, - "ProgressBar.failedColor": "#ec5f5d", - "ProgressBar.failedEndColor": "#ffa9ca", - "ProgressBar.indeterminateEndColor": "#f9d778", - "ProgressBar.indeterminateStartColor": "#ee9b70", - "ProgressBar.passedColor": "#78b756", - "ProgressBar.passedEndColor": "#b4da82", - "ProgressBar.progressColor": "#ffe499", + "ProgressBar.failedColor": "red", + "ProgressBar.failedEndColor": "greyDot65", + "ProgressBar.indeterminateEndColor": "greyDot25", + "ProgressBar.indeterminateStartColor": "accent", + "ProgressBar.passedColor": "green", + "ProgressBar.passedEndColor": "greyDot65", + "ProgressBar.progressColor": "accent", "ProgressBar.trackColor": "accent", - "RadioButton.background": "lightBackground", - "ScrollBar.Mac.hoverTrackColor": "headerBackground", - "Slider.background": "lightBackground", - "ScrollBar.Mac.trackColor": "lightBackground", - "ScrollPane.background": "paneBackground", - "ScrollPane.foreground": "darkerForeground", - "SearchEverywhere.Advertiser.background": "paneBackground", - "SearchEverywhere.Advertiser.foreground": "darkerForeground", - "SearchEverywhere.Header.background": "paneBackground", - "SearchEverywhere.List.separatorColor": "separator", - "SearchEverywhere.List.separatorForeground": "separator", - "SearchEverywhere.SearchField.background": "headerBackground", - "SearchEverywhere.SearchField.borderColor": "border", - "SearchEverywhere.SearchField.infoForeground": "darkerForeground", - "SearchEverywhere.Tab.selectedBackground": "separator", + "RadioButton.background": "greyDot75", + "ScrollBar.Mac.hoverTrackColor": "greyDot75", + "ScrollBar.Mac.trackColor": "greyDot75", + "ScrollPane.background": "greyDot85", + "ScrollPane.foreground": "greyDot25", + "SearchEverywhere.Advertiser.background": "greyDot85", + "SearchEverywhere.Advertiser.foreground": "greyDot33", + "SearchEverywhere.Header.background": "greyDot85", + "SearchEverywhere.List.separatorColor": "greyDot70", + "SearchEverywhere.List.separatorForeground": "greyDot70", + "SearchEverywhere.SearchField.background": "greyDot75", + "SearchEverywhere.SearchField.borderColor": "greyDot70", + "SearchEverywhere.SearchField.infoForeground": "greyDot50", + "SearchEverywhere.Tab.selectedBackground": "greyDot70", "SearchEverywhere.Tab.selectedForeground": "accent", "SearchMatch.endBackground": "accent", "SearchMatch.startBackground": "accent", - "Separator.separatorColor": "separator", - "SidePanel.background": "paneBackground", - "Slider.focus": "focused", - "SpeedSearch.background": "lightBackground", - "SpeedSearch.borderColor": "border", - "SpeedSearch.errorForeground": "#ed6b88", + "Separator.separatorColor": "greyDot70", + "SidePanel.background": "greyDot85", + "Slider.background": "greyDot80", + "Slider.focus": "greyDot65", + "SpeedSearch.background": "greyDot80", + "SpeedSearch.borderColor": "greyDot70", + "SpeedSearch.errorForeground": "red", "SpeedSearch.foreground": "accent", - "SplitPane.background": "lightBackground", - "SplitPane.darkShadow": "shadow", + "SplitPane.background": "greyDot80", + "SplitPane.darkShadow": "navyDot90", "SplitPane.highlight": "accent", - "SplitPane.shadow": "shadow", - "TabbedPane.background": "lightBackground", - "TabbedPane.contentAreaColor": "lightBackground", - "TabbedPane.disabledUnderlineColor": "border", - "TabbedPane.focusColor": "focused", - "TabbedPane.foreground": "foreground", - "TabbedPane.hoverColor": "separator", + "SplitPane.shadow": "navyDot90", + "TabbedPane.background": "greyDot80", + "TabbedPane.contentAreaColor": "greyDot80", + "TabbedPane.disabledUnderlineColor": "greyDot75", + "TabbedPane.focusColor": "greyDot65", + "TabbedPane.foreground": "greyDot25", + "TabbedPane.hoverColor": "navyDot85", "TabbedPane.tabSelectionHeight": 1, "TabbedPane.underlineColor": "accent", - "Table.background": "lightBackground", - "Table.dropLineColor": "border", - "Table.dropLineShortColor": "separator", + "Table.background": "greyDot80", + "Table.dropLineColor": "greyDot75", + "Table.dropLineShortColor": "greyDot70", "Table.focusCellForeground": "accent", - "Table.selectionBackground": "#191C21", + "Table.selectionBackground": "navyDot85", "Table.selectionForeground": "accent", "Table.sortIconColor": "accent", - "Table.stripeColor": "border", - "TableHeader.background": "paneBackground", - "TableHeader.bottomSeparatorColor": "border", - "TableHeader.separatorColor": "separator", - "TextArea.background": "paneBackground", + "Table.stripeColor": "greyDot75", + "TableHeader.background": "greyDot85", + "TableHeader.bottomSeparatorColor": "greyDot75", + "TableHeader.separatorColor": "greyDot70", + "TextArea.background": "greyDot85", "TextArea.caretForeground": "accent", - "TextArea.foreground": "foreground", - "TextArea.selectionBackground": "#191C21", - "TextField.background": "headerBackground", + "TextArea.foreground": "greyDot25", + "TextArea.selectionBackground": "navyDot85", + "TextField.background": "greyDot75", "TextField.caretForeground": "accent", - "TextField.darkShadow": "shadow", - "TextField.foreground": "foreground", - "TextField.highlight": "#ffffff", - "TextField.selectionBackground": "#191C21", - "TextPane.background": "lightBackground", - "TitlePane.background": "paneBackground", - "ToggleButton.borderColor": "separator", - "ToggleButton.buttonColor": "headerBackground", - "ToggleButton.offBackground": "#232323", - "ToggleButton.offForeground": "darkerForeground", - "ToggleButton.onBackground": "focused", + "TextField.darkShadow": "navyDot90", + "TextField.foreground": "greyDot25", + "TextField.highlight": "greyDot15", + "TextField.selectionBackground": "navyDot85", + "TextPane.background": "greyDot80", + "TitlePane.background": "greyDot85", + "ToggleButton.borderColor": "greyDot70", + "ToggleButton.buttonColor": "greyDot75", + "ToggleButton.offBackground": "greyDot75", + "ToggleButton.offForeground": "greyDot25", + "ToggleButton.onBackground": "greyDot50", "ToggleButton.onForeground": "accent", - "ToolBar.background": "lightBackground", - "ToolBar.borderHandleColor": "separator", - "ToolBar.shadow": "shadow", - "ToolTip.Actions.background": "lightBackground", - "ToolTip.Actions.infoForeground": "darkerForeground", - "ToolTip.background": "headerBackground", - "ToolTip.foreground": "foreground", - "ToolTip.infoForeground": "darkerForeground", - "ToolWindow.Button.hoverBackground": "focused", - "ToolWindow.Button.selectedBackground": "separator", + "ToolBar.background": "greyDot80", + "ToolBar.borderHandleColor": "greyDot70", + "ToolBar.darkShadow": "navyDot90", + "ToolBar.shadow": "navyDot90", + "ToolTip.Actions.background": "greyDot80", + "ToolTip.Actions.infoForeground": "greyDot50", + "ToolTip.background": "greyDot75", + "ToolTip.foreground": "greyDot25", + "ToolTip.infoForeground": "greyDot50", + "ToolWindow.Button.hoverBackground": "navyDot85", + "ToolWindow.Button.selectedBackground": "greyDot70", "ToolWindow.Button.selectedForeground": "accent", - "ToolWindow.Header.background": "paneBackground", - "ToolWindow.Header.inactiveBackground": "lightBackground", - "ToolWindow.HeaderTab.hoverBackground": "border", - "ToolWindow.HeaderTab.hoverInactiveBackground": "headerBackground", - "ToolWindow.HeaderTab.inactiveUnderlineColor": "border", - "ToolWindow.HeaderTab.selectedInactiveBackground": "headerBackground", + "ToolWindow.Header.background": "greyDot85", + "ToolWindow.Header.inactiveBackground": "greyDot80", + "ToolWindow.HeaderTab.hoverBackground": "navyDot85", + "ToolWindow.HeaderTab.hoverInactiveBackground": "navyDot90", + "ToolWindow.HeaderTab.inactiveUnderlineColor": "greyDot75", + "ToolWindow.HeaderTab.selectedInactiveBackground": "greyDot80", "ToolWindow.HeaderTab.underlineColor": "accent", "ToolWindow.HeaderTab.underlineHeight": 1, - "ToolWindow.HeaderTab.underlinedTabInactiveBackground": "border", - "Tree.background": "paneBackground", + "ToolWindow.HeaderTab.underlinedTabInactiveBackground": "greyDot75", + "Tree.background": "greyDot85", "Tree.modifiedItemForeground": "accent", "Tree.paintLines": 0, - "Tree.selectionBackground": "#191C21", + "Tree.rowHeight": 20, + "Tree.selectionBackground": "navyDot85", "Tree.selectionForeground": "accent", - "Tree.selectionInactiveBackground": "#191C217f", - "ValidationTooltip.errorBackground": "#261313", - "ValidationTooltip.errorBorderColor": "#ff0072", - "ValidationTooltip.warningBackground": "#372c0b", - "ValidationTooltip.warningBorderColor": "accent", - "VersionControl.FileHistory.Commit.selectedBranchBackground": "separator", - "VersionControl.Log.Commit.currentBranchBackground": "#232323", - "VersionControl.Log.Commit.unmatchedForeground": "foreground", - "WelcomeScreen.Projects.selectionBackground": "#191C21", - "WelcomeScreen.Projects.selectionInactiveBackground": "#191C217f", - "WelcomeScreen.separatorColor": "separator", - "Window.border": "1,1,1,1,4b4b4b" + "Tree.selectionInactiveBackground": "navyDot90", + "ValidationTooltip.errorBackground": "red", + "ValidationTooltip.errorBorderColor": "greyDot65", + "ValidationTooltip.warningBackground": "#805e00", + "ValidationTooltip.warningBorderColor": "greyDot65", + "VersionControl.FileHistory.Commit.selectedBranchBackground": "greyDot70", + "VersionControl.Log.Commit.currentBranchBackground": "greyDot85", + "VersionControl.Log.Commit.unmatchedForeground": "greyDot25", + "WelcomeScreen.Projects.selectionBackground": "navyDot85", + "WelcomeScreen.Projects.selectionInactiveBackground": "navyDot90", + "WelcomeScreen.separatorColor": "greyDot65", + "Window.border": "0,0,0,0,5a5a5a" } } From d0029beb2266fa843088d120595150d9f1d1e1ff Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 10:48:15 +0100 Subject: [PATCH 02/46] use 0.5 pixel "inner" focus border for "Flat Light" and "Flat Dark" themes --- .../com/formdev/flatlaf/UIDefaultsLoader.java | 23 +++++++++++++++++-- .../com/formdev/flatlaf/ui/FlatBorder.java | 6 ++--- .../com/formdev/flatlaf/ui/FlatUIUtils.java | 5 ++++ .../com/formdev/flatlaf/FlatLaf.properties | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java index a1901142..fc79c8cf 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java @@ -212,7 +212,7 @@ class UIDefaultsLoader return resolveValue( properties, newValue ); } - private enum ValueType { UNKNOWN, STRING, INTEGER, BORDER, ICON, INSETS, DIMENSION, COLOR, SCALEDINTEGER, INSTANCE, CLASS } + private enum ValueType { UNKNOWN, STRING, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, SCALEDINTEGER, INSTANCE, CLASS } static Object parseValue( String key, String value ) { return parseValue( key, value, v -> v, Collections.emptyList() ); @@ -242,7 +242,10 @@ class UIDefaultsLoader // check whether value type is specified in the value if( value.startsWith( "#" ) ) valueType = ValueType.COLOR; - else if( value.startsWith( TYPE_PREFIX ) ) { + else if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) { + valueType = ValueType.STRING; + value = value.substring( 1, value.length() - 1 ); + } else if( value.startsWith( TYPE_PREFIX ) ) { int end = value.indexOf( TYPE_PREFIX_END ); if( end != -1 ) { try { @@ -280,6 +283,7 @@ class UIDefaultsLoader switch( valueType ) { case STRING: return value; case INTEGER: return parseInteger( value, true ); + case FLOAT: return parseFloat( value, true ); case BORDER: return parseBorder( value, resolver, addonClassLoaders ); case ICON: return parseInstance( value, addonClassLoaders ); case INSETS: return parseInsets( value ); @@ -300,6 +304,11 @@ class UIDefaultsLoader if( integer != null ) return integer; + // float + Float f = parseFloat( value, false ); + if( f != null ) + return f; + // string return value; } @@ -594,6 +603,16 @@ class UIDefaultsLoader return null; } + private static Float parseFloat( String value, boolean reportError ) { + try { + return Float.parseFloat( value ); + } catch( NumberFormatException ex ) { + if( reportError ) + throw new NumberFormatException( "invalid float '" + value + "'" ); + } + return null; + } + private static ActiveValue parseScaledInteger( String value ) { int val = parseInteger( value, true ); return (ActiveValue) t -> { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java index 1449eb2a..6d489d6e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java @@ -48,7 +48,7 @@ import javax.swing.text.JTextComponent; * {@link FlatUIUtils#paintParentBackground} to paint the empty space correctly. * * @uiDefault Component.focusWidth int - * @uiDefault Component.innerFocusWidth int + * @uiDefault Component.innerFocusWidth int or float * @uiDefault Component.focusColor Color * @uiDefault Component.borderColor Color * @uiDefault Component.disabledBorderColor Color @@ -60,7 +60,7 @@ public class FlatBorder extends BasicBorders.MarginBorder { protected final int focusWidth = UIManager.getInt( "Component.focusWidth" ); - protected final int innerFocusWidth = UIManager.getInt( "Component.innerFocusWidth" ); + protected final float innerFocusWidth = FlatUIUtils.getUIFloat( "Component.innerFocusWidth", 0 ); protected final Color focusColor = UIManager.getColor( "Component.focusColor" ); protected final Color borderColor = UIManager.getColor( "Component.borderColor" ); protected final Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); @@ -80,7 +80,7 @@ public class FlatBorder if( isFocused( c ) ) { g2.setColor( getFocusColor( c ) ); FlatUIUtils.paintComponentOuterBorder( g2, x, y, width, height, focusWidth, - getLineWidth() + scale( (float) innerFocusWidth ), arc ); + getLineWidth() + scale( innerFocusWidth ), arc ); } g2.setPaint( getBorderColor( c ) ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 386cac0a..13f8d2d3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -102,6 +102,11 @@ public class FlatUIUtils return (value instanceof Integer) ? (Integer) value : defaultValue; } + public static float getUIFloat( String key, float defaultValue ) { + Object value = UIManager.get( key ); + return (value instanceof Number) ? ((Number)value).floatValue() : defaultValue; + } + public static Color nonUIResource( Color c ) { return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c; } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index c4f72247..954275db 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -137,7 +137,7 @@ ComboBox.padding=2,6,2,6 #---- Component ---- Component.focusWidth=0 -Component.innerFocusWidth=0 +Component.innerFocusWidth={float}0.5 Component.arc=5 Component.minimumWidth=64 Component.arrowType=chevron From 269075657d978099f1dc82d4c2b1819f18a5d4dc Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 11:02:40 +0100 Subject: [PATCH 03/46] FlatDefaultsAddon: added default implementation to `getDefaults()` because most subclasses use the same implementation --- .../com/formdev/flatlaf/FlatDefaultsAddon.java | 16 +++++++++++++--- .../jideoss/FlatJideOssDefaultsAddon.java | 5 +---- .../flatlaf/swingx/FlatSwingXDefaultsAddon.java | 15 +++------------ .../swingx/FlatSwingXDefaultsTestAddon.java | 15 +++------------ 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java index ef7c03d0..50a62554 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java @@ -23,11 +23,11 @@ import java.io.InputStream; * * Allows loading of additional .properties files from addon JARs. * {@link java.util.ServiceLoader} is used to load extensions of this class from addon JARs. - * + *

* If you extend this class in a addon JAR, you also have to add a text file named * {@code META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon} * to the addon JAR. The file must contain a single line with the class name. - * + *

* See 'flatlaf-swingx' addon for an example * * @author Karl Tauber @@ -37,6 +37,16 @@ public abstract class FlatDefaultsAddon /** * Finds an addon .properties file for the given LaF class and returns * it as input stream. Or {@code null} if not found. + *

+ * This default implementation finds addon .properties file for the given LaF class + * in the same package as the subclass. + *

+ * Override this method to load addon .properties files from other locations. */ - public abstract InputStream getDefaults( Class lafClass ); + public InputStream getDefaults( Class lafClass ) { + Class addonClass = this.getClass(); + String propertiesName = "/" + addonClass.getPackage().getName().replace( '.', '/' ) + + '/' + lafClass.getSimpleName() + ".properties"; + return addonClass.getResourceAsStream( propertiesName ); + } } diff --git a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java index 1f2902a9..bcbf8169 100644 --- a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java +++ b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java @@ -43,10 +43,7 @@ public class FlatJideOssDefaultsAddon LookAndFeelFactory.registerDefaultInitializer( FlatLaf.class.getName(), FlatJideUIDefaultsCustomizer.class.getName() ); LookAndFeelFactory.registerDefaultCustomizer( FlatLaf.class.getName(), FlatJideUIDefaultsCustomizer.class.getName() ); - Class addonClass = this.getClass(); - String propertiesName = "/" + addonClass.getPackage().getName().replace( '.', '/' ) - + '/' + lafClass.getSimpleName() + ".properties"; - return addonClass.getResourceAsStream( propertiesName ); + return super.getDefaults( lafClass ); } //---- class FlatJideUIDefaultsCustomizer --------------------------------- diff --git a/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java b/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java index e17f121a..b26894bb 100644 --- a/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java +++ b/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java @@ -16,26 +16,17 @@ package com.formdev.flatlaf.swingx; -import java.io.InputStream; import com.formdev.flatlaf.FlatDefaultsAddon; /** * SwingX addon for FlatLaf. + *

+ * Finds SwingX addon .properties file for the given LaF class + * in the same package as this class. * * @author Karl Tauber */ public class FlatSwingXDefaultsAddon extends FlatDefaultsAddon { - /** - * Finds SwingX addon .properties file for the given LaF class - * in the same package as this class. - */ - @Override - public InputStream getDefaults( Class lafClass ) { - Class addonClass = this.getClass(); - String propertiesName = "/" + addonClass.getPackage().getName().replace( '.', '/' ) - + '/' + lafClass.getSimpleName() + ".properties"; - return addonClass.getResourceAsStream( propertiesName ); - } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/swingx/FlatSwingXDefaultsTestAddon.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/swingx/FlatSwingXDefaultsTestAddon.java index 3ce87f7d..784afc9a 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/swingx/FlatSwingXDefaultsTestAddon.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/swingx/FlatSwingXDefaultsTestAddon.java @@ -16,26 +16,17 @@ package com.formdev.flatlaf.testing.swingx; -import java.io.InputStream; import com.formdev.flatlaf.FlatDefaultsAddon; /** * SwingX addon for FlatLaf for testing. + *

+ * Finds SwingX addon .properties file for the given LaF class + * in the same package as this class. * * @author Karl Tauber */ public class FlatSwingXDefaultsTestAddon extends FlatDefaultsAddon { - /** - * Finds SwingX addon .properties file for the given LaF class - * in the same package as this class. - */ - @Override - public InputStream getDefaults( Class lafClass ) { - Class addonClass = this.getClass(); - String propertiesName = "/" + addonClass.getPackage().getName().replace( '.', '/' ) - + '/' + lafClass.getSimpleName() + ".properties"; - return addonClass.getResourceAsStream( propertiesName ); - } } From 9c470d77cb07c147aa8c65a47c27c80ba89c8361 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 16:31:51 +0100 Subject: [PATCH 04/46] List and Tree: Hide cell focus indicator (black rectangle) by default. Can be enabled with `List.showCellFocusIndicator=true` / `Tree.showCellFocusIndicator=true`, but then the cell focus indicator is shown only if more than one item is selected. Table: Hide cell focus indicator (black rectangle) by default if none of the selected cells is editable. Can be show always with `Table.showCellFocusIndicator=true`. --- CHANGELOG.md | 11 +- .../flatlaf/ui/FlatListCellBorder.java | 24 +++- .../com/formdev/flatlaf/ui/FlatListUI.java | 1 + .../flatlaf/ui/FlatTableCellBorder.java | 115 ++++++++++++++++++ .../com/formdev/flatlaf/ui/FlatTableUI.java | 16 ++- .../com/formdev/flatlaf/ui/FlatTreeUI.java | 14 ++- .../com/formdev/flatlaf/FlatLaf.properties | 7 +- 7 files changed, 169 insertions(+), 19 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java diff --git a/CHANGELOG.md b/CHANGELOG.md index efcfcac3..aa4d2337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,17 @@ FlatLaf Change Log ## Unreleased - Updated colors in "Flat Light" and "Flat IntelliJ" themes with colors from - "IntelliJ Light Theme", which provides blue coloring that better match + "IntelliJ Light Theme", which provides blue coloring that better matches platform colors. - Tree: Support wide selection (enabled by default). - Table: Hide grid and changed intercell spacing to zero. -- List and Tree: Paint cell focus indicator (black rectangle) only if more than - one item is selected. +- List and Tree: Hide cell focus indicator (black rectangle) by default. Can be + enabled with `List.showCellFocusIndicator=true` / + `Tree.showCellFocusIndicator=true`, but then the cell focus indicator is shown + only if more than one item is selected. +- Table: Hide cell focus indicator (black rectangle) by default if none of the + selected cells is editable. Can be show always with + `Table.showCellFocusIndicator=true`. - Support basic color functions in `.properties` files: `rgb(red,green,blue)`, `rgba(red,green,blue,alpha)`, `hsl(hue,saturation,lightness)`, `hsla(hue,saturation,lightness,alpha)`, `lighten(color,amount[,options])` and diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java index 823a448a..16d3a23d 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java @@ -23,8 +23,9 @@ import javax.swing.SwingUtilities; import javax.swing.UIManager; /** - * Cell border for {@link javax.swing.DefaultListCellRenderer}. - * + * Cell border for {@link javax.swing.DefaultListCellRenderer} + * (used by {@link javax.swing.JList}). + *

* Uses separate cell margins from UI defaults to allow easy customizing. * * @author Karl Tauber @@ -32,23 +33,31 @@ import javax.swing.UIManager; public class FlatListCellBorder extends FlatLineBorder { + final boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" ); + protected FlatListCellBorder() { super( UIManager.getInsets( "List.cellMargins" ), UIManager.getColor( "List.cellFocusColor" ) ); } //---- class Default ------------------------------------------------------ + /** + * Border for unselected cell that uses margins, but does not paint focus indicator border. + */ public static class Default extends FlatListCellBorder { @Override public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { - // do not paint border + // do not paint focus indicator border } } //---- class Focused ------------------------------------------------------ + /** + * Border for focused unselected cell that uses margins and paints focus indicator border. + */ public static class Focused extends FlatListCellBorder { @@ -56,12 +65,19 @@ public class FlatListCellBorder //---- class Selected ----------------------------------------------------- + /** + * Border for selected cell that uses margins and paints focus indicator border + * if enabled (List.showCellFocusIndicator=true) and exactly one item is selected. + */ public static class Selected extends FlatListCellBorder { @Override public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { - // paint border only if exactly one item is selected + if( !showCellFocusIndicator ) + return; + + // paint focus indicator border only if exactly one item is selected JList list = (JList) SwingUtilities.getAncestorOfClass( JList.class, c ); if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() ) return; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java index c5efd11f..329eca2b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java @@ -56,6 +56,7 @@ import javax.swing.plaf.basic.BasicListUI; * * @uiDefault List.cellMargins Insets * @uiDefault List.cellFocusColor Color + * @uiDefault List.showCellFocusIndicator boolean * * @author Karl Tauber */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java new file mode 100644 index 00000000..05669edf --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java @@ -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.Graphics; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/** + * Cell border for {@link javax.swing.table.DefaultTableCellRenderer} + * (used by {@link javax.swing.JTable}). + *

+ * Uses separate cell margins from UI defaults to allow easy customizing. + * + * @author Karl Tauber + */ +public class FlatTableCellBorder + extends FlatLineBorder +{ + final boolean showCellFocusIndicator = UIManager.getBoolean( "Table.showCellFocusIndicator" ); + + protected FlatTableCellBorder() { + super( UIManager.getInsets( "Table.cellMargins" ), UIManager.getColor( "Table.cellFocusColor" ) ); + } + + //---- class Default ------------------------------------------------------ + + /** + * Border for unselected cell that uses margins, but does not paint focus indicator border. + */ + public static class Default + extends FlatTableCellBorder + { + @Override + public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { + // do not paint focus indicator border + } + } + + //---- class Focused ------------------------------------------------------ + + /** + * Border for focused unselected cell that uses margins and paints focus indicator border. + */ + public static class Focused + extends FlatTableCellBorder + { + } + + //---- class Selected ----------------------------------------------------- + + /** + * Border for selected cell that uses margins and paints focus indicator border + * if enabled (Table.showCellFocusIndicator=true) or at least one selected cell is editable. + */ + public static class Selected + extends FlatTableCellBorder + { + @Override + public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { + if( !showCellFocusIndicator ) { + JTable table = (JTable) SwingUtilities.getAncestorOfClass( JTable.class, c ); + if( table != null && !isSelectionEditable( table ) ) + return; + } + + super.paintBorder( c, g, x, y, width, height ); + } + + /** + * Checks whether at least one selected cell is editable. + */ + private boolean isSelectionEditable( JTable table ) { + if( table.getRowSelectionAllowed() ) { + int columnCount = table.getColumnCount(); + int[] selectedRows = table.getSelectedRows(); + for( int selectedRow : selectedRows ) { + for( int column = 0; column < columnCount; column++ ) { + if( table.isCellEditable( selectedRow, column ) ) + return true; + } + } + } + + if( table.getColumnSelectionAllowed() ) { + int rowCount = table.getRowCount(); + int[] selectedColumns = table.getSelectedColumns(); + for( int selectedColumn : selectedColumns ) { + for( int row = 0; row < rowCount; row++ ) { + if( table.isCellEditable( row, selectedColumn ) ) + return true; + } + } + } + + return false; + } + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java index 27d9553a..3e7c31bb 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java @@ -55,11 +55,17 @@ import com.formdev.flatlaf.util.UIScale; * * * - * @uiDefault Table.rowHeight int - * @uiDefault Table.showGrid boolean - * @uiDefault Table.intercellSpacing Dimension - * @uiDefault Table.selectionInactiveBackground Color - * @uiDefault Table.selectionInactiveForeground Color + * @uiDefault Table.rowHeight int + * @uiDefault Table.showGrid boolean + * @uiDefault Table.intercellSpacing Dimension + * @uiDefault Table.selectionInactiveBackground Color + * @uiDefault Table.selectionInactiveForeground Color + * + * + * + * @uiDefault Table.cellMargins Insets + * @uiDefault Table.cellFocusColor Color + * @uiDefault Table.showCellFocusIndicator boolean * * @author Karl Tauber */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java index 57e719a3..59566495 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java @@ -83,6 +83,7 @@ import com.formdev.flatlaf.util.UIScale; * @uiDefault Tree.selectionInactiveBackground Color * @uiDefault Tree.selectionInactiveForeground Color * @uiDefault Tree.wideSelection boolean + * @uiDefault Tree.showCellFocusIndicator boolean * * @author Karl Tauber */ @@ -95,6 +96,7 @@ public class FlatTreeUI protected Color selectionInactiveForeground; protected Color selectionBorderColor; protected boolean wideSelection; + protected boolean showCellFocusIndicator; public static ComponentUI createUI( JComponent c ) { return new FlatTreeUI(); @@ -112,6 +114,7 @@ public class FlatTreeUI selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" ); selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" ); wideSelection = UIManager.getBoolean( "Tree.wideSelection" ); + showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" ); // scale int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 ); @@ -217,9 +220,7 @@ public class FlatTreeUI protected void paintRow( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf ) { - if( editingComponent != null && editingRow == row ) - return; - + boolean isEditing = (editingComponent != null && editingRow == row); boolean hasFocus = tree.hasFocus(); boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow()); boolean isSelected = tree.isRowSelected( row ); @@ -240,6 +241,9 @@ public class FlatTreeUI } } + if( isEditing ) + return; + // get renderer component Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree, path.getLastPathComponent(), isSelected, isExpanded, isLeaf, row, cellHasFocus ); @@ -262,10 +266,10 @@ public class FlatTreeUI rendererComponent.setForeground( selectionInactiveForeground ); } - // remove selection border if exactly one item is selected + // remove focus selection border if exactly one item is selected Color oldBorderSelectionColor = null; if( isSelected && hasFocus && - tree.getMinSelectionRow() == tree.getMaxSelectionRow() && + (!showCellFocusIndicator || tree.getMinSelectionRow() == tree.getMaxSelectionRow()) && rendererComponent instanceof DefaultTreeCellRenderer ) { DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent; diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 954275db..16426537 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -375,8 +375,11 @@ Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon Table.descendingSortIcon=com.formdev.flatlaf.icons.FlatDescendingSortIcon Table.sortIconColor=@icon -Table.cellNoFocusBorder=2,3,2,3 -Table.focusSelectedCellHighlightBorder=2,3,2,3,@cellFocusColor +Table.cellMargins=2,3,2,3 +Table.cellFocusColor=@cellFocusColor +Table.cellNoFocusBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Default +Table.focusCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Focused +Table.focusSelectedCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Selected Table.selectionInactiveBackground=@selectionInactiveBackground Table.selectionInactiveForeground=@selectionInactiveForeground Table.dropCellBackground=@dropCellBackground From d260001cbdf7155c10dc8bfc172a24623a033147 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 16:55:35 +0100 Subject: [PATCH 05/46] IntelliJ Themes Demo: fixed progress bar in Hiberbee theme --- .../com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json index 66ed770d..60b8c07c 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json @@ -212,7 +212,7 @@ "ProgressBar.passedColor": "green", "ProgressBar.passedEndColor": "greyDot65", "ProgressBar.progressColor": "accent", - "ProgressBar.trackColor": "accent", + "ProgressBar.trackColor": "greyDot65", "RadioButton.background": "greyDot75", "ScrollBar.Mac.hoverTrackColor": "greyDot75", "ScrollBar.Mac.trackColor": "greyDot75", From aac6bd1b7cf068110cf1a240025585f9f666a452 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 17:49:16 +0100 Subject: [PATCH 06/46] release 0.23 --- CHANGELOG.md | 2 +- README.md | 2 +- build.gradle.kts | 2 +- flatlaf-jide-oss/README.md | 2 +- flatlaf-swingx/README.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4d2337..df97f929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ FlatLaf Change Log ================== -## Unreleased +## 0.23 - Updated colors in "Flat Light" and "Flat IntelliJ" themes with colors from "IntelliJ Light Theme", which provides blue coloring that better matches diff --git a/README.md b/README.md index 048379c0..cac51d6d 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ build script: groupId: com.formdev artifactId: flatlaf - version: 0.22 + version: 0.23 Otherwise download `flatlaf-.jar` here: diff --git a/build.gradle.kts b/build.gradle.kts index ee87feea..27c34b48 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -version = "0.22" +version = "0.23" allprojects { repositories { diff --git a/flatlaf-jide-oss/README.md b/flatlaf-jide-oss/README.md index 5ffc94d5..e9a6facf 100644 --- a/flatlaf-jide-oss/README.md +++ b/flatlaf-jide-oss/README.md @@ -26,7 +26,7 @@ build script: groupId: com.formdev artifactId: flatlaf-jide-oss - version: 0.22 + version: 0.23 Otherwise download `flatlaf-jide-oss-.jar` here: diff --git a/flatlaf-swingx/README.md b/flatlaf-swingx/README.md index 84e29701..0cb636b8 100644 --- a/flatlaf-swingx/README.md +++ b/flatlaf-swingx/README.md @@ -33,7 +33,7 @@ build script: groupId: com.formdev artifactId: flatlaf-swingx - version: 0.22 + version: 0.23 Otherwise download `flatlaf-swingx-.jar` here: From b6fb06bc65a042d74f3c99efac11ad21edcddfca Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 30 Dec 2019 18:10:33 +0100 Subject: [PATCH 07/46] CHANGELOG.md: added some missing changes form 0.23 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df97f929..561ec991 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ FlatLaf Change Log platform colors. - Tree: Support wide selection (enabled by default). - Table: Hide grid and changed intercell spacing to zero. +- List, Table and Tree: Added colors for drag-and-drop. Added "enable drag and + drop" checkbox to Demo on "Data Components" tab. - List and Tree: Hide cell focus indicator (black rectangle) by default. Can be enabled with `List.showCellFocusIndicator=true` / `Tree.showCellFocusIndicator=true`, but then the cell focus indicator is shown @@ -23,6 +25,8 @@ FlatLaf Change Log - Fixed link color (in HTML text) and separator color in IntelliJ platform themes. - Use logging instead of printing errors to `System.err`. +- Updated IntelliJ Themes in demo to the latest versions. +- IntelliJ Themes: Fixed link and separator colors. ## 0.22 From 452452dcc93f4edd5b91ed0d59651b8caaa82440 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 31 Dec 2019 09:49:56 +0100 Subject: [PATCH 08/46] Tree: fixed wide selection if scrolled horizontally --- CHANGELOG.md | 5 ++ .../com/formdev/flatlaf/ui/FlatTreeUI.java | 2 +- .../flatlaf/demo/DataComponentsPanel.java | 27 +++++++++ .../flatlaf/demo/DataComponentsPanel.jfd | 56 ++++++++++++++++++- 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 561ec991..5ff0496d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ FlatLaf Change Log ================== +## Unreleased + +- Tree: Fixed wide selection if scrolled horizontally. + + ## 0.23 - Updated colors in "Flat Light" and "Flat IntelliJ" themes with colors from diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java index 59566495..141dd2a7 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java @@ -232,7 +232,7 @@ public class FlatTreeUI g.setColor( isDropRow ? UIManager.getColor( "Tree.dropCellBackground" ) : (hasFocus ? selectionBackground : selectionInactiveBackground) ); - g.fillRect( 0, bounds.y, clipBounds.width, bounds.height ); + g.fillRect( 0, bounds.y, tree.getWidth(), bounds.height ); // paint expand/collapse icon if( shouldPaintExpandControl( path, row, isExpanded, hasBeenExpanded, isLeaf ) ) { diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.java index c46a0622..48344b26 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.java @@ -21,6 +21,7 @@ import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import javax.swing.*; import javax.swing.table.*; +import javax.swing.tree.*; import net.miginfocom.swing.*; /** @@ -171,6 +172,32 @@ class DataComponentsPanel //---- tree1 ---- tree1.setShowsRootHandles(true); tree1.setEditable(true); + tree1.setModel(new DefaultTreeModel( + new DefaultMutableTreeNode("JTree") { + { + DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("colors"); + node1.add(new DefaultMutableTreeNode("blue")); + node1.add(new DefaultMutableTreeNode("violet")); + node1.add(new DefaultMutableTreeNode("red")); + node1.add(new DefaultMutableTreeNode("yellow")); + add(node1); + node1 = new DefaultMutableTreeNode("sports"); + node1.add(new DefaultMutableTreeNode("basketball")); + node1.add(new DefaultMutableTreeNode("soccer")); + node1.add(new DefaultMutableTreeNode("football")); + node1.add(new DefaultMutableTreeNode("hockey")); + add(node1); + node1 = new DefaultMutableTreeNode("food"); + node1.add(new DefaultMutableTreeNode("hot dogs")); + DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("pizza"); + node2.add(new DefaultMutableTreeNode("pizza aglio e olio")); + node2.add(new DefaultMutableTreeNode("pizza margherita bianca")); + node1.add(node2); + node1.add(new DefaultMutableTreeNode("ravioli")); + node1.add(new DefaultMutableTreeNode("bananas")); + add(node1); + } + })); scrollPane3.setViewportView(tree1); } add(scrollPane3, "cell 1 1,growx"); diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.jfd index 42599f18..1c263544 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.jfd +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DataComponentsPanel.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -89,6 +89,60 @@ new FormModel { name: "tree1" "showsRootHandles": true "editable": true + "model": new javax.swing.tree.DefaultTreeModel( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "JTree" + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "colors" + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "blue" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "violet" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "red" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "yellow" + } ) + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "sports" + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "basketball" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "soccer" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "football" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "hockey" + } ) + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "food" + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "hot dogs" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "pizza" + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "pizza aglio e olio" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "pizza margherita bianca" + } ) + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "ravioli" + } ) + add( new javax.swing.tree.DefaultMutableTreeNode { + userObject: "bananas" + } ) + } ) + } ) auxiliary() { "JavaCodeGenerator.variableLocal": false } From 62fc3139cfc649091d2c5c43c12173f0c0352adf Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 2 Jan 2020 18:45:32 +0100 Subject: [PATCH 09/46] ComboBox: fixed NPE in Oracle SQL Developer settings --- CHANGELOG.md | 1 + .../src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ff0496d..f1830c28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ FlatLaf Change Log ## Unreleased - Tree: Fixed wide selection if scrolled horizontally. +- ComboBox: Fixed NPE in Oracle SQL Developer settings. ## 0.23 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index 07605de0..acf56ced 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -36,6 +36,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; @@ -348,6 +349,8 @@ public class FlatComboBoxUI public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) { ListCellRenderer renderer = comboBox.getRenderer(); uninstallCellPaddingBorder( renderer ); + if( renderer == null ) + renderer = new DefaultListCellRenderer(); Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false ); c.setFont( comboBox.getFont() ); c.applyComponentOrientation( comboBox.getComponentOrientation() ); @@ -520,6 +523,8 @@ public class FlatComboBoxUI CellPaddingBorder.uninstall( renderer ); CellPaddingBorder.uninstall( lastRendererComponent ); + if( renderer == null ) + renderer = new DefaultListCellRenderer(); Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus ); c.applyComponentOrientation( comboBox.getComponentOrientation() ); From 9f16249898a1291907c7c3e925bc59623f8b84c6 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 2 Jan 2020 21:09:11 +0100 Subject: [PATCH 10/46] IntelliJ Themes: fixed checkbox colors in Material UI Lite dark themes --- CHANGELOG.md | 1 + .../com/formdev/flatlaf/IntelliJTheme.java | 61 +++++++++++-------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1830c28..1d794a81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FlatLaf Change Log - Tree: Fixed wide selection if scrolled horizontally. - ComboBox: Fixed NPE in Oracle SQL Developer settings. +- IntelliJ Themes: Fixed checkbox colors in Material UI Lite dark themes. ## 0.23 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index fd241c5c..468bf58d 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -355,33 +355,43 @@ public class IntelliJTheme value = "#ffffff"; } + String key2 = checkboxDuplicateColors.get( key ); + if( dark ) key = StringUtils.removeTrailing( key, ".Dark" ); String newKey = checkboxKeyMapping.get( key ); if( newKey != null ) { ColorUIResource color = toColor( (String) value ); - if( color != null ) + if( color != null ) { defaults.put( newKey, color ); + if( key2 != null ) { + // When IDEA replaces colors in SVGs it uses color values and not the keys + // from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that + // have same color value: + // - Checkbox.Background.Default.Dark has same color as Checkbox.Background.Selected.Dark + // - Checkbox.Border.Default.Dark has same color as Checkbox.Border.Selected.Dark + // - Checkbox.Focus.Thin.Default.Dark has same color as Checkbox.Focus.Thin.Selected.Dark + // + // So if only e.g. Checkbox.Background.Default.Dark is specified in .theme.json, + // then this color is also used for Checkbox.Background.Selected.Dark. + // + // If Checkbox.Background.Default.Dark and Checkbox.Background.Selected.Dark + // are specified in .theme.json, then the later specified is used for both. + if( dark ) + key2 = StringUtils.removeTrailing( key2, ".Dark" ); + + String newKey2 = checkboxKeyMapping.get( key2 ); + if( newKey2 != null ) + defaults.put( newKey2, color ); + } + } + checkboxModified = true; } } - // When IDEA replaces colors in SVGs it uses color values and not the keys - // from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that - // have same color value: - // - Checkbox.Background.Default.Dark has same color as Checkbox.Background.Selected.Dark - // - Checkbox.Border.Default.Dark has same color as Checkbox.Border.Selected.Dark - // - Checkbox.Focus.Thin.Default.Dark has same color as Checkbox.Focus.Thin.Selected.Dark - // - // So if only e.g. Checkbox.Background.Default.Dark is specified in .theme.json, - // then this color is also used for Checkbox.Background.Selected.Dark. - // Occurs e.g. in "Dark purple" theme. - fixCheckBoxColor( defaults, colorPalette, "Checkbox.Background.Default.Dark", "Checkbox.Background.Selected.Dark" ); - fixCheckBoxColor( defaults, colorPalette, "Checkbox.Border.Default.Dark", "Checkbox.Border.Selected.Dark" ); - fixCheckBoxColor( defaults, colorPalette, "Checkbox.Focus.Thin.Default.Dark", "Checkbox.Focus.Thin.Selected.Dark" ); - // remove hover and pressed colors if( checkboxModified ) { defaults.remove( "CheckBox.icon.hoverBorderColor" ); @@ -393,21 +403,10 @@ public class IntelliJTheme } } - private void fixCheckBoxColor( UIDefaults defaults, Map colorPalette, String key1, String key2 ) { - if( colorPalette.containsKey( key1 ) == colorPalette.containsKey( key2 ) ) - return; - - String newKey1 = checkboxKeyMapping.get( StringUtils.removeTrailing( key1, ".Dark" ) ); - String newKey2 = checkboxKeyMapping.get( StringUtils.removeTrailing( key2, ".Dark" ) ); - if( colorPalette.containsKey( key1 ) ) - defaults.put( newKey2, defaults.get( newKey1 ) ); - else - defaults.put( newKey1, defaults.get( newKey2 ) ); - } - private static Map uiKeyMapping = new HashMap<>(); private static Map uiKeyInverseMapping = new HashMap<>(); private static Map checkboxKeyMapping = new HashMap<>(); + private static Map checkboxDuplicateColors = new HashMap<>(); private static Set noWildcardReplace = new HashSet<>(); static { @@ -453,6 +452,14 @@ public class IntelliJTheme checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" ); checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" ); + checkboxDuplicateColors.put( "Checkbox.Background.Default.Dark", "Checkbox.Background.Selected.Dark" ); + checkboxDuplicateColors.put( "Checkbox.Border.Default.Dark", "Checkbox.Border.Selected.Dark" ); + checkboxDuplicateColors.put( "Checkbox.Focus.Thin.Default.Dark", "Checkbox.Focus.Thin.Selected.Dark" ); + @SuppressWarnings( "unchecked" ) + Map.Entry[] entries = checkboxDuplicateColors.entrySet().toArray( new Map.Entry[checkboxDuplicateColors.size()] ); + for( Map.Entry e : entries ) + checkboxDuplicateColors.put( e.getValue(), e.getKey() ); + // because FlatLaf uses Button.background and Button.borderColor, // but IDEA uses Button.startBackground and Button.startBorderColor, // our default button background and border colors may be replaced by From d990ccc4aba662d9e86d9aa85ffbc466872863a0 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 2 Jan 2020 22:39:34 +0100 Subject: [PATCH 11/46] release 0.23.1 --- CHANGELOG.md | 2 +- README.md | 2 +- build.gradle.kts | 2 +- flatlaf-jide-oss/README.md | 2 +- flatlaf-swingx/README.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d794a81..8bb8304d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ FlatLaf Change Log ================== -## Unreleased +## 0.23.1 - Tree: Fixed wide selection if scrolled horizontally. - ComboBox: Fixed NPE in Oracle SQL Developer settings. diff --git a/README.md b/README.md index cac51d6d..37044444 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ build script: groupId: com.formdev artifactId: flatlaf - version: 0.23 + version: 0.23.1 Otherwise download `flatlaf-.jar` here: diff --git a/build.gradle.kts b/build.gradle.kts index 27c34b48..0a0cbf90 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -version = "0.23" +version = "0.23.1" allprojects { repositories { diff --git a/flatlaf-jide-oss/README.md b/flatlaf-jide-oss/README.md index e9a6facf..8db3fb14 100644 --- a/flatlaf-jide-oss/README.md +++ b/flatlaf-jide-oss/README.md @@ -26,7 +26,7 @@ build script: groupId: com.formdev artifactId: flatlaf-jide-oss - version: 0.23 + version: 0.23.1 Otherwise download `flatlaf-jide-oss-.jar` here: diff --git a/flatlaf-swingx/README.md b/flatlaf-swingx/README.md index 0cb636b8..cec446c8 100644 --- a/flatlaf-swingx/README.md +++ b/flatlaf-swingx/README.md @@ -33,7 +33,7 @@ build script: groupId: com.formdev artifactId: flatlaf-swingx - version: 0.23 + version: 0.23.1 Otherwise download `flatlaf-swingx-.jar` here: From 8dbbe208404f85ad17873b25312eb5b24ba80b32 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 6 Jan 2020 15:18:38 +0100 Subject: [PATCH 12/46] TableHeader: paint column borders also if renderer has changed, but delegates to the system default renderer (e.g. done in NetBeans class ETableHeader) --- CHANGELOG.md | 7 +++++++ .../formdev/flatlaf/ui/FlatTableHeaderUI.java | 20 +++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb8304d..fc076af3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ FlatLaf Change Log ================== +## Unreleased + +- TableHeader: Paint column borders if renderer has changed, but delegates to + the system default renderer (e.g. done in NetBeans). + + + ## 0.23.1 - Tree: Fixed wide selection if scrolled horizontally. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java index 71d4d31f..42ad87e3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableHeaderUI.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.ui; import java.awt.Color; +import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; @@ -29,6 +30,7 @@ import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicTableHeaderUI; +import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import com.formdev.flatlaf.util.UIScale; @@ -81,10 +83,14 @@ public class FlatTableHeaderUI @Override public void paint( Graphics g, JComponent c ) { // do not paint borders if JTableHeader.setDefaultRenderer() was used - String rendererClassName = header.getDefaultRenderer().getClass().getName(); - boolean paintBorders = - rendererClassName.equals( "sun.swing.table.DefaultTableCellHeaderRenderer" ) || - rendererClassName.equals( "sun.swing.FilePane$AlignableTableHeaderRenderer" ); + TableCellRenderer defaultRenderer = header.getDefaultRenderer(); + boolean paintBorders = isSystemDefaultRenderer( defaultRenderer ); + if( !paintBorders && header.getColumnModel().getColumnCount() > 0 ) { + // check whether the renderer delegates to the system default renderer + Component rendererComponent = defaultRenderer.getTableCellRendererComponent( + header.getTable(), "", false, false, -1, 0 ); + paintBorders = isSystemDefaultRenderer( rendererComponent ); + } if( paintBorders ) paintColumnBorders( g, c ); @@ -95,6 +101,12 @@ public class FlatTableHeaderUI paintDraggedColumnBorders( g, c ); } + private boolean isSystemDefaultRenderer( Object headerRenderer ) { + String rendererClassName = headerRenderer.getClass().getName(); + return rendererClassName.equals( "sun.swing.table.DefaultTableCellHeaderRenderer" ) || + rendererClassName.equals( "sun.swing.FilePane$AlignableTableHeaderRenderer" ); + } + private void paintColumnBorders( Graphics g, JComponent c ) { int width = c.getWidth(); int height = c.getHeight(); From 33ea84004ddff8d9a40318ad9d04d8c33df46809 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 6 Jan 2020 16:54:56 +0100 Subject: [PATCH 13/46] UIDefaultsLoader: changed `.properties` file loading order: now all core `.properties` files are loaded before loading addon `.properties` files, which makes it easier to overwrite core values in addons; also, addon loading order can be specified --- CHANGELOG.md | 3 ++ .../formdev/flatlaf/FlatDefaultsAddon.java | 12 ++++++- .../com/formdev/flatlaf/UIDefaultsLoader.java | 33 ++++++++++++------- .../jideoss/FlatJideOssDefaultsAddon.java | 5 +++ .../swingx/FlatSwingXDefaultsAddon.java | 4 +++ 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc076af3..9d16d8ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ FlatLaf Change Log ## Unreleased +- Changed `.properties` file loading order: Now all core `.properties` files are + loaded before loading addon `.properties` files. This makes it easier to + overwrite core values in addons. Also, addon loading order can be specified. - TableHeader: Paint column borders if renderer has changed, but delegates to the system default renderer (e.g. done in NetBeans). diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java index 50a62554..4e469d8f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatDefaultsAddon.java @@ -45,8 +45,18 @@ public abstract class FlatDefaultsAddon */ public InputStream getDefaults( Class lafClass ) { Class addonClass = this.getClass(); - String propertiesName = "/" + addonClass.getPackage().getName().replace( '.', '/' ) + String propertiesName = '/' + addonClass.getPackage().getName().replace( '.', '/' ) + '/' + lafClass.getSimpleName() + ".properties"; return addonClass.getResourceAsStream( propertiesName ); } + + /** + * Returns the priority used to sort addon loading. + * The order is only important if you want overwrite UI defaults of other addons. + * Lower numbers mean higher priority. + * Returns 10000 by default. + */ + public int getPriority() { + return 10000; + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java index fc79c8cf..b82ae296 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java @@ -84,32 +84,41 @@ class UIDefaultsLoader static void loadDefaultsFromProperties( List> lafClasses, UIDefaults defaults ) { try { - List addonClassLoaders = new ArrayList<>(); - - // load properties files + // load core properties files Properties properties = new Properties(); - ServiceLoader addonLoader = ServiceLoader.load( FlatDefaultsAddon.class ); for( Class lafClass : lafClasses ) { - // load core properties - String propertiesName = "/" + lafClass.getName().replace( '.', '/' ) + ".properties"; + String propertiesName = '/' + lafClass.getName().replace( '.', '/' ) + ".properties"; try( InputStream in = lafClass.getResourceAsStream( propertiesName ) ) { if( in != null ) properties.load( in ); } + } - // load properties from addons - for( FlatDefaultsAddon addon : addonLoader ) { + // get addons and sort them by priority + ServiceLoader addonLoader = ServiceLoader.load( FlatDefaultsAddon.class ); + List addonList = new ArrayList<>(); + for( FlatDefaultsAddon addon : addonLoader ) + addonList.add( addon ); + addonList.sort( (addon1, addon2) -> addon1.getPriority() - addon2.getPriority() ); + + // load properties from addons + for( FlatDefaultsAddon addon : addonList ) { + for( Class lafClass : lafClasses ) { try( InputStream in = addon.getDefaults( lafClass ) ) { if( in != null ) properties.load( in ); } - - ClassLoader addonClassLoader = addon.getClass().getClassLoader(); - if( !addonClassLoaders.contains( addonClassLoader ) ) - addonClassLoaders.add( addonClassLoader ); } } + // collect addon class loaders + List addonClassLoaders = new ArrayList<>(); + for( FlatDefaultsAddon addon : addonList ) { + ClassLoader addonClassLoader = addon.getClass().getClassLoader(); + if( !addonClassLoaders.contains( addonClassLoader ) ) + addonClassLoaders.add( addonClassLoader ); + } + // collect all platform specific keys (but do not modify properties) ArrayList platformSpecificKeys = new ArrayList<>(); for( Object key : properties.keySet() ) { diff --git a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java index bcbf8169..cb0494d5 100644 --- a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java +++ b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java @@ -46,6 +46,11 @@ public class FlatJideOssDefaultsAddon return super.getDefaults( lafClass ); } + @Override + public int getPriority() { + return 11; + } + //---- class FlatJideUIDefaultsCustomizer --------------------------------- /** diff --git a/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java b/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java index b26894bb..c708c034 100644 --- a/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java +++ b/flatlaf-swingx/src/main/java/com/formdev/flatlaf/swingx/FlatSwingXDefaultsAddon.java @@ -29,4 +29,8 @@ import com.formdev.flatlaf.FlatDefaultsAddon; public class FlatSwingXDefaultsAddon extends FlatDefaultsAddon { + @Override + public int getPriority() { + return 10; + } } From 822cd16daac9b1839a8db0c113a207a16cce4e84 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 7 Jan 2020 23:40:24 +0100 Subject: [PATCH 14/46] IntelliJ Themes Demo: updated Dracula, Hiberbee and Material UI Lite themes (used IJThemesUpdater) (issue #26) --- .../demo/intellijthemes/Dracula.theme.json | 16 ---------------- .../demo/intellijthemes/Hiberbee.theme.json | 2 +- .../Arc Dark Contrast.theme.json | 2 +- .../material-theme-ui-lite/Arc Dark.theme.json | 2 +- .../Atom One Dark Contrast.theme.json | 2 +- .../Atom One Dark.theme.json | 2 +- .../Atom One Light Contrast.theme.json | 2 +- .../Atom One Light.theme.json | 2 +- .../Dracula Contrast.theme.json | 2 +- .../material-theme-ui-lite/Dracula.theme.json | 2 +- .../GitHub Contrast.theme.json | 2 +- .../material-theme-ui-lite/GitHub.theme.json | 2 +- .../Light Owl Contrast.theme.json | 2 +- .../material-theme-ui-lite/Light Owl.theme.json | 2 +- .../Material Darker Contrast.theme.json | 2 +- .../Material Darker.theme.json | 2 +- .../Material Deep Ocean Contrast.theme.json | 2 +- .../Material Deep Ocean.theme.json | 2 +- .../Material Lighter Contrast.theme.json | 2 +- .../Material Lighter.theme.json | 2 +- .../Material Oceanic Contrast.theme.json | 2 +- .../Material Oceanic.theme.json | 2 +- .../Material Palenight Contrast.theme.json | 2 +- .../Material Palenight.theme.json | 2 +- .../Monokai Pro Contrast.theme.json | 2 +- .../Monokai Pro.theme.json | 2 +- .../Night Owl Contrast.theme.json | 2 +- .../material-theme-ui-lite/Night Owl.theme.json | 2 +- .../Solarized Dark Contrast.theme.json | 2 +- .../Solarized Dark.theme.json | 2 +- .../Solarized Light Contrast.theme.json | 2 +- .../Solarized Light.theme.json | 2 +- 32 files changed, 31 insertions(+), 47 deletions(-) diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Dracula.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Dracula.theme.json index eadab125..d48f1c58 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Dracula.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Dracula.theme.json @@ -160,22 +160,6 @@ "inactiveBackground": "#44475a" } }, - "ScrollBar": { - "thumbColor": "#bd93f9", - "hoverThumbColor": "#bd93f9", - "Transparent": { - "thumbColor": "#bd93f9", - "hoverThumbColor": "#bd93f9" - }, - "Mac": { - "thumbColor": "#bd93f9", - "hoverThumbColor": "#bd93f9", - "Transparent": { - "thumbColor": "#bd93f9", - "hoverThumbColor": "#bd93f9" - } - } - }, "SearchEverywhere": { "SearchField": { "background": "#44475a" diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json index 60b8c07c..d2dafd0b 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/Hiberbee.theme.json @@ -212,7 +212,7 @@ "ProgressBar.passedColor": "green", "ProgressBar.passedEndColor": "greyDot65", "ProgressBar.progressColor": "accent", - "ProgressBar.trackColor": "greyDot65", + "ProgressBar.trackColor": "greyDot75", "RadioButton.background": "greyDot75", "ScrollBar.Mac.hoverTrackColor": "greyDot75", "ScrollBar.Mac.trackColor": "greyDot75", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark Contrast.theme.json index 78e34cef..cbc7b980 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#393f4c", "foreground": "#D3DAE3", "infoForeground": "#8b9eb5", - "matchForeground": "#42A5F52", + "matchForeground": "#42A5F5", "matchSelectionForeground": "#42A5F5", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark.theme.json index e8fee7ae..ea2806af 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Arc Dark.theme.json @@ -110,7 +110,7 @@ "background": "#393f4c", "foreground": "#D3DAE3", "infoForeground": "#8b9eb5", - "matchForeground": "#42A5F52", + "matchForeground": "#42A5F5", "matchSelectionForeground": "#42A5F5", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark Contrast.theme.json index 2fd5f7d7..48c3e072 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#2F333D", "foreground": "#979FAD", "infoForeground": "#979FAD", - "matchForeground": "#2979ff2", + "matchForeground": "#2979ff", "matchSelectionForeground": "#2979ff", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark.theme.json index b00b0178..d62bac34 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Dark.theme.json @@ -110,7 +110,7 @@ "background": "#2F333D", "foreground": "#979FAD", "infoForeground": "#979FAD", - "matchForeground": "#2979ff2", + "matchForeground": "#2979ff", "matchSelectionForeground": "#2979ff", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light Contrast.theme.json index 82fbf951..e5ecc3c9 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#EAEAEB", "foreground": "#232324", "infoForeground": "#7f7f7f", - "matchForeground": "#2979ff2", + "matchForeground": "#2979ff", "matchSelectionForeground": "#2979ff", "nonFocusedState": "false", "selectedGrayedForeground": "#232324", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light.theme.json index cc2555bf..2b9ac237 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Atom One Light.theme.json @@ -110,7 +110,7 @@ "background": "#EAEAEB", "foreground": "#232324", "infoForeground": "#7f7f7f", - "matchForeground": "#2979ff2", + "matchForeground": "#2979ff", "matchSelectionForeground": "#2979ff", "nonFocusedState": "false", "selectedGrayedForeground": "#232324", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula Contrast.theme.json index 4fd31518..97561c5f 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#282A36", "foreground": "#F8F8F2", "infoForeground": "#6272A4", - "matchForeground": "#FF79C52", + "matchForeground": "#FF79C5", "matchSelectionForeground": "#FF79C5", "nonFocusedState": "false", "selectedGrayedForeground": "#8BE9FD", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula.theme.json index 89e354d6..fea5d31a 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Dracula.theme.json @@ -110,7 +110,7 @@ "background": "#282A36", "foreground": "#F8F8F2", "infoForeground": "#6272A4", - "matchForeground": "#FF79C52", + "matchForeground": "#FF79C5", "matchSelectionForeground": "#FF79C5", "nonFocusedState": "false", "selectedGrayedForeground": "#8BE9FD", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub Contrast.theme.json index 3700e2d7..1706d1ff 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#f3f3f3", "foreground": "#5B6168", "infoForeground": "#292D31", - "matchForeground": "#79CB602", + "matchForeground": "#79CB60", "matchSelectionForeground": "#79CB60", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub.theme.json index 306027a0..fa83c69b 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/GitHub.theme.json @@ -110,7 +110,7 @@ "background": "#f3f3f3", "foreground": "#5B6168", "infoForeground": "#292D31", - "matchForeground": "#79CB602", + "matchForeground": "#79CB60", "matchSelectionForeground": "#79CB60", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl Contrast.theme.json index e170cb02..50012dad 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#FBFBFB", "foreground": "#403f53", "infoForeground": "#90A7B2", - "matchForeground": "#2AA2982", + "matchForeground": "#2AA298", "matchSelectionForeground": "#2AA298", "nonFocusedState": "false", "selectedGrayedForeground": "#403f53", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl.theme.json index ca55fcc9..bd72ec1d 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Light Owl.theme.json @@ -110,7 +110,7 @@ "background": "#FBFBFB", "foreground": "#403f53", "infoForeground": "#90A7B2", - "matchForeground": "#2AA2982", + "matchForeground": "#2AA298", "matchSelectionForeground": "#2AA298", "nonFocusedState": "false", "selectedGrayedForeground": "#403f53", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json index 375b8d65..df2a38ab 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#292929", "foreground": "#B0BEC5", "infoForeground": "#727272", - "matchForeground": "#FF98002", + "matchForeground": "#FF9800", "matchSelectionForeground": "#FF9800", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json index 14679bf8..fcefe47b 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json @@ -110,7 +110,7 @@ "background": "#292929", "foreground": "#B0BEC5", "infoForeground": "#727272", - "matchForeground": "#FF98002", + "matchForeground": "#FF9800", "matchSelectionForeground": "#FF9800", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean Contrast.theme.json index cba304d4..8012bf05 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#181A1F", "foreground": "#8F93A2", "infoForeground": "#4B526D", - "matchForeground": "#84ffff2", + "matchForeground": "#84ffff", "matchSelectionForeground": "#84ffff", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean.theme.json index f0ac1e5f..6c229e25 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Deep Ocean.theme.json @@ -110,7 +110,7 @@ "background": "#181A1F", "foreground": "#8F93A2", "infoForeground": "#4B526D", - "matchForeground": "#84ffff2", + "matchForeground": "#84ffff", "matchSelectionForeground": "#84ffff", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter Contrast.theme.json index 5fc834f2..054f7a40 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#FFFFFF", "foreground": "#546E7A", "infoForeground": "#94A7B0", - "matchForeground": "#00BCD42", + "matchForeground": "#00BCD4", "matchSelectionForeground": "#00BCD4", "nonFocusedState": "false", "selectedGrayedForeground": "#546e7a", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter.theme.json index 2c98b09a..c2994fb9 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Lighter.theme.json @@ -110,7 +110,7 @@ "background": "#FFFFFF", "foreground": "#546E7A", "infoForeground": "#94A7B0", - "matchForeground": "#00BCD42", + "matchForeground": "#00BCD4", "matchSelectionForeground": "#00BCD4", "nonFocusedState": "false", "selectedGrayedForeground": "#546e7a", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic Contrast.theme.json index 78bda9f5..c1a6ecdf 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#32424A", "foreground": "#B0BEC5", "infoForeground": "#607D8B", - "matchForeground": "#0096882", + "matchForeground": "#009688", "matchSelectionForeground": "#009688", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic.theme.json index d68f0007..21a6762c 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Oceanic.theme.json @@ -110,7 +110,7 @@ "background": "#32424A", "foreground": "#B0BEC5", "infoForeground": "#607D8B", - "matchForeground": "#0096882", + "matchForeground": "#009688", "matchSelectionForeground": "#009688", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight Contrast.theme.json index 52c4a332..95638985 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#34324a", "foreground": "#A6ACCD", "infoForeground": "#676E95", - "matchForeground": "#ab47bc2", + "matchForeground": "#ab47bc", "matchSelectionForeground": "#ab47bc", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight.theme.json index 6b20cc6a..38e4fc3f 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Palenight.theme.json @@ -110,7 +110,7 @@ "background": "#34324a", "foreground": "#A6ACCD", "infoForeground": "#676E95", - "matchForeground": "#ab47bc2", + "matchForeground": "#ab47bc", "matchSelectionForeground": "#ab47bc", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro Contrast.theme.json index 7822a9a4..50e4f111 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#403E41", "foreground": "#fcfcfa", "infoForeground": "#939293", - "matchForeground": "#ffd8662", + "matchForeground": "#ffd866", "matchSelectionForeground": "#ffd866", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro.theme.json index a86d0b28..6730e306 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Monokai Pro.theme.json @@ -110,7 +110,7 @@ "background": "#403E41", "foreground": "#fcfcfa", "infoForeground": "#939293", - "matchForeground": "#ffd8662", + "matchForeground": "#ffd866", "matchSelectionForeground": "#ffd866", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl Contrast.theme.json index 259eb4ce..fad9dd49 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#0b2942", "foreground": "#d6deeb", "infoForeground": "#5f7e97", - "matchForeground": "#7e57c22", + "matchForeground": "#7e57c2", "matchSelectionForeground": "#7e57c2", "nonFocusedState": "false", "selectedGrayedForeground": "#ffffff", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl.theme.json index 925eaf39..cd666916 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Night Owl.theme.json @@ -110,7 +110,7 @@ "background": "#0b2942", "foreground": "#d6deeb", "infoForeground": "#5f7e97", - "matchForeground": "#7e57c22", + "matchForeground": "#7e57c2", "matchSelectionForeground": "#7e57c2", "nonFocusedState": "false", "selectedGrayedForeground": "#ffffff", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark Contrast.theme.json index 4a13987b..7af69ed7 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#003745", "foreground": "#839496", "infoForeground": "#586e75", - "matchForeground": "#d336822", + "matchForeground": "#d33682", "matchSelectionForeground": "#d33682", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark.theme.json index 501c5bf5..81d11a16 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Dark.theme.json @@ -110,7 +110,7 @@ "background": "#003745", "foreground": "#839496", "infoForeground": "#586e75", - "matchForeground": "#d336822", + "matchForeground": "#d33682", "matchSelectionForeground": "#d33682", "nonFocusedState": "false", "selectedGrayedForeground": "#FFFFFF", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light Contrast.theme.json index aa800af0..1a6deefc 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light Contrast.theme.json @@ -110,7 +110,7 @@ "background": "#F6F0DE", "foreground": "#586e75", "infoForeground": "#93a1a1", - "matchForeground": "#d336822", + "matchForeground": "#d33682", "matchSelectionForeground": "#d33682", "nonFocusedState": "false", "selectedGrayedForeground": "#002b36", diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light.theme.json index 1d914ad1..b07c9efe 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Solarized Light.theme.json @@ -110,7 +110,7 @@ "background": "#F6F0DE", "foreground": "#586e75", "infoForeground": "#93a1a1", - "matchForeground": "#d336822", + "matchForeground": "#d33682", "matchSelectionForeground": "#d33682", "nonFocusedState": "false", "selectedGrayedForeground": "#002b36", From 8e8411283792149252855a11a5220865bf407015 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 8 Jan 2020 10:18:30 +0100 Subject: [PATCH 15/46] Label and ToolTip: fixed font sizes for HTML headings --- CHANGELOG.md | 2 +- .../com/formdev/flatlaf/ui/FlatLabelUI.java | 47 +++++ .../com/formdev/flatlaf/ui/FlatToolTipUI.java | 35 ++++ .../flatlaf/testing/FlatComponentsTest.java | 49 ----- .../flatlaf/testing/FlatComponentsTest.jfd | 46 +---- .../formdev/flatlaf/testing/FlatHtmlTest.java | 186 ++++++++++++++++++ .../formdev/flatlaf/testing/FlatHtmlTest.jfd | 105 ++++++++++ 7 files changed, 376 insertions(+), 94 deletions(-) create mode 100644 flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.java create mode 100644 flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.jfd diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d16d8ba..188d8958 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ FlatLaf Change Log overwrite core values in addons. Also, addon loading order can be specified. - TableHeader: Paint column borders if renderer has changed, but delegates to the system default renderer (e.g. done in NetBeans). - +- Label and ToolTip: Fixed font sizes for HTML headings. ## 0.23.1 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java index 66779db7..6ed86360 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatLabelUI.java @@ -20,12 +20,14 @@ import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Rectangle; +import java.beans.PropertyChangeEvent; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicHTML; import javax.swing.plaf.basic.BasicLabelUI; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.util.UIScale; @@ -77,6 +79,51 @@ public class FlatLabelUI defaults_initialized = false; } + @Override + protected void installComponents( JLabel c ) { + super.installComponents( c ); + + // update HTML renderer if necessary + updateHTMLRenderer( c, c.getText(), false ); + } + + @Override + public void propertyChange( PropertyChangeEvent e ) { + String name = e.getPropertyName(); + if( name == "text" || name == "font" || name == "foreground" ) { + JLabel label = (JLabel) e.getSource(); + updateHTMLRenderer( label, label.getText(), true ); + } else + super.propertyChange( e ); + } + + /** + * Checks whether text contains HTML headings and adds a special CSS rule to + * re-calculate heading font sizes based on current component font size. + */ + static void updateHTMLRenderer( JComponent c, String text, boolean always ) { + if( BasicHTML.isHTMLString( text ) && + c.getClientProperty( "html.disable" ) != Boolean.TRUE && + text.contains( "" ); + + String style = ""; + if( headIndex < 0 ) + style = "" + style + ""; + + int insertIndex = headIndex >= 0 ? (headIndex + "".length()) : "".length(); + text = text.substring( 0, insertIndex ) + + style + + text.substring( insertIndex ); + } else if( !always ) + return; // not necessary to invoke BasicHTML.updateRenderer() + + BasicHTML.updateRenderer( c, text ); + } + @Override protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) { int mnemIndex = FlatLaf.isShowMnemonics() ? l.getDisplayedMnemonicIndex() : -1; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java index ad3b501e..ee42b6e8 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java @@ -21,6 +21,7 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; +import java.beans.PropertyChangeListener; import java.util.List; import javax.swing.JComponent; import javax.swing.JToolTip; @@ -47,6 +48,8 @@ import com.formdev.flatlaf.util.StringUtils; public class FlatToolTipUI extends BasicToolTipUI { + private static PropertyChangeListener sharedPropertyChangedListener; + private static ComponentUI instance; public static ComponentUI createUI( JComponent c ) { @@ -55,6 +58,38 @@ public class FlatToolTipUI return instance; } + @Override + public void installUI( JComponent c ) { + super.installUI( c ); + + // update HTML renderer if necessary + FlatLabelUI.updateHTMLRenderer( c, ((JToolTip)c).getTipText(), false ); + } + + @Override + protected void installListeners( JComponent c ) { + super.installListeners( c ); + + if( sharedPropertyChangedListener == null ) { + sharedPropertyChangedListener = e -> { + String name = e.getPropertyName(); + if( name == "text" || name == "font" || name == "foreground" ) { + JToolTip toolTip = (JToolTip) e.getSource(); + FlatLabelUI.updateHTMLRenderer( toolTip, toolTip.getTipText(), false ); + } + }; + } + + c.addPropertyChangeListener( sharedPropertyChangedListener ); + } + + @Override + protected void uninstallListeners( JComponent c ) { + super.uninstallListeners( c ); + + c.removePropertyChangeListener( sharedPropertyChangedListener ); + } + @Override public Dimension getPreferredSize( JComponent c ) { if( isMultiLine( c ) ) { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java index 89eb57d7..90c710e6 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java @@ -162,14 +162,7 @@ public class FlatComponentsTest JToggleButton toggleButton7 = new JToggleButton(); JLabel scrollBarLabel = new JLabel(); JScrollBar scrollBar1 = new JScrollBar(); - JLabel label4 = new JLabel(); JScrollBar scrollBar4 = new JScrollBar(); - JPanel panel3 = new JPanel(); - JLabel label3 = new JLabel(); - JScrollPane scrollPane15 = new JScrollPane(); - JEditorPane editorPane6 = new JEditorPane(); - JScrollPane scrollPane16 = new JScrollPane(); - JTextPane textPane6 = new JTextPane(); JScrollBar scrollBar5 = new JScrollBar(); JScrollBar scrollBar6 = new JScrollBar(); JLabel separatorLabel = new JLabel(); @@ -806,53 +799,11 @@ public class FlatComponentsTest scrollBar1.setOrientation(Adjustable.HORIZONTAL); add(scrollBar1, "cell 1 14,growx"); - //---- label4 ---- - label4.setText("HTML:"); - add(label4, "cell 5 14"); - //---- scrollBar4 ---- scrollBar4.setOrientation(Adjustable.HORIZONTAL); scrollBar4.setEnabled(false); add(scrollBar4, "cell 1 15,growx"); - //======== panel3 ======== - { - panel3.setOpaque(false); - panel3.setLayout(new MigLayout( - "ltr,insets 0,hidemode 3", - // columns - "[]", - // rows - "[]" + - "[]" + - "[]")); - - //---- label3 ---- - label3.setText("JLabel HTML
Sample content
text with link"); - panel3.add(label3, "cell 0 0"); - - //======== scrollPane15 ======== - { - - //---- editorPane6 ---- - editorPane6.setContentType("text/html"); - editorPane6.setText("JEditorPane HTML
Sample content
text with link"); - scrollPane15.setViewportView(editorPane6); - } - panel3.add(scrollPane15, "cell 0 1,grow"); - - //======== scrollPane16 ======== - { - - //---- textPane6 ---- - textPane6.setContentType("text/html"); - textPane6.setText("JTextPane HTML
Sample content
text with link"); - scrollPane16.setViewportView(textPane6); - } - panel3.add(scrollPane16, "cell 0 2,grow"); - } - add(panel3, "cell 5 15 1 9,aligny top,grow 100 0"); - //---- scrollBar5 ---- scrollBar5.setOrientation(Adjustable.HORIZONTAL); scrollBar5.putClientProperty("JScrollBar.showButtons", true); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd index 9cc96640..0ab48b7e 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -756,12 +756,6 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 14,growx" } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "label4" - "text": "HTML:" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 5 14" - } ) add( new FormComponent( "javax.swing.JScrollBar" ) { name: "scrollBar4" "orientation": 0 @@ -769,42 +763,6 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 15,growx" } ) - add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$columnConstraints": "[]" - "$rowConstraints": "[][][]" - "$layoutConstraints": "ltr,insets 0,hidemode 3" - } ) { - name: "panel3" - "opaque": false - add( new FormComponent( "javax.swing.JLabel" ) { - name: "label3" - "text": "JLabel HTML
Sample content
text with link" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 0" - } ) - add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { - name: "scrollPane15" - add( new FormComponent( "javax.swing.JEditorPane" ) { - name: "editorPane6" - "contentType": "text/html" - "text": "JEditorPane HTML
Sample content
text with link" - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 1,grow" - } ) - add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { - name: "scrollPane16" - add( new FormComponent( "javax.swing.JTextPane" ) { - name: "textPane6" - "contentType": "text/html" - "text": "JTextPane HTML
Sample content
text with link" - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2,grow" - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 5 15 1 9,aligny top,grow 100 0" - } ) add( new FormComponent( "javax.swing.JScrollBar" ) { name: "scrollBar5" "orientation": 0 @@ -977,7 +935,7 @@ new FormModel { } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) - "size": new java.awt.Dimension( 865, 750 ) + "size": new java.awt.Dimension( 865, 800 ) } ) } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.java new file mode 100644 index 00000000..cfd48649 --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.java @@ -0,0 +1,186 @@ +/* + * Copyright 2020 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.testing; + +import java.awt.*; +import javax.swing.*; +import com.formdev.flatlaf.util.UIScale; +import net.miginfocom.swing.*; + +/** + * @author Karl Tauber + */ +public class FlatHtmlTest + extends FlatTestPanel +{ + public static void main( String[] args ) { + SwingUtilities.invokeLater( () -> { + FlatTestFrame frame = FlatTestFrame.create( args, "FlatHtmlTest" ); + frame.showFrame( FlatHtmlTest::new ); + } ); + } + + FlatHtmlTest() { + initComponents(); + increaseFontSize(); + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + labelLabel = new JLabel(); + editorPaneLabel = new JLabel(); + textPaneLabel = new JLabel(); + toolTipLabel = new JLabel(); + label1 = new JLabel(); + scrollPane15 = new JScrollPane(); + editorPane1 = new JEditorPane(); + scrollPane16 = new JScrollPane(); + textPane1 = new JTextPane(); + toolTip1 = new JToolTip(); + label2 = new JLabel(); + scrollPane17 = new JScrollPane(); + editorPane2 = new JEditorPane(); + scrollPane18 = new JScrollPane(); + textPane2 = new JTextPane(); + toolTip2 = new JToolTip(); + + //======== this ======== + setLayout(new MigLayout( + "ltr,insets dialog,hidemode 3", + // columns + "[fill]" + + "[fill]" + + "[fill]" + + "[fill]", + // rows + "[]" + + "[top]" + + "[top]")); + + //---- labelLabel ---- + labelLabel.setText("JLabel:"); + add(labelLabel, "cell 0 0"); + + //---- editorPaneLabel ---- + editorPaneLabel.setText("JEditorPane:"); + add(editorPaneLabel, "cell 1 0"); + + //---- textPaneLabel ---- + textPaneLabel.setText("JTextPane:"); + add(textPaneLabel, "cell 2 0"); + + //---- toolTipLabel ---- + toolTipLabel.setText("JToolTip:"); + add(toolTipLabel, "cell 3 0"); + + //---- label1 ---- + label1.setText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + add(label1, "cell 0 1"); + + //======== scrollPane15 ======== + { + + //---- editorPane1 ---- + editorPane1.setContentType("text/html"); + editorPane1.setText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + scrollPane15.setViewportView(editorPane1); + } + add(scrollPane15, "cell 1 1,grow"); + + //======== scrollPane16 ======== + { + + //---- textPane1 ---- + textPane1.setContentType("text/html"); + textPane1.setText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + scrollPane16.setViewportView(textPane1); + } + add(scrollPane16, "cell 2 1"); + + //---- toolTip1 ---- + toolTip1.setTipText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + add(toolTip1, "cell 3 1"); + + //---- label2 ---- + label2.setText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + add(label2, "cell 0 2"); + + //======== scrollPane17 ======== + { + + //---- editorPane2 ---- + editorPane2.setContentType("text/html"); + editorPane2.setText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + scrollPane17.setViewportView(editorPane2); + } + add(scrollPane17, "cell 1 2,grow"); + + //======== scrollPane18 ======== + { + + //---- textPane2 ---- + textPane2.setContentType("text/html"); + textPane2.setText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + scrollPane18.setViewportView(textPane2); + } + add(scrollPane18, "cell 2 2"); + + //---- toolTip2 ---- + toolTip2.setTipText("HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

"); + add(toolTip2, "cell 3 2"); + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + @Override + public void updateUI() { + super.updateUI(); + + EventQueue.invokeLater( () -> { + increaseFontSize(); + } ); + } + + private void increaseFontSize() { + increaseFontSize( label2, label1.getFont() ); + increaseFontSize( editorPane2, editorPane1.getFont() ); + increaseFontSize( textPane2, textPane1.getFont() ); + increaseFontSize( toolTip2, toolTip1.getFont() ); + } + + private void increaseFontSize( JComponent c, Font baseFont ) { + c.setFont( baseFont.deriveFont( Font.PLAIN, baseFont.getSize() + UIScale.scale( 10f ) ) ); + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JLabel labelLabel; + private JLabel editorPaneLabel; + private JLabel textPaneLabel; + private JLabel toolTipLabel; + private JLabel label1; + private JScrollPane scrollPane15; + private JEditorPane editorPane1; + private JScrollPane scrollPane16; + private JTextPane textPane1; + private JToolTip toolTip1; + private JLabel label2; + private JScrollPane scrollPane17; + private JEditorPane editorPane2; + private JScrollPane scrollPane18; + private JTextPane textPane2; + private JToolTip toolTip2; + // JFormDesigner - End of variables declaration //GEN-END:variables +} diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.jfd new file mode 100644 index 00000000..df2c31ec --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatHtmlTest.jfd @@ -0,0 +1,105 @@ +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" + +new FormModel { + contentType: "form/swing" + root: new FormRoot { + add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "ltr,insets dialog,hidemode 3" + "$columnConstraints": "[fill][fill][fill][fill]" + "$rowConstraints": "[][top][top]" + } ) { + name: "this" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "labelLabel" + "text": "JLabel:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "editorPaneLabel" + "text": "JEditorPane:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "textPaneLabel" + "text": "JTextPane:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "toolTipLabel" + "text": "JToolTip:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label1" + "text": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane15" + add( new FormComponent( "javax.swing.JEditorPane" ) { + name: "editorPane1" + "contentType": "text/html" + "text": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1,grow" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane16" + add( new FormComponent( "javax.swing.JTextPane" ) { + name: "textPane1" + "contentType": "text/html" + "text": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 1" + } ) + add( new FormComponent( "javax.swing.JToolTip" ) { + name: "toolTip1" + "tipText": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label2" + "text": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane17" + add( new FormComponent( "javax.swing.JEditorPane" ) { + name: "editorPane2" + "contentType": "text/html" + "text": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2,grow" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane18" + add( new FormComponent( "javax.swing.JTextPane" ) { + name: "textPane2" + "contentType": "text/html" + "text": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 2" + } ) + add( new FormComponent( "javax.swing.JToolTip" ) { + name: "toolTip2" + "tipText": "HTML
Sample content
text with link

Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Paragraph

" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 2" + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 0 ) + "size": new java.awt.Dimension( 695, 755 ) + } ) + } +} From af7c18159648789561046c0f60cc130730d45ac3 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 8 Jan 2020 13:57:42 +0100 Subject: [PATCH 16/46] Button and ToggleButton: support square button style --- CHANGELOG.md | 2 ++ .../formdev/flatlaf/FlatClientProperties.java | 17 ++++++++-- .../com/formdev/flatlaf/ui/FlatBorder.java | 4 +-- .../formdev/flatlaf/ui/FlatButtonBorder.java | 4 +-- .../com/formdev/flatlaf/ui/FlatButtonUI.java | 7 +++- .../formdev/flatlaf/ui/FlatRoundBorder.java | 3 +- .../flatlaf/demo/BasicComponentsPanel.java | 15 ++++++++- .../flatlaf/demo/BasicComponentsPanel.jfd | 19 +++++++++-- .../flatlaf/testing/FlatComponentsTest.java | 26 +++++++++++++++ .../flatlaf/testing/FlatComponentsTest.jfd | 32 ++++++++++++++++++- 10 files changed, 116 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 188d8958..0dca90d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ FlatLaf Change Log - TableHeader: Paint column borders if renderer has changed, but delegates to the system default renderer (e.g. done in NetBeans). - Label and ToolTip: Fixed font sizes for HTML headings. +- Button and ToggleButton: Support square button style (set client property + `JButton.buttonType` to `square`). ## 0.23.1 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 10aebe50..3d0bc85d 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -27,14 +27,25 @@ public interface FlatClientProperties /** * Specifies type of a button. *

- * Component {@link javax.swing.JButton}
+ * Components {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}
* Value type {@link java.lang.String}
- * Allowed Values {@link BUTTON_TYPE_HELP} + * Allowed Values {@link #BUTTON_TYPE_SQUARE} and {@link #BUTTON_TYPE_HELP} */ String BUTTON_TYPE = "JButton.buttonType"; + /** + * Paint the button with square edges. + *

+ * Components {@link javax.swing.JButton} and {@link javax.swing.JToggleButton} + * + * @see #BUTTON_TYPE + */ + String BUTTON_TYPE_SQUARE = "square"; + /** * Paint a help button (circle with question mark). + *

+ * Components {@link javax.swing.JButton} * * @see #BUTTON_TYPE */ @@ -45,7 +56,7 @@ public interface FlatClientProperties *

* Component {@link javax.swing.JCheckBox}
* Value type {@link java.lang.String}
- * Allowed Values {@link SELECTED_STATE_INDETERMINATE} + * Allowed Values {@link #SELECTED_STATE_INDETERMINATE} */ String SELECTED_STATE = "JButton.selectedState"; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java index 6d489d6e..a88418e8 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java @@ -75,7 +75,7 @@ public class FlatBorder boolean isCellEditor = isTableCellEditor( c ); float focusWidth = isCellEditor ? 0 : getFocusWidth(); float borderWidth = getBorderWidth( c ); - float arc = isCellEditor ? 0 : getArc(); + float arc = isCellEditor ? 0 : getArc( c ); if( isFocused( c ) ) { g2.setColor( getFocusColor( c ) ); @@ -173,7 +173,7 @@ public class FlatBorder return getLineWidth(); } - protected float getArc() { + protected float getArc( Component c ) { return 0; } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java index 145565ef..a0341619 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java @@ -110,7 +110,7 @@ public class FlatButtonBorder } @Override - protected float getArc() { - return scale( (float) arc ); + protected float getArc( Component c ) { + return FlatButtonUI.isSquareButton( c ) ? 0 : scale( (float) arc ); } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java index 922c6663..9eadebee 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java @@ -209,6 +209,10 @@ public class FlatButtonUI (icon == null && text != null && ("...".equals( text ) || text.length() == 1)); } + static boolean isSquareButton( Component c ) { + return c instanceof AbstractButton && clientPropertyEquals( (AbstractButton) c, BUTTON_TYPE, BUTTON_TYPE_SQUARE ); + } + static boolean isHelpButton( Component c ) { return c instanceof JButton && clientPropertyEquals( (JButton) c, BUTTON_TYPE, BUTTON_TYPE_HELP ); } @@ -237,7 +241,8 @@ public class FlatButtonUI Border border = c.getBorder(); float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0; - float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0; + float arc = ((border instanceof FlatButtonBorder && !isSquareButton( c )) || isToolBarButton( c )) + ? scale( (float) this.arc ) : 0; boolean def = isDefaultButton( c ); // paint shadow diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java index 66960f75..0eced1f2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Component; import javax.swing.UIManager; /** @@ -32,7 +33,7 @@ public class FlatRoundBorder protected final int arc = UIManager.getInt( "Component.arc" ); @Override - protected float getArc() { + protected float getArc( Component c ) { return scale( (float) arc ); } } diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java index 7ed32f2b..b7ca8714 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java @@ -37,6 +37,8 @@ class BasicComponentsPanel JLabel buttonLabel = new JLabel(); JButton button1 = new JButton(); JButton button2 = new JButton(); + JButton button5 = new JButton(); + JButton button6 = new JButton(); JButton button3 = new JButton(); JButton button4 = new JButton(); JButton button13 = new JButton(); @@ -166,10 +168,21 @@ class BasicComponentsPanel button2.setEnabled(false); add(button2, "cell 2 1"); + //---- button5 ---- + button5.setText("square"); + button5.putClientProperty("JButton.buttonType", "square"); + add(button5, "cell 3 1"); + + //---- button6 ---- + button6.setText("square"); + button6.setEnabled(false); + button6.putClientProperty("JButton.buttonType", "square"); + add(button6, "cell 4 1"); + //---- button3 ---- button3.setText("Help"); button3.putClientProperty("JButton.buttonType", "help"); - add(button3, "cell 3 1"); + add(button3, "cell 4 1"); //---- button4 ---- button4.setText("Help"); diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd index c778d423..469a8884 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -54,12 +54,27 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 1" } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "button5" + "text": "square" + "$client.JButton.buttonType": "square" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 1" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "button6" + "text": "square" + "enabled": false + "$client.JButton.buttonType": "square" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 1" + } ) add( new FormComponent( "javax.swing.JButton" ) { name: "button3" "text": "Help" "$client.JButton.buttonType": "help" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 3 1" + "value": "cell 4 1" } ) add( new FormComponent( "javax.swing.JButton" ) { name: "button4" diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java index 90c710e6..07aa13de 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java @@ -61,7 +61,9 @@ public class FlatComponentsTest JLabel label2 = new JLabel(); JLabel buttonLabel = new JLabel(); JButton button1 = new JButton(); + JButton button17 = new JButton(); JButton button2 = new JButton(); + JButton button18 = new JButton(); FlatComponentsTest.TestDefaultButton button5 = new FlatComponentsTest.TestDefaultButton(); JButton button3 = new JButton(); JButton button12 = new JButton(); @@ -71,7 +73,9 @@ public class FlatComponentsTest JButton button16 = new JButton(); JLabel toggleButtonLabel = new JLabel(); JToggleButton toggleButton1 = new JToggleButton(); + JToggleButton toggleButton9 = new JToggleButton(); JToggleButton toggleButton2 = new JToggleButton(); + JToggleButton toggleButton10 = new JToggleButton(); JToggleButton toggleButton3 = new JToggleButton(); JToggleButton toggleButton4 = new JToggleButton(); JLabel checkBoxLabel = new JLabel(); @@ -249,6 +253,11 @@ public class FlatComponentsTest button1.setToolTipText("This button is enabled."); add(button1, "cell 1 1"); + //---- button17 ---- + button17.setText("square"); + button17.putClientProperty("JButton.buttonType", "square"); + add(button17, "cell 1 1"); + //---- button2 ---- button2.setText("disabled"); button2.setDisplayedMnemonicIndex(0); @@ -256,6 +265,12 @@ public class FlatComponentsTest button2.setToolTipText("This button is disabled."); add(button2, "cell 2 1"); + //---- button18 ---- + button18.setText("square"); + button18.putClientProperty("JButton.buttonType", "square"); + button18.setEnabled(false); + add(button18, "cell 2 1"); + //---- button5 ---- button5.setText("default"); button5.setDisplayedMnemonicIndex(0); @@ -297,11 +312,22 @@ public class FlatComponentsTest toggleButton1.setText("enabled"); add(toggleButton1, "cell 1 2"); + //---- toggleButton9 ---- + toggleButton9.setText("square"); + toggleButton9.putClientProperty("JButton.buttonType", "square"); + add(toggleButton9, "cell 1 2"); + //---- toggleButton2 ---- toggleButton2.setText("disabled"); toggleButton2.setEnabled(false); add(toggleButton2, "cell 2 2"); + //---- toggleButton10 ---- + toggleButton10.setText("square"); + toggleButton10.putClientProperty("JButton.buttonType", "square"); + toggleButton10.setEnabled(false); + add(toggleButton10, "cell 2 2"); + //---- toggleButton3 ---- toggleButton3.setText("selected"); toggleButton3.setSelected(true); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd index 0ab48b7e..2f32943f 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd @@ -47,6 +47,13 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1" } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "button17" + "text": "square" + "$client.JButton.buttonType": "square" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) add( new FormComponent( "javax.swing.JButton" ) { name: "button2" "text": "disabled" @@ -56,6 +63,14 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 1" } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "button18" + "text": "square" + "$client.JButton.buttonType": "square" + "enabled": false + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 1" + } ) add( new FormComponent( "com.formdev.flatlaf.testing.FlatComponentsTest$TestDefaultButton" ) { name: "button5" "text": "default" @@ -115,6 +130,13 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 2" } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "toggleButton9" + "text": "square" + "$client.JButton.buttonType": "square" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "toggleButton2" "text": "disabled" @@ -122,6 +144,14 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 2" } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "toggleButton10" + "text": "square" + "$client.JButton.buttonType": "square" + "enabled": false + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 2" + } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "toggleButton3" "text": "selected" @@ -935,7 +965,7 @@ new FormModel { } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) - "size": new java.awt.Dimension( 865, 800 ) + "size": new java.awt.Dimension( 1005, 800 ) } ) } } From dfccabc2b980d75203bbc68f7fc3dc5552df72d3 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 8 Jan 2020 14:18:17 +0100 Subject: [PATCH 17/46] ToggleButton: support underline toggle button style --- CHANGELOG.md | 2 + .../formdev/flatlaf/FlatClientProperties.java | 9 +++ .../formdev/flatlaf/ui/FlatButtonBorder.java | 2 +- .../com/formdev/flatlaf/ui/FlatButtonUI.java | 71 ++++++++++--------- .../flatlaf/ui/FlatToggleButtonUI.java | 56 +++++++++++++++ .../com/formdev/flatlaf/FlatLaf.properties | 8 +++ .../flatlaf/testing/FlatComponentsTest.java | 15 ++++ .../flatlaf/testing/FlatComponentsTest.jfd | 17 +++++ 8 files changed, 145 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dca90d4..8fdb69bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ FlatLaf Change Log - Label and ToolTip: Fixed font sizes for HTML headings. - Button and ToggleButton: Support square button style (set client property `JButton.buttonType` to `square`). +- ToggleButton: Support underline toggle button style (set client property + `JButton.buttonType` to `underline`). ## 0.23.1 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 3d0bc85d..8048c6d0 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -42,6 +42,15 @@ public interface FlatClientProperties */ String BUTTON_TYPE_SQUARE = "square"; + /** + * Paint the toggle button in underline style. + *

+ * Components {@link javax.swing.JToggleButton} + * + * @see #TOGGLE_BUTTON_TYPE + */ + String BUTTON_TYPE_UNDERLINE = "underline"; + /** * Paint a help button (circle with question mark). *

diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java index a0341619..70156a6c 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java @@ -65,7 +65,7 @@ public class FlatButtonBorder @Override public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { - if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) ) + if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) && !FlatToggleButtonUI.isUnderlineButton( c ) ) super.paintBorder( c, g, x, y, width, height ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java index 9eadebee..f1b41324 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java @@ -232,44 +232,47 @@ public class FlatButtonUI return; } - if( isContentAreaFilled( c ) ) { - Color background = getBackground( c ); - if( background != null ) { - Graphics2D g2 = (Graphics2D) g.create(); - try { - FlatUIUtils.setRenderingHints( g2 ); - - Border border = c.getBorder(); - float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0; - float arc = ((border instanceof FlatButtonBorder && !isSquareButton( c )) || isToolBarButton( c )) - ? scale( (float) this.arc ) : 0; - boolean def = isDefaultButton( c ); - - // paint shadow - Color shadowColor = def ? defaultShadowColor : this.shadowColor; - if( shadowColor != null && shadowWidth > 0 && focusWidth > 0 && !c.hasFocus() && c.isEnabled() ) { - g2.setColor( shadowColor ); - g2.fill( new RoundRectangle2D.Float( focusWidth, focusWidth + UIScale.scale( (float) shadowWidth ), - c.getWidth() - focusWidth * 2, c.getHeight() - focusWidth * 2, arc, arc ) ); - } - - // paint background - Color startBg = def ? defaultBackground : startBackground; - Color endBg = def ? defaultEndBackground : endBackground; - if( background == startBg && endBg != null && !startBg.equals( endBg ) ) - g2.setPaint( new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ) ); - else - FlatUIUtils.setColor( g2, background, def ? defaultBackground : c.getBackground() ); - FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc ); - } finally { - g2.dispose(); - } - } - } + if( isContentAreaFilled( c ) ) + paintBackground( g, c ); paint( g, c ); } + protected void paintBackground( Graphics g, JComponent c ) { + Color background = getBackground( c ); + if( background != null ) { + Graphics2D g2 = (Graphics2D) g.create(); + try { + FlatUIUtils.setRenderingHints( g2 ); + + Border border = c.getBorder(); + float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0; + float arc = ((border instanceof FlatButtonBorder && !isSquareButton( c )) || isToolBarButton( c )) + ? scale( (float) this.arc ) : 0; + boolean def = isDefaultButton( c ); + + // paint shadow + Color shadowColor = def ? defaultShadowColor : this.shadowColor; + if( shadowColor != null && shadowWidth > 0 && focusWidth > 0 && !c.hasFocus() && c.isEnabled() ) { + g2.setColor( shadowColor ); + g2.fill( new RoundRectangle2D.Float( focusWidth, focusWidth + UIScale.scale( (float) shadowWidth ), + c.getWidth() - focusWidth * 2, c.getHeight() - focusWidth * 2, arc, arc ) ); + } + + // paint background + Color startBg = def ? defaultBackground : startBackground; + Color endBg = def ? defaultEndBackground : endBackground; + if( background == startBg && endBg != null && !startBg.equals( endBg ) ) + g2.setPaint( new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ) ); + else + FlatUIUtils.setColor( g2, background, def ? defaultBackground : c.getBackground() ); + FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc ); + } finally { + g2.dispose(); + } + } + } + @Override protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) { if( isHelpButton( b ) ) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java index e35a390b..97f390ac 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java @@ -16,12 +16,17 @@ package com.formdev.flatlaf.ui; +import static com.formdev.flatlaf.FlatClientProperties.*; import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.JComponent; +import javax.swing.JToggleButton; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +import com.formdev.flatlaf.util.UIScale; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JToggleButton}. @@ -55,6 +60,13 @@ import javax.swing.plaf.ComponentUI; * @uiDefault ToggleButton.disabledSelectedBackground Color * @uiDefault ToggleButton.toolbar.selectedBackground Color * + * @uiDefault ToggleButton.underline.underlineHeight int + * @uiDefault ToggleButton.underline.underlineColor Color + * @uiDefault ToggleButton.underline.disabledUnderlineColor Color + * @uiDefault ToggleButton.underline.selectedBackground Color optional + * @uiDefault ToggleButton.underline.hoverBackground Color + * @uiDefault ToggleButton.underline.focusBackground Color + * * * @author Karl Tauber */ @@ -67,6 +79,13 @@ public class FlatToggleButtonUI protected Color toolbarSelectedBackground; + protected int underlineHeight; + protected Color underlineColor; + protected Color disabledUnderlineColor; + protected Color underlineSelectedBackground; + protected Color underlineHoverBackground; + protected Color underlineFocusBackground; + private boolean defaults_initialized = false; private static ComponentUI instance; @@ -93,6 +112,13 @@ public class FlatToggleButtonUI toolbarSelectedBackground = UIManager.getColor( "ToggleButton.toolbar.selectedBackground" ); + underlineHeight = UIManager.getInt( "ToggleButton.underline.underlineHeight" ); + underlineColor = UIManager.getColor( "ToggleButton.underline.underlineColor" ); + disabledUnderlineColor = UIManager.getColor( "ToggleButton.underline.disabledUnderlineColor" ); + underlineSelectedBackground = UIManager.getColor( "ToggleButton.underline.selectedBackground" ); + underlineHoverBackground = UIManager.getColor( "ToggleButton.underline.hoverBackground" ); + underlineFocusBackground = UIManager.getColor( "ToggleButton.underline.focusBackground" ); + defaults_initialized = true; } } @@ -103,6 +129,36 @@ public class FlatToggleButtonUI defaults_initialized = false; } + static boolean isUnderlineButton( Component c ) { + return c instanceof JToggleButton && clientPropertyEquals( (JToggleButton) c, BUTTON_TYPE, BUTTON_TYPE_UNDERLINE ); + } + + @Override + protected void paintBackground( Graphics g, JComponent c ) { + if( isUnderlineButton( c ) ) { + int height = c.getHeight(); + int width = c.getWidth(); + boolean selected = ((AbstractButton)c).isSelected(); + + // paint background + Color background = buttonStateColor( c, + selected ? underlineSelectedBackground : null, + null, underlineFocusBackground, underlineHoverBackground, null ); + if( background != null ) { + g.setColor( background ); + g.fillRect( 0, 0, width, height ); + } + + // paint underline if selected + if( selected ) { + int underlineHeight = UIScale.scale( this.underlineHeight ); + g.setColor( c.isEnabled() ? underlineColor : disabledUnderlineColor ); + g.fillRect( 0, height - underlineHeight, width, underlineHeight ); + } + } else + super.paintBackground( g, c ); + } + @Override protected Color getBackground( JComponent c ) { ButtonModel model = ((AbstractButton)c).getModel(); diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 16426537..0940c8e1 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -435,6 +435,14 @@ ToggleButton.pressedBackground=$Button.pressedBackground ToggleButton.toolbar.hoverBackground=$Button.toolbar.hoverBackground ToggleButton.toolbar.pressedBackground=$Button.toolbar.pressedBackground +# button type "underline" +ToggleButton.underline.underlineHeight=2 +ToggleButton.underline.underlineColor=$TabbedPane.underlineColor +ToggleButton.underline.disabledUnderlineColor=$TabbedPane.disabledUnderlineColor +ToggleButton.underline.selectedBackground=$?TabbedPane.selectedBackground +ToggleButton.underline.hoverBackground=$TabbedPane.hoverColor +ToggleButton.underline.focusBackground=$TabbedPane.focusColor + #---- ToolBar ---- diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java index 07aa13de..0dac7e91 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java @@ -78,6 +78,8 @@ public class FlatComponentsTest JToggleButton toggleButton10 = new JToggleButton(); JToggleButton toggleButton3 = new JToggleButton(); JToggleButton toggleButton4 = new JToggleButton(); + JToggleButton toggleButton5 = new JToggleButton(); + JToggleButton toggleButton8 = new JToggleButton(); JLabel checkBoxLabel = new JLabel(); JCheckBox checkBox1 = new JCheckBox(); JCheckBox checkBox2 = new JCheckBox(); @@ -339,6 +341,19 @@ public class FlatComponentsTest toggleButton4.setSelected(true); add(toggleButton4, "cell 4 2"); + //---- toggleButton5 ---- + toggleButton5.setText("underline"); + toggleButton5.putClientProperty("JButton.buttonType", "underline"); + toggleButton5.setSelected(true); + add(toggleButton5, "cell 5 2"); + + //---- toggleButton8 ---- + toggleButton8.setText("underline"); + toggleButton8.putClientProperty("JButton.buttonType", "underline"); + toggleButton8.setEnabled(false); + toggleButton8.setSelected(true); + add(toggleButton8, "cell 5 2"); + //---- checkBoxLabel ---- checkBoxLabel.setText("JCheckBox"); add(checkBoxLabel, "cell 0 3"); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd index 2f32943f..9f358bfb 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd @@ -167,6 +167,23 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 4 2" } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "toggleButton5" + "text": "underline" + "$client.JButton.buttonType": "underline" + "selected": true + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 2" + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "toggleButton8" + "text": "underline" + "$client.JButton.buttonType": "underline" + "enabled": false + "selected": true + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 2" + } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "checkBoxLabel" "text": "JCheckBox" From 3f3884193d0530f32e9b01c826811b4e94ed9ac1 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 8 Jan 2020 14:47:40 +0100 Subject: [PATCH 18/46] Button and TextComponent: support per component minimum width --- CHANGELOG.md | 2 ++ .../java/com/formdev/flatlaf/FlatClientProperties.java | 8 ++++++++ .../main/java/com/formdev/flatlaf/ui/FlatButtonUI.java | 2 +- .../java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java | 1 + .../java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java | 1 + .../main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java | 1 + .../main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java | 1 + .../main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java | 1 + .../main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java | 1 + .../src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java | 6 ++++++ .../com/formdev/flatlaf/testing/FlatComponentsTest.java | 2 ++ .../com/formdev/flatlaf/testing/FlatComponentsTest.jfd | 2 ++ 12 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fdb69bc..e9120fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ FlatLaf Change Log `JButton.buttonType` to `square`). - ToggleButton: Support underline toggle button style (set client property `JButton.buttonType` to `underline`). +- Button and TextComponent: Support per component minimum width (set client + property `JComponent.minimumWidth` to an integer). ## 0.23.1 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 8048c6d0..d6952d0e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -76,6 +76,14 @@ public interface FlatClientProperties */ String SELECTED_STATE_INDETERMINATE = "indeterminate"; + /** + * Specifies minimum width of a component. + *

+ * Component {@link javax.swing.JButton} and {@link javax.swing.text.JTextComponent}
+ * Value type {@link java.lang.Integer}
+ */ + String MINIMUM_WIDTH = "JComponent.minimumWidth"; + /** * Specifies whether the decrease/increase arrow buttons of a scrollbar are shown. *

diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java index f1b41324..dd9cd90b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java @@ -363,7 +363,7 @@ public class FlatButtonUI if( isIconOnlyButton( c ) ) prefSize.width = Math.max( prefSize.width, prefSize.height ); else if( !isToolBarButton( c ) ) - prefSize.width = Math.max( prefSize.width, scale( minimumWidth + (focusWidth * 2) ) ); + prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) + (focusWidth * 2) ) ); return prefSize; } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java index 75dfde0f..0bfe034b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatEditorPaneUI.java @@ -98,6 +98,7 @@ public class FlatEditorPaneUI // and subtract 1px border line width. // Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding // issues. E.g. at scale factor 1.5 the first returns 4, but the second 3. + int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth ); size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); return size; } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java index 0894bc46..40fe9586 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPasswordFieldUI.java @@ -147,6 +147,7 @@ public class FlatPasswordFieldUI } private Dimension applyMinimumWidth( Dimension size, JComponent c ) { + int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth ); int focusWidth = (c.getBorder() instanceof FlatBorder) ? this.focusWidth : 0; size.width = Math.max( size.width, scale( minimumWidth + (focusWidth * 2) ) ); return size; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java index f64ce2b3..8c0e20ee 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java @@ -326,6 +326,7 @@ public class FlatSpinnerUI Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 ); // the arrows width is the same as the inner height so that the arrows area is square + int minimumWidth = FlatUIUtils.minimumWidth( spinner, FlatSpinnerUI.this.minimumWidth ); int innerHeight = editorSize.height + padding.top + padding.bottom; return new Dimension( Math.max( insets.left + insets.right + editorSize.width + padding.left + padding.right + innerHeight, scale( minimumWidth + (focusWidth * 2) ) ), diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java index a7d2ffb7..4cc5c109 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextAreaUI.java @@ -117,6 +117,7 @@ public class FlatTextAreaUI // and subtract 1px border line width. // Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding // issues. E.g. at scale factor 1.5 the first returns 4, but the second 3. + int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth ); size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); return size; } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java index d74dabf1..47f97005 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java @@ -217,6 +217,7 @@ public class FlatTextFieldUI (parent != null && parent.getParent() instanceof JSpinner) ) return size; + int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth ); int focusWidth = (c.getBorder() instanceof FlatBorder) ? this.focusWidth : 0; size.width = Math.max( size.width, scale( minimumWidth + (focusWidth * 2) ) ); return size; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java index dc3a196c..b6c70926 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextPaneUI.java @@ -98,6 +98,7 @@ public class FlatTextPaneUI // and subtract 1px border line width. // Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding // issues. E.g. at scale factor 1.5 the first returns 4, but the second 3. + int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth ); size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); return size; } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 13f8d2d3..b12af8e1 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -38,6 +38,7 @@ import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.UIManager; import javax.swing.plaf.ColorUIResource; +import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.util.DerivedColor; import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.JavaCompatibility; @@ -111,6 +112,11 @@ public class FlatUIUtils return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c; } + public static int minimumWidth( JComponent c, int minimumWidth ) { + Object p = c.getClientProperty( FlatClientProperties.MINIMUM_WIDTH ); + return (p instanceof Integer) ? ((Integer)p).intValue() : minimumWidth; + } + public static boolean isTableCellEditor( Component c ) { return c instanceof JComponent && Boolean.TRUE.equals( ((JComponent)c).getClientProperty( "JComboBox.isTableCellEditor" ) ); } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java index 0dac7e91..e7c1c58a 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java @@ -258,6 +258,7 @@ public class FlatComponentsTest //---- button17 ---- button17.setText("square"); button17.putClientProperty("JButton.buttonType", "square"); + button17.putClientProperty("JComponent.minimumWidth", 0); add(button17, "cell 1 1"); //---- button2 ---- @@ -271,6 +272,7 @@ public class FlatComponentsTest button18.setText("square"); button18.putClientProperty("JButton.buttonType", "square"); button18.setEnabled(false); + button18.putClientProperty("JComponent.minimumWidth", 0); add(button18, "cell 2 1"); //---- button5 ---- diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd index 9f358bfb..61ac0eeb 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd @@ -51,6 +51,7 @@ new FormModel { name: "button17" "text": "square" "$client.JButton.buttonType": "square" + "$client.JComponent.minimumWidth": 0 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1" } ) @@ -68,6 +69,7 @@ new FormModel { "text": "square" "$client.JButton.buttonType": "square" "enabled": false + "$client.JComponent.minimumWidth": 0 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 1" } ) From e7d5e22960dcc618593c203a1ff02d06dac8e5d6 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 8 Jan 2020 15:27:31 +0100 Subject: [PATCH 19/46] IntelliJ Themes Demo: fixed last invalid colors in Material UI Lite themes (issue #26) --- .../Material Darker Contrast.theme.json | 6 +++--- .../material-theme-ui-lite/Material Darker.theme.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json index df2a38ab..226b14d3 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker Contrast.theme.json @@ -294,7 +294,7 @@ "selectionBackground": "#40404050", "selectionForeground": "#FFFFFF", "selectionInactiveForeground": "#FFFFFF", - "selectionInactiveBackground": "#3232327025" + "selectionInactiveBackground": "#32323225" }, "material": { "background": "#212121", @@ -746,10 +746,10 @@ "hash": "#292929", "modifiedItemForeground": "#FF9800", "rowHeight": 28, - "selectionBackground": "#3232327070", + "selectionBackground": "#32323270", "selectionForeground": "#FFFFFF", "selectionInactiveForeground": "#FFFFFF", - "selectionInactiveBackground": "#3232327025", + "selectionInactiveBackground": "#32323225", "textBackground": "#1A1A1A" }, "Tree.leftChildIndent": 10, diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json index fcefe47b..9b1c3dc6 100644 --- a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/intellijthemes/material-theme-ui-lite/Material Darker.theme.json @@ -294,7 +294,7 @@ "selectionBackground": "#40404050", "selectionForeground": "#FFFFFF", "selectionInactiveForeground": "#FFFFFF", - "selectionInactiveBackground": "#3232327025" + "selectionInactiveBackground": "#32323225" }, "material": { "background": "#212121", @@ -746,10 +746,10 @@ "hash": "#292929", "modifiedItemForeground": "#FF9800", "rowHeight": 28, - "selectionBackground": "#3232327070", + "selectionBackground": "#32323270", "selectionForeground": "#FFFFFF", "selectionInactiveForeground": "#FFFFFF", - "selectionInactiveBackground": "#3232327025", + "selectionInactiveBackground": "#32323225", "textBackground": "#212121" }, "Tree.leftChildIndent": 10, From 41e2888bf196eb5e1d63f755cb2731857c58e25a Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 8 Jan 2020 23:25:57 +0100 Subject: [PATCH 20/46] ScrollPane with Table: The border of buttons that are added to one of the four scroll pane corners are now removed if the center component is a table. Also, these corner buttons are made not focusable. --- CHANGELOG.md | 3 ++ .../formdev/flatlaf/ui/FlatScrollPaneUI.java | 44 ++++++++++++++----- .../flatlaf/testing/FlatComponents2Test.java | 25 ++++++++++- .../flatlaf/testing/FlatComponents2Test.jfd | 17 ++++++- 4 files changed, 74 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9120fb5..0abc5f73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ FlatLaf Change Log `JButton.buttonType` to `underline`). - Button and TextComponent: Support per component minimum width (set client property `JComponent.minimumWidth` to an integer). +- ScrollPane with Table: The border of buttons that are added to one of the four + scroll pane corners are now removed if the center component is a table. Also, + these corner buttons are made not focusable. ## 0.23.1 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java index 84fc4583..31481542 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java @@ -25,11 +25,15 @@ import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.BorderFactory; +import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; +import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.LookAndFeel; +import javax.swing.ScrollPaneConstants; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicScrollPaneUI; @@ -97,17 +101,35 @@ public class FlatScrollPaneUI public void propertyChange( PropertyChangeEvent e ) { super.propertyChange( e ); - if( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS.equals( e.getPropertyName() ) ) { - JScrollBar vsb = scrollpane.getVerticalScrollBar(); - JScrollBar hsb = scrollpane.getHorizontalScrollBar(); - if( vsb != null ) { - vsb.revalidate(); - vsb.repaint(); - } - if( hsb != null ) { - hsb.revalidate(); - hsb.repaint(); - } + switch( e.getPropertyName() ) { + case FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS: + JScrollBar vsb = scrollpane.getVerticalScrollBar(); + JScrollBar hsb = scrollpane.getHorizontalScrollBar(); + if( vsb != null ) { + vsb.revalidate(); + vsb.repaint(); + } + if( hsb != null ) { + hsb.revalidate(); + hsb.repaint(); + } + break; + + case ScrollPaneConstants.LOWER_LEFT_CORNER: + case ScrollPaneConstants.LOWER_RIGHT_CORNER: + case ScrollPaneConstants.UPPER_LEFT_CORNER: + case ScrollPaneConstants.UPPER_RIGHT_CORNER: + // remove border from buttons added to corners + Object corner = e.getNewValue(); + if( corner instanceof JButton && + ((JButton)corner).getBorder() instanceof FlatButtonBorder && + scrollpane.getViewport() != null && + scrollpane.getViewport().getView() instanceof JTable ) + { + ((JButton)corner).setBorder( BorderFactory.createEmptyBorder() ); + ((JButton)corner).setFocusable( false ); + } + break; } } }; diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java index f050e511..56d3f67c 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java @@ -21,6 +21,7 @@ import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import javax.swing.*; import javax.swing.table.*; +import com.formdev.flatlaf.icons.FlatMenuArrowIcon; import net.miginfocom.swing.*; /** @@ -70,6 +71,18 @@ public class FlatComponents2Test } } + private void tableHeaderButtonChanged() { + boolean show = tableHeaderButtonCheckBox.isSelected(); + JButton button = null; + if( show ) { + button = new JButton( new FlatMenuArrowIcon() ); + button.addActionListener( e -> { + JOptionPane.showMessageDialog( this, "hello" ); + } ); + } + scrollPane5.setCorner( JScrollPane.UPPER_TRAILING_CORNER, button ); + } + @SuppressWarnings( { "unchecked", "rawtypes" } ) private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @@ -87,9 +100,10 @@ public class FlatComponents2Test JScrollPane scrollPane4 = new JScrollPane(); tree2 = new JTree(); JLabel tableLabel = new JLabel(); - JScrollPane scrollPane5 = new JScrollPane(); + scrollPane5 = new JScrollPane(); table1 = new JTable(); dndCheckBox = new JCheckBox(); + tableHeaderButtonCheckBox = new JCheckBox(); //======== this ======== setLayout(new MigLayout( @@ -102,7 +116,7 @@ public class FlatComponents2Test "[]" + "[]" + "[::200]" + - "[::150]" + + "[150,grow]" + "[]")); //---- textFieldLabel ---- @@ -293,6 +307,11 @@ public class FlatComponents2Test dndCheckBox.setMnemonic('D'); dndCheckBox.addActionListener(e -> dndChanged()); add(dndCheckBox, "cell 0 4 3 1"); + + //---- tableHeaderButtonCheckBox ---- + tableHeaderButtonCheckBox.setText("show button in table header"); + tableHeaderButtonCheckBox.addActionListener(e -> tableHeaderButtonChanged()); + add(tableHeaderButtonCheckBox, "cell 0 4 3 1"); // JFormDesigner - End of component initialization //GEN-END:initComponents ((JComboBox)((DefaultCellEditor)table1.getColumnModel().getColumn( 3 ).getCellEditor()).getComponent()).setEditable( true ); @@ -303,8 +322,10 @@ public class FlatComponents2Test private JList list2; private JTree tree1; private JTree tree2; + private JScrollPane scrollPane5; private JTable table1; private JCheckBox dndCheckBox; + private JCheckBox tableHeaderButtonCheckBox; // JFormDesigner - End of variables declaration //GEN-END:variables //---- class DummyTransferHandler ----------------------------------------- diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd index 62f281b8..7b992ea7 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -9,7 +9,7 @@ new FormModel { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "ltr,insets dialog,hidemode 3" "$columnConstraints": "[][200][200]" - "$rowConstraints": "[][][::200][::150][]" + "$rowConstraints": "[][][::200][150,grow][]" } ) { name: "this" add( new FormComponent( "javax.swing.JLabel" ) { @@ -135,6 +135,9 @@ new FormModel { } ) add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { name: "scrollPane5" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } add( new FormComponent( "javax.swing.JTable" ) { name: "table1" "model": new com.jformdesigner.model.SwingTableModel( new java.util.Vector { @@ -282,6 +285,16 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 4 3 1" } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "tableHeaderButtonCheckBox" + "text": "show button in table header" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tableHeaderButtonChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4 3 1" + } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) "size": new java.awt.Dimension( 790, 715 ) From 43ab095e0f8f3933d0ffc8313e05368fc97e8b28 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 9 Jan 2020 20:55:55 +0100 Subject: [PATCH 21/46] Table: replaced `Table.showGrid` with `Table.showHorizontalLines` and `Table.showVerticalLines` (issue #38) --- CHANGELOG.md | 2 ++ .../com/formdev/flatlaf/ui/FlatTableUI.java | 36 ++++++++++--------- .../com/formdev/flatlaf/FlatLaf.properties | 3 +- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0abc5f73..c8801d51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ FlatLaf Change Log - ScrollPane with Table: The border of buttons that are added to one of the four scroll pane corners are now removed if the center component is a table. Also, these corner buttons are made not focusable. +- Table: Replaced `Table.showGrid` with `Table.showHorizontalLines` and + `Table.showVerticalLines`. (issue #38) ## 0.23.1 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java index 3e7c31bb..bee64c09 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java @@ -56,7 +56,8 @@ import com.formdev.flatlaf.util.UIScale; * * * @uiDefault Table.rowHeight int - * @uiDefault Table.showGrid boolean + * @uiDefault Table.showHorizontalLines boolean + * @uiDefault Table.showVerticalLines boolean * @uiDefault Table.intercellSpacing Dimension * @uiDefault Table.selectionInactiveBackground Color * @uiDefault Table.selectionInactiveForeground Color @@ -72,7 +73,8 @@ import com.formdev.flatlaf.util.UIScale; public class FlatTableUI extends BasicTableUI { - protected boolean showGrid; + protected boolean showHorizontalLines; + protected boolean showVerticalLines; protected Dimension intercellSpacing; protected Color selectionBackground; @@ -102,7 +104,8 @@ public class FlatTableUI protected void installDefaults() { super.installDefaults(); - showGrid = UIManager.getBoolean( "Table.showGrid" ); + showHorizontalLines = UIManager.getBoolean( "Table.showHorizontalLines" ); + showVerticalLines = UIManager.getBoolean( "Table.showVerticalLines" ); intercellSpacing = UIManager.getDimension( "Table.intercellSpacing" ); selectionBackground = UIManager.getColor( "Table.selectionBackground" ); @@ -116,10 +119,13 @@ public class FlatTableUI if( rowHeight > 0 ) LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) ); - if( !showGrid ) { + if( !showHorizontalLines ) { oldShowHorizontalLines = table.getShowHorizontalLines(); + table.setShowHorizontalLines( false ); + } + if( !showVerticalLines ) { oldShowVerticalLines = table.getShowVerticalLines(); - table.setShowGrid( false ); + table.setShowVerticalLines( false ); } if( intercellSpacing != null ) { @@ -137,19 +143,15 @@ public class FlatTableUI selectionInactiveBackground = null; selectionInactiveForeground = null; - // restore old show grid - if( !showGrid ) { - if( !table.getShowHorizontalLines() ) - table.setShowHorizontalLines( oldShowHorizontalLines ); - if( !table.getShowVerticalLines() ) - table.setShowVerticalLines( oldShowVerticalLines ); - } + // restore old show horizontal/vertical lines (if not modified) + if( !showHorizontalLines && oldShowHorizontalLines && !table.getShowHorizontalLines() ) + table.setShowHorizontalLines( true ); + if( !showVerticalLines && oldShowVerticalLines && !table.getShowVerticalLines() ) + table.setShowVerticalLines( true ); - // restore old intercell spacing - if( intercellSpacing != null ) { - if( table.getIntercellSpacing().equals( intercellSpacing ) ) - table.setIntercellSpacing( oldIntercellSpacing ); - } + // restore old intercell spacing (if not modified) + if( intercellSpacing != null && table.getIntercellSpacing().equals( intercellSpacing ) ) + table.setIntercellSpacing( oldIntercellSpacing ); } @Override diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 0940c8e1..111ed511 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -369,7 +369,8 @@ TabbedPane.shadow=$ComboBox.buttonArrowColor #---- Table ---- Table.rowHeight=20 -Table.showGrid=false +Table.showHorizontalLines=false +Table.showVerticalLines=false Table.intercellSpacing={dimension}0,0 Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon From fd9dbbd7e6485be1440894f1f985dd63ae521259 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 9 Jan 2020 23:43:58 +0100 Subject: [PATCH 22/46] support smooth scrolling with touchpads and high precision mouse wheels (issue #27) --- CHANGELOG.md | 2 + .../formdev/flatlaf/ui/FlatScrollPaneUI.java | 139 ++++++++++++++++++ .../com/formdev/flatlaf/FlatLaf.properties | 1 + 3 files changed, 142 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8801d51..793df496 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ FlatLaf Change Log ## Unreleased +- Support smooth scrolling with touchpads and high precision mouse wheels. + (issue #27) - Changed `.properties` file loading order: Now all core `.properties` files are loaded before loading addon `.properties` files. This makes it easier to overwrite core values in addons. Also, addon loading order can be specified. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java index 31481542..1a118dbb 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java @@ -14,15 +14,24 @@ * limitations under the License. */ +/* + * Smooth scrolling code partly based on code from IntelliJ IDEA Community Edition, + * which is licensed under the Apache 2.0 license. Copyright 2000-2016 JetBrains s.r.o. + * See: https://github.com/JetBrains/intellij-community/blob/31e1b5a8e43219b9571951bab6457cfb3012e3ef/platform/platform-api/src/com/intellij/ui/components/SmoothScrollPane.java#L141-L185 + * + */ package com.formdev.flatlaf.ui; import java.awt.Component; import java.awt.Graphics; import java.awt.Insets; +import java.awt.Rectangle; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.BorderFactory; @@ -34,6 +43,8 @@ import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.LookAndFeel; import javax.swing.ScrollPaneConstants; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicScrollPaneUI; @@ -50,6 +61,10 @@ import com.formdev.flatlaf.FlatClientProperties; * @uiDefault ScrollPane.border Border * @uiDefault ScrollPane.viewportBorder Border * + * + * + * @uiDefault ScrollPane.smoothScrolling boolean + * * @author Karl Tauber */ public class FlatScrollPaneUI @@ -94,6 +109,130 @@ public class FlatScrollPaneUI handler = null; } + @Override + protected MouseWheelListener createMouseWheelListener() { + return new BasicScrollPaneUI.MouseWheelHandler() { + @Override + public void mouseWheelMoved( MouseWheelEvent e ) { + // Note: Getting UI value "ScrollPane.smoothScrolling" here to allow + // applications to turn smooth scrolling on or off at any time + // (e.g. in application options dialog). + if( UIManager.getBoolean( "ScrollPane.smoothScrolling" ) && + scrollpane.isWheelScrollingEnabled() && + e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL && + e.getPreciseWheelRotation() != 0 && + e.getPreciseWheelRotation() != e.getWheelRotation() ) + { + mouseWheelMovedSmooth( e ); + } else + super.mouseWheelMoved( e ); + } + }; + } + + private static final double EPSILON = 1e-5d; + + private void mouseWheelMovedSmooth( MouseWheelEvent e ) { + // return if there is no viewport + JViewport viewport = scrollpane.getViewport(); + if( viewport == null ) + return; + + // find scrollbar to scroll + JScrollBar scrollbar = scrollpane.getVerticalScrollBar(); + if( scrollbar == null || !scrollbar.isVisible() || e.isShiftDown() ) { + scrollbar = scrollpane.getHorizontalScrollBar(); + if( scrollbar == null || !scrollbar.isVisible() ) + return; + } + + // consume event + e.consume(); + + // get precise wheel rotation + double rotation = e.getPreciseWheelRotation(); + + // get unit and block increment + int unitIncrement; + int blockIncrement; + int orientation = scrollbar.getOrientation(); + Component view = viewport.getView(); + if( view instanceof Scrollable ) { + Scrollable scrollable = (Scrollable) view; + + // Use (0, 0) view position to obtain constant unit increment of first item + // (which might otherwise be variable on smaller-than-unit scrolling). + Rectangle visibleRect = new Rectangle( viewport.getViewSize() ); + unitIncrement = scrollable.getScrollableUnitIncrement( visibleRect, orientation, 1 ); + blockIncrement = scrollable.getScrollableBlockIncrement( visibleRect, orientation, 1 ); + + if( unitIncrement > 0 ) { + // For the case that the first item (e.g. in a list) is larger + // than the other items, get the unit increment of the second item + // and use the smaller one. + if( orientation == SwingConstants.VERTICAL ) { + visibleRect.y += unitIncrement; + visibleRect.height -= unitIncrement; + } else { + visibleRect.x += unitIncrement; + visibleRect.width -= unitIncrement; + } + int unitIncrement2 = scrollable.getScrollableUnitIncrement( visibleRect, orientation, 1 ); + if( unitIncrement2 > 0 ) + unitIncrement = Math.min( unitIncrement, unitIncrement2 ); + } + } else { + int direction = rotation < 0 ? -1 : 1; + unitIncrement = scrollbar.getUnitIncrement( direction ); + blockIncrement = scrollbar.getBlockIncrement( direction ); + } + + // limit scroll amount (number of units to scroll) for small viewports + // (e.g. vertical scrolling in file chooser) + int scrollAmount = e.getScrollAmount(); + int viewportWH = (orientation == SwingConstants.VERTICAL) + ? viewport.getHeight() + : viewport.getWidth(); + if( unitIncrement * scrollAmount > viewportWH ) + scrollAmount = Math.max( viewportWH / unitIncrement, 1 ); + + // compute relative delta + double delta = rotation * scrollAmount * unitIncrement; + boolean adjustDelta = Math.abs( rotation ) < (1.0 + EPSILON); + double adjustedDelta = adjustDelta + ? Math.max( -blockIncrement, Math.min( delta, blockIncrement ) ) + : delta; + + // compute new value + int value = scrollbar.getValue(); + double minDelta = scrollbar.getMinimum() - value; + double maxDelta = scrollbar.getMaximum() - scrollbar.getModel().getExtent() - value; + double boundedDelta = Math.max( minDelta, Math.min( adjustedDelta, maxDelta ) ); + int newValue = value + (int) Math.round( boundedDelta ); + + // set new value + if( newValue != value ) + scrollbar.setValue( newValue ); + +/*debug + System.out.println( String.format( "%4d %9f / %4d %4d / %12f %5s %12f / %4d %4d %4d / %12f %12f %12f / %4d", + e.getWheelRotation(), + e.getPreciseWheelRotation(), + unitIncrement, + blockIncrement, + delta, + adjustDelta, + adjustedDelta, + value, + scrollbar.getMinimum(), + scrollbar.getMaximum(), + minDelta, + maxDelta, + boundedDelta, + newValue ) ); +*/ + } + @Override protected PropertyChangeListener createPropertyChangeListener() { return new BasicScrollPaneUI.PropertyChangeHandler() { diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 111ed511..065d54ea 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -311,6 +311,7 @@ ScrollBar.buttonDisabledArrowColor=$ComboBox.buttonDisabledArrowColor ScrollPane.border=com.formdev.flatlaf.ui.FlatBorder ScrollPane.background=$ScrollBar.track ScrollPane.fillUpperCorner=true +ScrollPane.smoothScrolling=true #---- Separator ---- From c474565ff521bf47d26a10131e737098beab3102 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 9 Jan 2020 23:54:45 +0100 Subject: [PATCH 23/46] UI inspector: support nested classes --- .../java/com/formdev/flatlaf/testing/FlatInspector.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java index 8dba383d..c197d5e3 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java @@ -245,12 +245,8 @@ public class FlatInspector } private String buildToolTipText( Component c ) { - String name = c.getClass().getSimpleName(); - if( name.isEmpty() ) { - // anonymous class - name = c.getClass().getName(); - name = name.substring( name.lastIndexOf( '.' ) + 1 ); - } + String name = c.getClass().getName(); + name = name.substring( name.lastIndexOf( '.' ) + 1 ); String text = "Class: " + name + " (" + c.getClass().getPackage().getName() + ")\n" + From f2dad88875d0a642d904a7b28b6716749deb9df4 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 10 Jan 2020 00:13:39 +0100 Subject: [PATCH 24/46] ToggleButton: support underline toggle button colors in IntelliJ themes --- .../main/java/com/formdev/flatlaf/IntelliJTheme.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index 468bf58d..7c556807 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -401,9 +401,14 @@ public class IntelliJTheme defaults.remove( "CheckBox.icon.selectedHoverBackground" ); defaults.remove( "CheckBox.icon.selectedPressedBackground" ); } + + // copy values + for( Map.Entry e : uiKeyCopying.entrySet() ) + defaults.put( e.getKey(), defaults.get( e.getValue() ) ); } private static Map uiKeyMapping = new HashMap<>(); + private static Map uiKeyCopying = new HashMap<>(); private static Map uiKeyInverseMapping = new HashMap<>(); private static Map checkboxKeyMapping = new HashMap<>(); private static Map checkboxDuplicateColors = new HashMap<>(); @@ -440,6 +445,12 @@ public class IntelliJTheme for( Map.Entry e : uiKeyMapping.entrySet() ) uiKeyInverseMapping.put( e.getValue(), e.getKey() ); + uiKeyCopying.put( "ToggleButton.underline.underlineColor", "TabbedPane.underlineColor" ); + uiKeyCopying.put( "ToggleButton.underline.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" ); + uiKeyCopying.put( "ToggleButton.underline.selectedBackground", "TabbedPane.selectedBackground" ); + uiKeyCopying.put( "ToggleButton.underline.hoverBackground", "TabbedPane.hoverColor" ); + uiKeyCopying.put( "ToggleButton.underline.focusBackground", "TabbedPane.focusColor" ); + checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" ); checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" ); checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" ); From ab7bbb6593a18f39cd718d10bf7144ded684384a Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 10 Jan 2020 00:28:26 +0100 Subject: [PATCH 25/46] ProgressBar: now uses blueish color for the progress part in "Flat Dark" theme --- CHANGELOG.md | 2 ++ .../resources/com/formdev/flatlaf/FlatDarculaLaf.properties | 6 ++++++ .../resources/com/formdev/flatlaf/FlatDarkLaf.properties | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 793df496..81769d9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ FlatLaf Change Log these corner buttons are made not focusable. - Table: Replaced `Table.showGrid` with `Table.showHorizontalLines` and `Table.showVerticalLines`. (issue #38) +- ProgressBar: Now uses blueish color for the progress part in "Flat Dark" + theme. In the "Flat Darcula" theme, it remains light gray. ## 0.23.1 diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarculaLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarculaLaf.properties index b01fd35a..b7dcf057 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarculaLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarculaLaf.properties @@ -30,6 +30,12 @@ Component.innerFocusWidth=0 Component.arrowType=triangle +#---- ProgressBar ---- + +ProgressBar.foreground=#a0a0a0 +ProgressBar.selectionForeground=@background + + #---- RadioButton ---- RadioButton.icon.centerDiameter=5 diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties index c66fb7f6..d71ebe21 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -161,8 +161,8 @@ PopupMenu.borderColor=#515151 #---- ProgressBar ---- ProgressBar.background=#555555 -ProgressBar.foreground=#a0a0a0 -ProgressBar.selectionForeground=@background +ProgressBar.foreground=#4A88C7 +ProgressBar.selectionForeground=@foreground ProgressBar.selectionBackground=@foreground From ef01f2338454b190d92bcded1801c1f4ac558a82 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 10 Jan 2020 09:47:13 +0100 Subject: [PATCH 26/46] improved Swing system colors `controlHighlight`, `controlLtHighlight`, `controlShadow` and `controlDkShadow` --- CHANGELOG.md | 2 ++ .../resources/com/formdev/flatlaf/FlatDarkLaf.properties | 7 +++---- .../main/resources/com/formdev/flatlaf/FlatLaf.properties | 2 ++ .../resources/com/formdev/flatlaf/FlatLightLaf.properties | 3 +-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81769d9f..091bfce4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ FlatLaf Change Log `Table.showVerticalLines`. (issue #38) - ProgressBar: Now uses blueish color for the progress part in "Flat Dark" theme. In the "Flat Darcula" theme, it remains light gray. +- Improved Swing system colors `controlHighlight`, `controlLtHighlight`, + `controlShadow` and `controlDkShadow`. ## 0.23.1 diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties index d71ebe21..25fda3b0 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -64,10 +64,9 @@ activeCaption=#434E60 inactiveCaption=#393C3D -controlHighlight=#616669 -controlLtHighlight=#303234 -controlShadow=#afb3b5 -controlDkShadow=#d7d9da +controlHighlight=darken($controlShadow,20%) +controlLtHighlight=darken($controlShadow,25%) +controlDkShadow=lighten($controlShadow,10%) #---- Button ---- diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 065d54ea..0c24e127 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -80,6 +80,7 @@ textHighlightText=@selectionForeground textInactiveText=@disabledText control=@background controlText=@foreground +controlShadow=$Component.borderColor scrollbar=$ScrollBar.track info=$ToolTip.background infoText=@foreground @@ -196,6 +197,7 @@ HelpButton.disabledQuestionMarkColor=$CheckBox.icon.disabledCheckmarkColor #---- List ---- List.border=1,0,1,0 +List.border=0,0,0,0 List.cellMargins=1,6,1,6 List.cellFocusColor=@cellFocusColor List.cellNoFocusBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Default diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties index 9733a667..91bc1207 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties @@ -66,8 +66,7 @@ activeCaption=#99b4d1 inactiveCaption=#bfcddb controlHighlight=#e3e3e3 controlLtHighlight=#fff -controlShadow=#a0a0a0 -controlDkShadow=#696969 +controlDkShadow=darken($controlShadow,15%) #---- Button ---- From 2bcdf774ff6f2c4ed0a267082a2c24d019a52499 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 10 Jan 2020 10:02:54 +0100 Subject: [PATCH 27/46] release 0.24 --- CHANGELOG.md | 2 +- README.md | 2 +- build.gradle.kts | 2 +- flatlaf-jide-oss/README.md | 2 +- flatlaf-swingx/README.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 091bfce4..97bf1a82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ FlatLaf Change Log ================== -## Unreleased +## 0.24 - Support smooth scrolling with touchpads and high precision mouse wheels. (issue #27) diff --git a/README.md b/README.md index 37044444..6d2b1811 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ build script: groupId: com.formdev artifactId: flatlaf - version: 0.23.1 + version: 0.24 Otherwise download `flatlaf-.jar` here: diff --git a/build.gradle.kts b/build.gradle.kts index 0a0cbf90..ad8ba89f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -version = "0.23.1" +version = "0.24" allprojects { repositories { diff --git a/flatlaf-jide-oss/README.md b/flatlaf-jide-oss/README.md index 8db3fb14..2014320c 100644 --- a/flatlaf-jide-oss/README.md +++ b/flatlaf-jide-oss/README.md @@ -26,7 +26,7 @@ build script: groupId: com.formdev artifactId: flatlaf-jide-oss - version: 0.23.1 + version: 0.24 Otherwise download `flatlaf-jide-oss-.jar` here: diff --git a/flatlaf-swingx/README.md b/flatlaf-swingx/README.md index cec446c8..a927b68e 100644 --- a/flatlaf-swingx/README.md +++ b/flatlaf-swingx/README.md @@ -33,7 +33,7 @@ build script: groupId: com.formdev artifactId: flatlaf-swingx - version: 0.23.1 + version: 0.24 Otherwise download `flatlaf-swingx-.jar` here: From e9a3456cf5b84e46cd579803616cd8d5011a4e13 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Jan 2020 10:44:00 +0100 Subject: [PATCH 28/46] Tree: `Tree.textBackground` now has a valid color and is no longer null; instead set `Tree.rendererFillBackground` to false to always get correct cell backgrounds (in IntelliJ themes or if `tree.setBackground(...)` was used) undone commit 645be4bfa3c201373fc785789c934ed65f78bea4 --- CHANGELOG.md | 6 ++++++ .../main/resources/com/formdev/flatlaf/FlatLaf.properties | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97bf1a82..138a9fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ FlatLaf Change Log ================== +## Unreleased + +- Tree: UI default value `Tree.textBackground` now has a valid color and is no + longer `null`. + + ## 0.24 - Support smooth scrolling with touchpads and high precision mouse wheels. diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 0c24e127..ce303fb2 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -475,11 +475,12 @@ ToolTip.foregroundInactive=@disabledText Tree.border=1,1,1,1 Tree.selectionInactiveBackground=@selectionInactiveBackground Tree.selectionInactiveForeground=@selectionInactiveForeground -Tree.textBackground=null +Tree.textBackground=$Tree.background Tree.selectionBorderColor=@cellFocusColor Tree.dropCellBackground=@dropCellBackground Tree.dropCellForeground=@dropCellForeground Tree.dropLineColor=@dropLineColor +Tree.rendererFillBackground=false Tree.rendererMargins=1,2,1,2 Tree.wideSelection=true Tree.paintLines=false From 2459a3654bdc0918d2477362577f4d914e6cc916 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Jan 2020 10:51:07 +0100 Subject: [PATCH 29/46] TabbedPane: hide cropped line in scroll-tab-layout (issue #40) --- CHANGELOG.md | 1 + .../src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java | 2 +- .../src/main/resources/com/formdev/flatlaf/FlatLaf.properties | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 138a9fe2..8f40cd62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ FlatLaf Change Log ## Unreleased +- TabbedPane: In scroll-tab-layout, the cropped line is now hidden. (issue #40) - Tree: UI default value `Tree.textBackground` now has a valid color and is no longer `null`. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java index 06d278d5..a4418f32 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java @@ -181,7 +181,7 @@ public class FlatTabbedPaneUI protected JButton createScrollButton( int direction ) { // this method is invoked before installDefaults(), so we can not use color fields here return new FlatArrowButton( direction, UIManager.getString( "Component.arrowType" ), - UIManager.getColor( "TabbedPane.shadow" ), + UIManager.getColor( "TabbedPane.foreground" ), UIManager.getColor( "TabbedPane.disabledForeground" ), null, UIManager.getColor( "TabbedPane.hoverColor" ) ); } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index ce303fb2..a1d878fa 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -366,7 +366,7 @@ TabbedPane.tabAreaInsets=0,0,0,0 TabbedPane.selectedTabPadInsets=0,0,0,0 TabbedPane.tabRunOverlay=0 TabbedPane.tabsOverlapBorder=true -TabbedPane.shadow=$ComboBox.buttonArrowColor +TabbedPane.shadow=@background #---- Table ---- From 5c3638a5a45b0e812afa265fbbcbb436dbc0cfea Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Jan 2020 11:58:51 +0100 Subject: [PATCH 30/46] Menu: hide mnemonics by default and show them only when Alt key is pressed (issue #43) --- CHANGELOG.md | 2 + .../java/com/formdev/flatlaf/FlatLaf.java | 32 ++++-- .../flatlaf/ui/FlatCheckBoxMenuItemUI.java | 8 ++ .../formdev/flatlaf/ui/FlatMenuItemUI.java | 30 ++++++ .../com/formdev/flatlaf/ui/FlatMenuUI.java | 8 ++ .../flatlaf/ui/FlatRadioButtonMenuItemUI.java | 8 ++ .../com/formdev/flatlaf/demo/DemoFrame.java | 97 +++++++++++++++++++ .../com/formdev/flatlaf/demo/DemoFrame.jfd | 79 ++++++++++++++- .../flatlaf/testing/FlatMenusTest.java | 11 +++ .../formdev/flatlaf/testing/FlatMenusTest.jfd | 13 ++- 10 files changed, 276 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f40cd62..f8722cf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ FlatLaf Change Log ## Unreleased +- Hide menu mnemonics by default and show them only when Alt key is + pressed. (issue #43) - TabbedPane: In scroll-tab-layout, the cropped line is now hidden. (issue #40) - Tree: UI default value `Tree.textBackground` now has a valid color and is no longer `null`. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index 59fece80..3d708d7e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -28,6 +28,7 @@ import java.awt.Window; import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; import java.util.List; import java.util.function.Consumer; import java.util.logging.Level; @@ -66,6 +67,7 @@ public abstract class FlatLaf private KeyEventPostProcessor mnemonicListener; private static boolean showMnemonics; + private static WeakReference lastShowMnemonicWindow; private Consumer postInitialization; @@ -391,18 +393,28 @@ public abstract class FlatLaf if( !UIManager.getBoolean( "Component.hideMnemonics" ) ) return; - // get focus owner - Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); - if( focusOwner == null ) - return; + if( show ) { + // get focus owner + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if( focusOwner == null ) + return; - // get focused window - Window window = SwingUtilities.windowForComponent( focusOwner ); - if( window == null ) - return; + // get focused window + Window window = SwingUtilities.windowForComponent( focusOwner ); + if( window == null ) + return; - // repaint components with mnemonics in focused window - repaintMnemonics( window ); + // repaint components with mnemonics in focused window + repaintMnemonics( window ); + + lastShowMnemonicWindow = new WeakReference<>( window ); + } else if( lastShowMnemonicWindow != null ) { + Window window = lastShowMnemonicWindow.get(); + if( window != null ) + repaintMnemonics( window ); + + lastShowMnemonicWindow = null; + } } private static void repaintMnemonics( Container container ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java index 5679af31..f1cb3767 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCheckBoxMenuItemUI.java @@ -17,8 +17,11 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Graphics; +import java.awt.Rectangle; import java.beans.PropertyChangeListener; import javax.swing.JComponent; +import javax.swing.JMenuItem; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI; @@ -74,4 +77,9 @@ public class FlatCheckBoxMenuItemUI defaultTextIconGap = scale( defaultTextIconGap ); }; } + + @Override + protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) { + FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground ); + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java index 205c75ca..28c76999 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemUI.java @@ -17,10 +17,18 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Rectangle; import java.beans.PropertyChangeListener; +import javax.swing.ButtonModel; import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuItem; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicMenuItemUI; +import com.formdev.flatlaf.FlatLaf; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JMenuItem}. @@ -74,4 +82,26 @@ public class FlatMenuItemUI defaultTextIconGap = scale( defaultTextIconGap ); }; } + + @Override + protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) { + paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground ); + } + + public static void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, + String text, Color disabledForeground, Color selectionForeground ) + { + FontMetrics fm = menuItem.getFontMetrics( menuItem.getFont() ); + int mnemonicIndex = FlatLaf.isShowMnemonics() ? menuItem.getDisplayedMnemonicIndex() : -1; + + ButtonModel model = menuItem.getModel(); + g.setColor( !model.isEnabled() + ? disabledForeground + : (model.isArmed() || (menuItem instanceof JMenu && model.isSelected()) + ? selectionForeground + : menuItem.getForeground()) ); + + FlatUIUtils.drawStringUnderlineCharAt( menuItem, g, text, mnemonicIndex, + textRect.x, textRect.y + fm.getAscent() ); + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java index a1ab13e2..3706b564 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java @@ -17,8 +17,11 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Graphics; +import java.awt.Rectangle; import java.beans.PropertyChangeListener; import javax.swing.JComponent; +import javax.swing.JMenuItem; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicMenuUI; @@ -77,4 +80,9 @@ public class FlatMenuUI defaultTextIconGap = scale( defaultTextIconGap ); }; } + + @Override + protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) { + FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground ); + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java index 114525d2..ef55d3ec 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonMenuItemUI.java @@ -17,8 +17,11 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Graphics; +import java.awt.Rectangle; import java.beans.PropertyChangeListener; import javax.swing.JComponent; +import javax.swing.JMenuItem; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI; @@ -74,4 +77,9 @@ public class FlatRadioButtonMenuItemUI defaultTextIconGap = scale( defaultTextIconGap ); }; } + + @Override + protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) { + FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground ); + } } diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java index 11fcd6af..9a7c5208 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java @@ -51,6 +51,12 @@ class DemoFrame DemoPrefs.getState().putInt( FlatLafDemo.KEY_TAB, tabbedPane.getSelectedIndex() ); } + private void menuItemActionPerformed(ActionEvent e) { + SwingUtilities.invokeLater( () -> { + JOptionPane.showMessageDialog( this, e.getActionCommand(), "Menu Item", JOptionPane.PLAIN_MESSAGE ); + } ); + } + private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents JMenuBar menuBar1 = new JMenuBar(); @@ -68,6 +74,14 @@ class DemoFrame JMenuItem deleteMenuItem = new JMenuItem(); JMenu viewMenu = new JMenu(); JCheckBoxMenuItem checkBoxMenuItem1 = new JCheckBoxMenuItem(); + JMenu menu1 = new JMenu(); + JMenu subViewsMenu = new JMenu(); + JMenu subSubViewsMenu = new JMenu(); + JMenuItem errorLogViewMenuItem = new JMenuItem(); + JMenuItem searchViewMenuItem = new JMenuItem(); + JMenuItem projectViewMenuItem = new JMenuItem(); + JMenuItem structureViewMenuItem = new JMenuItem(); + JMenuItem propertiesViewMenuItem = new JMenuItem(); JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem(); JRadioButtonMenuItem radioButtonMenuItem2 = new JRadioButtonMenuItem(); JRadioButtonMenuItem radioButtonMenuItem3 = new JRadioButtonMenuItem(); @@ -103,27 +117,35 @@ class DemoFrame //======== fileMenu ======== { fileMenu.setText("File"); + fileMenu.setMnemonic('F'); //---- newMenuItem ---- newMenuItem.setText("New"); newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + newMenuItem.setMnemonic('N'); + newMenuItem.addActionListener(e -> menuItemActionPerformed(e)); fileMenu.add(newMenuItem); //---- openMenuItem ---- openMenuItem.setText("Open"); openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + openMenuItem.setMnemonic('O'); + openMenuItem.addActionListener(e -> menuItemActionPerformed(e)); fileMenu.add(openMenuItem); fileMenu.addSeparator(); //---- closeMenuItem ---- closeMenuItem.setText("Close"); closeMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + closeMenuItem.setMnemonic('C'); + closeMenuItem.addActionListener(e -> menuItemActionPerformed(e)); fileMenu.add(closeMenuItem); fileMenu.addSeparator(); //---- exitMenuItem ---- exitMenuItem.setText("Exit"); exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + exitMenuItem.setMnemonic('X'); exitMenuItem.addActionListener(e -> exitActionPerformed()); fileMenu.add(exitMenuItem); } @@ -132,37 +154,50 @@ class DemoFrame //======== editMenu ======== { editMenu.setText("Edit"); + editMenu.setMnemonic('E'); //---- undoMenuItem ---- undoMenuItem.setText("Undo"); undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + undoMenuItem.setMnemonic('U'); + undoMenuItem.addActionListener(e -> menuItemActionPerformed(e)); editMenu.add(undoMenuItem); //---- redoMenuItem ---- redoMenuItem.setText("Redo"); redoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + redoMenuItem.setMnemonic('R'); + redoMenuItem.addActionListener(e -> menuItemActionPerformed(e)); editMenu.add(redoMenuItem); editMenu.addSeparator(); //---- cutMenuItem ---- cutMenuItem.setText("Cut"); cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + cutMenuItem.setMnemonic('C'); + cutMenuItem.addActionListener(e -> menuItemActionPerformed(e)); editMenu.add(cutMenuItem); //---- copyMenuItem ---- copyMenuItem.setText("Copy"); copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + copyMenuItem.setMnemonic('O'); + copyMenuItem.addActionListener(e -> menuItemActionPerformed(e)); editMenu.add(copyMenuItem); //---- pasteMenuItem ---- pasteMenuItem.setText("Paste"); pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + pasteMenuItem.setMnemonic('P'); + pasteMenuItem.addActionListener(e -> menuItemActionPerformed(e)); editMenu.add(pasteMenuItem); editMenu.addSeparator(); //---- deleteMenuItem ---- deleteMenuItem.setText("Delete"); deleteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)); + deleteMenuItem.setMnemonic('D'); + deleteMenuItem.addActionListener(e -> menuItemActionPerformed(e)); editMenu.add(deleteMenuItem); } menuBar1.add(editMenu); @@ -170,24 +205,84 @@ class DemoFrame //======== viewMenu ======== { viewMenu.setText("View"); + viewMenu.setMnemonic('V'); //---- checkBoxMenuItem1 ---- checkBoxMenuItem1.setText("Show Toolbar"); checkBoxMenuItem1.setSelected(true); + checkBoxMenuItem1.setMnemonic('T'); + checkBoxMenuItem1.addActionListener(e -> menuItemActionPerformed(e)); viewMenu.add(checkBoxMenuItem1); + + //======== menu1 ======== + { + menu1.setText("Show View"); + menu1.setMnemonic('V'); + + //======== subViewsMenu ======== + { + subViewsMenu.setText("Sub Views"); + subViewsMenu.setMnemonic('S'); + + //======== subSubViewsMenu ======== + { + subSubViewsMenu.setText("Sub sub Views"); + subSubViewsMenu.setMnemonic('U'); + + //---- errorLogViewMenuItem ---- + errorLogViewMenuItem.setText("Error Log"); + errorLogViewMenuItem.setMnemonic('E'); + errorLogViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + subSubViewsMenu.add(errorLogViewMenuItem); + } + subViewsMenu.add(subSubViewsMenu); + + //---- searchViewMenuItem ---- + searchViewMenuItem.setText("Search"); + searchViewMenuItem.setMnemonic('S'); + searchViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + subViewsMenu.add(searchViewMenuItem); + } + menu1.add(subViewsMenu); + + //---- projectViewMenuItem ---- + projectViewMenuItem.setText("Project"); + projectViewMenuItem.setMnemonic('P'); + projectViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + menu1.add(projectViewMenuItem); + + //---- structureViewMenuItem ---- + structureViewMenuItem.setText("Structure"); + structureViewMenuItem.setMnemonic('T'); + structureViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + menu1.add(structureViewMenuItem); + + //---- propertiesViewMenuItem ---- + propertiesViewMenuItem.setText("Properties"); + propertiesViewMenuItem.setMnemonic('O'); + propertiesViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + menu1.add(propertiesViewMenuItem); + } + viewMenu.add(menu1); viewMenu.addSeparator(); //---- radioButtonMenuItem1 ---- radioButtonMenuItem1.setText("Details"); radioButtonMenuItem1.setSelected(true); + radioButtonMenuItem1.setMnemonic('D'); + radioButtonMenuItem1.addActionListener(e -> menuItemActionPerformed(e)); viewMenu.add(radioButtonMenuItem1); //---- radioButtonMenuItem2 ---- radioButtonMenuItem2.setText("Small Icons"); + radioButtonMenuItem2.setMnemonic('S'); + radioButtonMenuItem2.addActionListener(e -> menuItemActionPerformed(e)); viewMenu.add(radioButtonMenuItem2); //---- radioButtonMenuItem3 ---- radioButtonMenuItem3.setText("Large Icons"); + radioButtonMenuItem3.setMnemonic('L'); + radioButtonMenuItem3.addActionListener(e -> menuItemActionPerformed(e)); viewMenu.add(radioButtonMenuItem3); } menuBar1.add(viewMenu); @@ -195,9 +290,11 @@ class DemoFrame //======== helpMenu ======== { helpMenu.setText("Help"); + helpMenu.setMnemonic('H'); //---- aboutMenuItem ---- aboutMenuItem.setText("About"); + aboutMenuItem.setMnemonic('A'); aboutMenuItem.addActionListener(e -> aboutActionPerformed()); helpMenu.add(aboutMenuItem); } diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd index 7c652832..4912b254 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -117,15 +117,20 @@ new FormModel { add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { name: "fileMenu" "text": "File" + "mnemonic": 70 add( new FormComponent( "javax.swing.JMenuItem" ) { name: "newMenuItem" "text": "New" "accelerator": static javax.swing.KeyStroke getKeyStroke( 78, 4226, false ) + "mnemonic": 78 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JMenuItem" ) { name: "openMenuItem" "text": "Open" "accelerator": static javax.swing.KeyStroke getKeyStroke( 79, 4226, false ) + "mnemonic": 79 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { name: "separator2" @@ -134,6 +139,8 @@ new FormModel { name: "closeMenuItem" "text": "Close" "accelerator": static javax.swing.KeyStroke getKeyStroke( 87, 4226, false ) + "mnemonic": 67 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { name: "separator1" @@ -142,21 +149,27 @@ new FormModel { name: "exitMenuItem" "text": "Exit" "accelerator": static javax.swing.KeyStroke getKeyStroke( 81, 4226, false ) + "mnemonic": 88 addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "exitActionPerformed", false ) ) } ) } ) add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { name: "editMenu" "text": "Edit" + "mnemonic": 69 add( new FormComponent( "javax.swing.JMenuItem" ) { name: "undoMenuItem" "text": "Undo" "accelerator": static javax.swing.KeyStroke getKeyStroke( 90, 4226, false ) + "mnemonic": 85 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JMenuItem" ) { name: "redoMenuItem" "text": "Redo" "accelerator": static javax.swing.KeyStroke getKeyStroke( 89, 4226, false ) + "mnemonic": 82 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { name: "separator4" @@ -165,16 +178,22 @@ new FormModel { name: "cutMenuItem" "text": "Cut" "accelerator": static javax.swing.KeyStroke getKeyStroke( 88, 4226, false ) + "mnemonic": 67 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JMenuItem" ) { name: "copyMenuItem" "text": "Copy" "accelerator": static javax.swing.KeyStroke getKeyStroke( 67, 4226, false ) + "mnemonic": 79 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JMenuItem" ) { name: "pasteMenuItem" "text": "Paste" "accelerator": static javax.swing.KeyStroke getKeyStroke( 86, 4226, false ) + "mnemonic": 80 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { name: "separator3" @@ -183,15 +202,65 @@ new FormModel { name: "deleteMenuItem" "text": "Delete" "accelerator": static javax.swing.KeyStroke getKeyStroke( 127, 0, false ) + "mnemonic": 68 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) } ) add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { name: "viewMenu" "text": "View" + "mnemonic": 86 add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) { name: "checkBoxMenuItem1" "text": "Show Toolbar" "selected": true + "mnemonic": 84 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "menu1" + "text": "Show View" + "mnemonic": 86 + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "subViewsMenu" + "text": "Sub Views" + "mnemonic": 83 + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "subSubViewsMenu" + "text": "Sub sub Views" + "mnemonic": 85 + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "errorLogViewMenuItem" + "text": "Error Log" + "mnemonic": 69 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "searchViewMenuItem" + "text": "Search" + "mnemonic": 83 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "projectViewMenuItem" + "text": "Project" + "mnemonic": 80 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "structureViewMenuItem" + "text": "Structure" + "mnemonic": 84 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "propertiesViewMenuItem" + "text": "Properties" + "mnemonic": 79 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) } ) add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { name: "separator8" @@ -201,24 +270,32 @@ new FormModel { "text": "Details" "selected": true "$buttonGroup": new FormReference( "buttonGroup1" ) + "mnemonic": 68 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JRadioButtonMenuItem" ) { name: "radioButtonMenuItem2" "text": "Small Icons" "$buttonGroup": new FormReference( "buttonGroup1" ) + "mnemonic": 83 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) add( new FormComponent( "javax.swing.JRadioButtonMenuItem" ) { name: "radioButtonMenuItem3" "text": "Large Icons" "$buttonGroup": new FormReference( "buttonGroup1" ) + "mnemonic": 76 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) } ) } ) add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { name: "helpMenu" "text": "Help" + "mnemonic": 72 add( new FormComponent( "javax.swing.JMenuItem" ) { name: "aboutMenuItem" "text": "About" + "mnemonic": 65 addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "aboutActionPerformed", false ) ) } ) } ) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.java index 908f89cc..52d8390a 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.java @@ -126,13 +126,16 @@ public class FlatMenusTest //======== menu5 ======== { menu5.setText("text"); + menu5.setMnemonic('T'); //---- menuItem7 ---- menuItem7.setText("text"); + menuItem7.setMnemonic('X'); menu5.add(menuItem7); //---- menuItem8 ---- menuItem8.setText("text"); + menuItem8.setMnemonic('E'); menu5.add(menuItem8); } menuBar1.add(menu5); @@ -175,6 +178,7 @@ public class FlatMenusTest //======== menu1 ======== { menu1.setText("enabled"); + menu1.setMnemonic('E'); } panel1.add(menu1, "cell 1 0"); @@ -185,6 +189,7 @@ public class FlatMenusTest //---- menuItem1 ---- menuItem1.setText("enabled"); menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK)); + menuItem1.setMnemonic('N'); panel1.add(menuItem1, "cell 1 1"); //---- checkBoxMenuItemLabel ---- @@ -194,6 +199,7 @@ public class FlatMenusTest //---- checkBoxMenuItem1 ---- checkBoxMenuItem1.setText("enabled"); checkBoxMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); + checkBoxMenuItem1.setMnemonic('A'); panel1.add(checkBoxMenuItem1, "cell 1 2"); //---- radioButtonMenuItemLabel ---- @@ -203,6 +209,7 @@ public class FlatMenusTest //---- radioButtonMenuItem1 ---- radioButtonMenuItem1.setText("enabled"); radioButtonMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); + radioButtonMenuItem1.setMnemonic('B'); panel1.add(radioButtonMenuItem1, "cell 1 3"); //---- popupMenuSeparatorLabel ---- @@ -230,6 +237,7 @@ public class FlatMenusTest { menu2.setText("disabled"); menu2.setEnabled(false); + menu2.setMnemonic('D'); } panel2.add(menu2, "cell 0 0"); @@ -237,18 +245,21 @@ public class FlatMenusTest menuItem2.setText("disabled"); menuItem2.setEnabled(false); menuItem2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.ALT_MASK|KeyEvent.SHIFT_MASK)); + menuItem2.setMnemonic('I'); panel2.add(menuItem2, "cell 0 1"); //---- checkBoxMenuItem2 ---- checkBoxMenuItem2.setText("disabled"); checkBoxMenuItem2.setEnabled(false); checkBoxMenuItem2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); + checkBoxMenuItem2.setMnemonic('S'); panel2.add(checkBoxMenuItem2, "cell 0 2"); //---- radioButtonMenuItem2 ---- radioButtonMenuItem2.setText("disabled"); radioButtonMenuItem2.setEnabled(false); radioButtonMenuItem2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); + radioButtonMenuItem2.setMnemonic('L'); panel2.add(radioButtonMenuItem2, "cell 0 3"); } add(panel2, "cell 2 1"); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.jfd index bc2ff51b..2700ef0b 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMenusTest.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -23,13 +23,16 @@ new FormModel { add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { name: "menu5" "text": "text" + "mnemonic": 84 add( new FormComponent( "javax.swing.JMenuItem" ) { name: "menuItem7" "text": "text" + "mnemonic": 88 } ) add( new FormComponent( "javax.swing.JMenuItem" ) { name: "menuItem8" "text": "text" + "mnemonic": 69 } ) } ) add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { @@ -63,6 +66,7 @@ new FormModel { add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { name: "menu1" "text": "enabled" + "mnemonic": 69 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 0" } ) @@ -76,6 +80,7 @@ new FormModel { name: "menuItem1" "text": "enabled" "accelerator": static javax.swing.KeyStroke getKeyStroke( 65, 130, false ) + "mnemonic": 78 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1" } ) @@ -89,6 +94,7 @@ new FormModel { name: "checkBoxMenuItem1" "text": "enabled" "accelerator": &KeyStroke0 static javax.swing.KeyStroke getKeyStroke( 112, 0, false ) + "mnemonic": 65 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 2" } ) @@ -102,6 +108,7 @@ new FormModel { name: "radioButtonMenuItem1" "text": "enabled" "accelerator": #KeyStroke0 + "mnemonic": 66 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 3" } ) @@ -130,6 +137,7 @@ new FormModel { name: "menu2" "text": "disabled" "enabled": false + "mnemonic": 68 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 0" } ) @@ -138,6 +146,7 @@ new FormModel { "text": "disabled" "enabled": false "accelerator": static javax.swing.KeyStroke getKeyStroke( 68, 585, false ) + "mnemonic": 73 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1" } ) @@ -146,6 +155,7 @@ new FormModel { "text": "disabled" "enabled": false "accelerator": #KeyStroke0 + "mnemonic": 83 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 2" } ) @@ -154,6 +164,7 @@ new FormModel { "text": "disabled" "enabled": false "accelerator": #KeyStroke0 + "mnemonic": 76 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 3" } ) From 655bf112ac2de911f7cfb80771a209e89cbe1fb3 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Jan 2020 15:03:07 +0100 Subject: [PATCH 31/46] ScrollPane: fixed UI artifact at bottom right corner of scroll pane if both scroll bars are visible, which was caused by `Component.innerFocusWidth` > 0 (issue #35) --- .../src/main/java/com/formdev/flatlaf/ui/FlatBorder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java index a88418e8..8da2517b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java @@ -78,6 +78,8 @@ public class FlatBorder float arc = isCellEditor ? 0 : getArc( c ); if( isFocused( c ) ) { + float innerFocusWidth = !(c instanceof JScrollPane) ? this.innerFocusWidth : 0; + g2.setColor( getFocusColor( c ) ); FlatUIUtils.paintComponentOuterBorder( g2, x, y, width, height, focusWidth, getLineWidth() + scale( innerFocusWidth ), arc ); From 74909da110f81ee4eb6a67a5504f9daa8e5ca529 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Jan 2020 18:42:06 +0100 Subject: [PATCH 32/46] Button and ToggleButton: - support per component minimum height (issue #44) - do not apply minimum width if button border was changed (is no longer an instance of `FlatButtonBorder`) - ToggleButton: no longer use focus width for underline style toggle buttons to compute component size, which reduces/fixes component size in "Flat IntelliJ" and "Flat Darcula" themes - revalidate/repaint client properties minimum width/height or buttonType change --- CHANGELOG.md | 7 ++++ .../formdev/flatlaf/FlatClientProperties.java | 19 +++++++++- .../com/formdev/flatlaf/ui/FlatBorder.java | 12 +++---- .../formdev/flatlaf/ui/FlatButtonBorder.java | 5 +++ .../com/formdev/flatlaf/ui/FlatButtonUI.java | 35 +++++++++++++++++-- .../flatlaf/ui/FlatToggleButtonUI.java | 23 ++++++++++++ .../com/formdev/flatlaf/ui/FlatUIUtils.java | 7 ++-- 7 files changed, 96 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8722cf0..17a60019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ FlatLaf Change Log - TabbedPane: In scroll-tab-layout, the cropped line is now hidden. (issue #40) - Tree: UI default value `Tree.textBackground` now has a valid color and is no longer `null`. +- Button and ToggleButton: Support per component minimum height (set client + property `JComponent.minimumHeight` to an integer). (issue #44) +- Button and ToggleButton: Do not apply minimum width if button border was + changed (is no longer an instance of `FlatButtonBorder`). +- ToggleButton: No longer use focus width for underline style toggle buttons to + compute component size, which reduces/fixes component size in "Flat IntelliJ" + and "Flat Darcula" themes. ## 0.24 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index d6952d0e..45081cae 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -79,11 +79,19 @@ public interface FlatClientProperties /** * Specifies minimum width of a component. *

- * Component {@link javax.swing.JButton} and {@link javax.swing.text.JTextComponent}
+ * Component {@link javax.swing.JButton}, {@link javax.swing.JToggleButton} and {@link javax.swing.text.JTextComponent}
* Value type {@link java.lang.Integer}
*/ String MINIMUM_WIDTH = "JComponent.minimumWidth"; + /** + * Specifies minimum height of a component. + *

+ * Component {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}
+ * Value type {@link java.lang.Integer}
+ */ + String MINIMUM_HEIGHT = "JComponent.minimumHeight"; + /** * Specifies whether the decrease/increase arrow buttons of a scrollbar are shown. *

@@ -131,4 +139,13 @@ public interface FlatClientProperties Object value = c.getClientProperty( key ); return (value instanceof Boolean) ? (boolean) value : defaultValue; } + + /** + * Checks whether a client property of a component is an integer and returns its value. + * If the client property is not set, or not an integer, defaultValue is returned. + */ + static int clientPropertyInt( JComponent c, String key, int defaultValue ) { + Object value = c.getClientProperty( key ); + return (value instanceof Integer) ? (int) value : defaultValue; + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java index 8da2517b..0cf2b7ea 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java @@ -73,7 +73,7 @@ public class FlatBorder FlatUIUtils.setRenderingHints( g2 ); boolean isCellEditor = isTableCellEditor( c ); - float focusWidth = isCellEditor ? 0 : getFocusWidth(); + float focusWidth = isCellEditor ? 0 : getFocusWidth( c ); float borderWidth = getBorderWidth( c ); float arc = isCellEditor ? 0 : getArc( c ); @@ -82,7 +82,7 @@ public class FlatBorder g2.setColor( getFocusColor( c ) ); FlatUIUtils.paintComponentOuterBorder( g2, x, y, width, height, focusWidth, - getLineWidth() + scale( innerFocusWidth ), arc ); + getLineWidth( c ) + scale( innerFocusWidth ), arc ); } g2.setPaint( getBorderColor( c ) ); @@ -153,7 +153,7 @@ public class FlatBorder @Override public Insets getBorderInsets( Component c, Insets insets ) { boolean isCellEditor = isTableCellEditor( c ); - float ow = (isCellEditor ? 0 : getFocusWidth()) + getLineWidth(); + float ow = (isCellEditor ? 0 : getFocusWidth( c )) + getLineWidth( c ); insets = super.getBorderInsets( c, insets ); insets.top = Math.round( scale( (float) insets.top ) + ow ); @@ -163,16 +163,16 @@ public class FlatBorder return insets; } - protected float getFocusWidth() { + protected float getFocusWidth( Component c ) { return scale( (float) focusWidth ); } - protected float getLineWidth() { + protected float getLineWidth( Component c ) { return scale( 1f ); } protected float getBorderWidth( Component c ) { - return getLineWidth(); + return getLineWidth( c ); } protected float getArc( Component c ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java index 70156a6c..4fd505b3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java @@ -104,6 +104,11 @@ public class FlatButtonBorder return insets; } + @Override + protected float getFocusWidth( Component c ) { + return FlatToggleButtonUI.isUnderlineButton( c ) ? 0 : super.getFocusWidth(c ); + } + @Override protected float getBorderWidth( Component c ) { return FlatButtonUI.isDefaultButton( c ) ? scale( (float) defaultBorderWidth ) : super.getBorderWidth( c ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java index dd9cd90b..c8d0b2a9 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java @@ -28,6 +28,7 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.RoundRectangle2D; +import java.beans.PropertyChangeEvent; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.Icon; @@ -39,6 +40,7 @@ import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicButtonListener; import javax.swing.plaf.basic.BasicButtonUI; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.util.UIScale; @@ -180,7 +182,7 @@ public class FlatButtonUI LookAndFeel.installProperty( b, "opaque", false ); LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) ); - MigLayoutVisualPadding.install( b, focusWidth ); + MigLayoutVisualPadding.install( b, getFocusWidth( b ) ); } @Override @@ -191,6 +193,26 @@ public class FlatButtonUI defaults_initialized = false; } + @Override + protected BasicButtonListener createButtonListener( AbstractButton b ) { + return new BasicButtonListener( b ) { + @Override + public void propertyChange( PropertyChangeEvent e ) { + super.propertyChange( e ); + FlatButtonUI.this.propertyChange( b, e ); + } + }; + } + + protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) { + switch( e.getPropertyName() ) { + case MINIMUM_WIDTH: + case MINIMUM_HEIGHT: + b.revalidate(); + break; + } + } + static boolean isContentAreaFilled( Component c ) { return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled(); } @@ -246,7 +268,7 @@ public class FlatButtonUI FlatUIUtils.setRenderingHints( g2 ); Border border = c.getBorder(); - float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0; + float focusWidth = (border instanceof FlatBorder) ? scale( (float) getFocusWidth( c ) ) : 0; float arc = ((border instanceof FlatButtonBorder && !isSquareButton( c )) || isToolBarButton( c )) ? scale( (float) this.arc ) : 0; boolean def = isDefaultButton( c ); @@ -362,9 +384,16 @@ public class FlatButtonUI // or apply minimum width, if not in toolbar and not a icon-only button if( isIconOnlyButton( c ) ) prefSize.width = Math.max( prefSize.width, prefSize.height ); - else if( !isToolBarButton( c ) ) + else if( !isToolBarButton( c ) && c.getBorder() instanceof FlatButtonBorder ) { + int focusWidth = getFocusWidth( c ); prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) + (focusWidth * 2) ) ); + prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, 0 ) + (focusWidth * 2) ) ); + } return prefSize; } + + protected int getFocusWidth( JComponent c ) { + return focusWidth; + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java index 97f390ac..f313b64e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java @@ -20,6 +20,7 @@ import static com.formdev.flatlaf.FlatClientProperties.*; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; +import java.beans.PropertyChangeEvent; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.JComponent; @@ -129,6 +130,23 @@ public class FlatToggleButtonUI defaults_initialized = false; } + @Override + protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) { + super.propertyChange( b, e ); + + switch( e.getPropertyName() ) { + case BUTTON_TYPE: + if( BUTTON_TYPE_UNDERLINE.equals( e.getOldValue() ) || BUTTON_TYPE_UNDERLINE.equals( e.getNewValue() ) ) { + MigLayoutVisualPadding.uninstall( b ); + MigLayoutVisualPadding.install( b, getFocusWidth( b ) ); + b.revalidate(); + } + + b.repaint(); + break; + } + } + static boolean isUnderlineButton( Component c ) { return c instanceof JToggleButton && clientPropertyEquals( (JToggleButton) c, BUTTON_TYPE, BUTTON_TYPE_UNDERLINE ); } @@ -186,4 +204,9 @@ public class FlatToggleButtonUI return super.getForeground( c ); } + + @Override + protected int getFocusWidth( JComponent c ) { + return isUnderlineButton( c ) ? 0 : super.getFocusWidth( c ); + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index b12af8e1..e8e1dec1 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -113,8 +113,11 @@ public class FlatUIUtils } public static int minimumWidth( JComponent c, int minimumWidth ) { - Object p = c.getClientProperty( FlatClientProperties.MINIMUM_WIDTH ); - return (p instanceof Integer) ? ((Integer)p).intValue() : minimumWidth; + return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_WIDTH, minimumWidth ); + } + + public static int minimumHeight( JComponent c, int minimumHeight ) { + return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_HEIGHT, minimumHeight ); } public static boolean isTableCellEditor( Component c ) { From e378576632b0e9d5407da10b21fe6cbe9e8b2a6b Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Jan 2020 23:59:56 +0100 Subject: [PATCH 33/46] ToggleButton renamed toggle button type "underline" to "tab" (value of client property `JButton.buttonType` is now `tab`) --- CHANGELOG.md | 4 +- .../formdev/flatlaf/FlatClientProperties.java | 4 +- .../com/formdev/flatlaf/IntelliJTheme.java | 10 ++-- .../formdev/flatlaf/ui/FlatButtonBorder.java | 4 +- .../flatlaf/ui/FlatToggleButtonUI.java | 54 +++++++++---------- .../com/formdev/flatlaf/FlatLaf.properties | 14 ++--- .../flatlaf/testing/FlatComponentsTest.java | 8 +-- .../flatlaf/testing/FlatComponentsTest.jfd | 8 +-- 8 files changed, 54 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a60019..c9bef8e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,9 @@ FlatLaf Change Log property `JComponent.minimumHeight` to an integer). (issue #44) - Button and ToggleButton: Do not apply minimum width if button border was changed (is no longer an instance of `FlatButtonBorder`). -- ToggleButton: No longer use focus width for underline style toggle buttons to +- ToggleButton: Renamed toggle button type "underline" to "tab" (value of client + property `JButton.buttonType` is now `tab`). +- ToggleButton: No longer use focus width for tab-style toggle buttons to compute component size, which reduces/fixes component size in "Flat IntelliJ" and "Flat Darcula" themes. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 45081cae..be2707d6 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -43,13 +43,13 @@ public interface FlatClientProperties String BUTTON_TYPE_SQUARE = "square"; /** - * Paint the toggle button in underline style. + * Paint the toggle button in tab style. *

* Components {@link javax.swing.JToggleButton} * * @see #TOGGLE_BUTTON_TYPE */ - String BUTTON_TYPE_UNDERLINE = "underline"; + String BUTTON_TYPE_TAB = "tab"; /** * Paint a help button (circle with question mark). diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index 7c556807..33f7dfdc 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -445,11 +445,11 @@ public class IntelliJTheme for( Map.Entry e : uiKeyMapping.entrySet() ) uiKeyInverseMapping.put( e.getValue(), e.getKey() ); - uiKeyCopying.put( "ToggleButton.underline.underlineColor", "TabbedPane.underlineColor" ); - uiKeyCopying.put( "ToggleButton.underline.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" ); - uiKeyCopying.put( "ToggleButton.underline.selectedBackground", "TabbedPane.selectedBackground" ); - uiKeyCopying.put( "ToggleButton.underline.hoverBackground", "TabbedPane.hoverColor" ); - uiKeyCopying.put( "ToggleButton.underline.focusBackground", "TabbedPane.focusColor" ); + uiKeyCopying.put( "ToggleButton.tab.underlineColor", "TabbedPane.underlineColor" ); + uiKeyCopying.put( "ToggleButton.tab.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" ); + uiKeyCopying.put( "ToggleButton.tab.selectedBackground", "TabbedPane.selectedBackground" ); + uiKeyCopying.put( "ToggleButton.tab.hoverBackground", "TabbedPane.hoverColor" ); + uiKeyCopying.put( "ToggleButton.tab.focusBackground", "TabbedPane.focusColor" ); checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" ); checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java index 4fd505b3..f8ebe5a6 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java @@ -65,7 +65,7 @@ public class FlatButtonBorder @Override public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { - if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) && !FlatToggleButtonUI.isUnderlineButton( c ) ) + if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) && !FlatToggleButtonUI.isTabButton( c ) ) super.paintBorder( c, g, x, y, width, height ); } @@ -106,7 +106,7 @@ public class FlatButtonBorder @Override protected float getFocusWidth( Component c ) { - return FlatToggleButtonUI.isUnderlineButton( c ) ? 0 : super.getFocusWidth(c ); + return FlatToggleButtonUI.isTabButton( c ) ? 0 : super.getFocusWidth(c ); } @Override diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java index f313b64e..2c232de3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java @@ -61,12 +61,12 @@ import com.formdev.flatlaf.util.UIScale; * @uiDefault ToggleButton.disabledSelectedBackground Color * @uiDefault ToggleButton.toolbar.selectedBackground Color * - * @uiDefault ToggleButton.underline.underlineHeight int - * @uiDefault ToggleButton.underline.underlineColor Color - * @uiDefault ToggleButton.underline.disabledUnderlineColor Color - * @uiDefault ToggleButton.underline.selectedBackground Color optional - * @uiDefault ToggleButton.underline.hoverBackground Color - * @uiDefault ToggleButton.underline.focusBackground Color + * @uiDefault ToggleButton.tab.underlineHeight int + * @uiDefault ToggleButton.tab.underlineColor Color + * @uiDefault ToggleButton.tab.disabledUnderlineColor Color + * @uiDefault ToggleButton.tab.selectedBackground Color optional + * @uiDefault ToggleButton.tab.hoverBackground Color + * @uiDefault ToggleButton.tab.focusBackground Color * * * @author Karl Tauber @@ -80,12 +80,12 @@ public class FlatToggleButtonUI protected Color toolbarSelectedBackground; - protected int underlineHeight; - protected Color underlineColor; - protected Color disabledUnderlineColor; - protected Color underlineSelectedBackground; - protected Color underlineHoverBackground; - protected Color underlineFocusBackground; + protected int tabUnderlineHeight; + protected Color tabUnderlineColor; + protected Color tabDisabledUnderlineColor; + protected Color tabSelectedBackground; + protected Color tabHoverBackground; + protected Color tabFocusBackground; private boolean defaults_initialized = false; @@ -113,12 +113,12 @@ public class FlatToggleButtonUI toolbarSelectedBackground = UIManager.getColor( "ToggleButton.toolbar.selectedBackground" ); - underlineHeight = UIManager.getInt( "ToggleButton.underline.underlineHeight" ); - underlineColor = UIManager.getColor( "ToggleButton.underline.underlineColor" ); - disabledUnderlineColor = UIManager.getColor( "ToggleButton.underline.disabledUnderlineColor" ); - underlineSelectedBackground = UIManager.getColor( "ToggleButton.underline.selectedBackground" ); - underlineHoverBackground = UIManager.getColor( "ToggleButton.underline.hoverBackground" ); - underlineFocusBackground = UIManager.getColor( "ToggleButton.underline.focusBackground" ); + tabUnderlineHeight = UIManager.getInt( "ToggleButton.tab.underlineHeight" ); + tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" ); + tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" ); + tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" ); + tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" ); + tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" ); defaults_initialized = true; } @@ -136,7 +136,7 @@ public class FlatToggleButtonUI switch( e.getPropertyName() ) { case BUTTON_TYPE: - if( BUTTON_TYPE_UNDERLINE.equals( e.getOldValue() ) || BUTTON_TYPE_UNDERLINE.equals( e.getNewValue() ) ) { + if( BUTTON_TYPE_TAB.equals( e.getOldValue() ) || BUTTON_TYPE_TAB.equals( e.getNewValue() ) ) { MigLayoutVisualPadding.uninstall( b ); MigLayoutVisualPadding.install( b, getFocusWidth( b ) ); b.revalidate(); @@ -147,21 +147,21 @@ public class FlatToggleButtonUI } } - static boolean isUnderlineButton( Component c ) { - return c instanceof JToggleButton && clientPropertyEquals( (JToggleButton) c, BUTTON_TYPE, BUTTON_TYPE_UNDERLINE ); + static boolean isTabButton( Component c ) { + return c instanceof JToggleButton && clientPropertyEquals( (JToggleButton) c, BUTTON_TYPE, BUTTON_TYPE_TAB ); } @Override protected void paintBackground( Graphics g, JComponent c ) { - if( isUnderlineButton( c ) ) { + if( isTabButton( c ) ) { int height = c.getHeight(); int width = c.getWidth(); boolean selected = ((AbstractButton)c).isSelected(); // paint background Color background = buttonStateColor( c, - selected ? underlineSelectedBackground : null, - null, underlineFocusBackground, underlineHoverBackground, null ); + selected ? tabSelectedBackground : null, + null, tabFocusBackground, tabHoverBackground, null ); if( background != null ) { g.setColor( background ); g.fillRect( 0, 0, width, height ); @@ -169,8 +169,8 @@ public class FlatToggleButtonUI // paint underline if selected if( selected ) { - int underlineHeight = UIScale.scale( this.underlineHeight ); - g.setColor( c.isEnabled() ? underlineColor : disabledUnderlineColor ); + int underlineHeight = UIScale.scale( tabUnderlineHeight ); + g.setColor( c.isEnabled() ? tabUnderlineColor : tabDisabledUnderlineColor ); g.fillRect( 0, height - underlineHeight, width, underlineHeight ); } } else @@ -207,6 +207,6 @@ public class FlatToggleButtonUI @Override protected int getFocusWidth( JComponent c ) { - return isUnderlineButton( c ) ? 0 : super.getFocusWidth( c ); + return isTabButton( c ) ? 0 : super.getFocusWidth( c ); } } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index a1d878fa..8dc57f3f 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -439,13 +439,13 @@ ToggleButton.pressedBackground=$Button.pressedBackground ToggleButton.toolbar.hoverBackground=$Button.toolbar.hoverBackground ToggleButton.toolbar.pressedBackground=$Button.toolbar.pressedBackground -# button type "underline" -ToggleButton.underline.underlineHeight=2 -ToggleButton.underline.underlineColor=$TabbedPane.underlineColor -ToggleButton.underline.disabledUnderlineColor=$TabbedPane.disabledUnderlineColor -ToggleButton.underline.selectedBackground=$?TabbedPane.selectedBackground -ToggleButton.underline.hoverBackground=$TabbedPane.hoverColor -ToggleButton.underline.focusBackground=$TabbedPane.focusColor +# button type "tab" +ToggleButton.tab.underlineHeight=2 +ToggleButton.tab.underlineColor=$TabbedPane.underlineColor +ToggleButton.tab.disabledUnderlineColor=$TabbedPane.disabledUnderlineColor +ToggleButton.tab.selectedBackground=$?TabbedPane.selectedBackground +ToggleButton.tab.hoverBackground=$TabbedPane.hoverColor +ToggleButton.tab.focusBackground=$TabbedPane.focusColor #---- ToolBar ---- diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java index e7c1c58a..9c3c9ffe 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java @@ -344,14 +344,14 @@ public class FlatComponentsTest add(toggleButton4, "cell 4 2"); //---- toggleButton5 ---- - toggleButton5.setText("underline"); - toggleButton5.putClientProperty("JButton.buttonType", "underline"); + toggleButton5.setText("tab"); + toggleButton5.putClientProperty("JButton.buttonType", "tab"); toggleButton5.setSelected(true); add(toggleButton5, "cell 5 2"); //---- toggleButton8 ---- - toggleButton8.setText("underline"); - toggleButton8.putClientProperty("JButton.buttonType", "underline"); + toggleButton8.setText("tab"); + toggleButton8.putClientProperty("JButton.buttonType", "tab"); toggleButton8.setEnabled(false); toggleButton8.setSelected(true); add(toggleButton8, "cell 5 2"); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd index 61ac0eeb..48ccc963 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd @@ -171,16 +171,16 @@ new FormModel { } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "toggleButton5" - "text": "underline" - "$client.JButton.buttonType": "underline" + "text": "tab" + "$client.JButton.buttonType": "tab" "selected": true }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 5 2" } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "toggleButton8" - "text": "underline" - "$client.JButton.buttonType": "underline" + "text": "tab" + "$client.JButton.buttonType": "tab" "enabled": false "selected": true }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { From 27d4b5eba717d535a8c464e622122b9886c9af8f Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 15 Jan 2020 11:05:16 +0100 Subject: [PATCH 34/46] ToggleButton: Support per component styling for tab-style toggle buttons with client properties `JToggleButton.tab.underlineHeight` (integer), `JToggleButton.tab.underlineColor` (Color) and `JToggleButton.tab.selectedBackground` (Color) (issue #45) --- CHANGELOG.md | 4 +++ .../formdev/flatlaf/FlatClientProperties.java | 34 +++++++++++++++++++ .../flatlaf/ui/FlatToggleButtonUI.java | 14 ++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9bef8e1..41dcd972 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ FlatLaf Change Log changed (is no longer an instance of `FlatButtonBorder`). - ToggleButton: Renamed toggle button type "underline" to "tab" (value of client property `JButton.buttonType` is now `tab`). +- ToggleButton: Support per component styling for tab-style toggle buttons with + client properties `JToggleButton.tab.underlineHeight` (integer), + `JToggleButton.tab.underlineColor` (Color) and + `JToggleButton.tab.selectedBackground` (Color). (issue #45) - ToggleButton: No longer use focus width for tab-style toggle buttons to compute component size, which reduces/fixes component size in "Flat IntelliJ" and "Flat Darcula" themes. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index be2707d6..016b048b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -16,6 +16,7 @@ package com.formdev.flatlaf; +import java.awt.Color; import java.util.Objects; import javax.swing.JComponent; @@ -124,6 +125,30 @@ public interface FlatClientProperties */ String PLACEHOLDER_TEXT = "JTextField.placeholderText"; + /** + * Height of underline if toggle button type is {@link #BUTTON_TYPE_TAB}. + *

+ * Component {@link javax.swing.JToggleButton}
+ * Value type {@link java.lang.Integer} + */ + String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight"; + + /** + * Color of underline if toggle button type is {@link #BUTTON_TYPE_TAB}. + *

+ * Component {@link javax.swing.JToggleButton}
+ * Value type {@link java.awt.Color} + */ + String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor"; + + /** + * Background color if selected and toggle button type is {@link #BUTTON_TYPE_TAB}. + *

+ * Component {@link javax.swing.JToggleButton}
+ * Value type {@link java.awt.Color} + */ + String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"; + /** * Checks whether a client property of a component has the given value. */ @@ -148,4 +173,13 @@ public interface FlatClientProperties Object value = c.getClientProperty( key ); return (value instanceof Integer) ? (int) value : defaultValue; } + + /** + * Checks whether a client property of a component is a color and returns its value. + * If the client property is not set, or not a color, defaultValue is returned. + */ + static Color clientPropertyColor( JComponent c, String key, Color defaultValue ) { + Object value = c.getClientProperty( key ); + return (value instanceof Color) ? (Color) value : defaultValue; + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java index 2c232de3..c664a7dd 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToggleButtonUI.java @@ -144,6 +144,12 @@ public class FlatToggleButtonUI b.repaint(); break; + + case TAB_BUTTON_UNDERLINE_HEIGHT: + case TAB_BUTTON_UNDERLINE_COLOR: + case TAB_BUTTON_SELECTED_BACKGROUND: + b.repaint(); + break; } } @@ -160,7 +166,7 @@ public class FlatToggleButtonUI // paint background Color background = buttonStateColor( c, - selected ? tabSelectedBackground : null, + selected ? clientPropertyColor( c, TAB_BUTTON_SELECTED_BACKGROUND, tabSelectedBackground ) : null, null, tabFocusBackground, tabHoverBackground, null ); if( background != null ) { g.setColor( background ); @@ -169,8 +175,10 @@ public class FlatToggleButtonUI // paint underline if selected if( selected ) { - int underlineHeight = UIScale.scale( tabUnderlineHeight ); - g.setColor( c.isEnabled() ? tabUnderlineColor : tabDisabledUnderlineColor ); + int underlineHeight = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) ); + g.setColor( c.isEnabled() + ? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor ) + : tabDisabledUnderlineColor ); g.fillRect( 0, height - underlineHeight, width, underlineHeight ); } } else From fe15078bbd6055b29207391a83f2672815afda40 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 15 Jan 2020 12:52:39 +0100 Subject: [PATCH 35/46] TabbedPane: support per component tab height --- CHANGELOG.md | 2 ++ .../java/com/formdev/flatlaf/FlatClientProperties.java | 8 ++++++++ .../java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java | 2 ++ 3 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41dcd972..c672da9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ FlatLaf Change Log - ToggleButton: No longer use focus width for tab-style toggle buttons to compute component size, which reduces/fixes component size in "Flat IntelliJ" and "Flat Darcula" themes. +- TabbedPane: Support per component tab height (set client property + `JTabbedPane.tabHeight` to an integer). ## 0.24 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 016b048b..09a84016 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -117,6 +117,14 @@ public interface FlatClientProperties */ String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder"; + /** + * Specifies the height of a tab. + *

+ * Component {@link javax.swing.JTabbedPane}
+ * Value type {@link java.lang.Integer} + */ + String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight"; + /** * Placeholder text that is only painted if the text field is empty. *

diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java index a4418f32..7d6415fb 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java @@ -169,6 +169,7 @@ public class FlatTabbedPaneUI switch( e.getPropertyName() ) { case TABBED_PANE_SHOW_TAB_SEPARATORS: case TABBED_PANE_HAS_FULL_BORDER: + case TABBED_PANE_TAB_HEIGHT: tabPane.revalidate(); tabPane.repaint(); break; @@ -215,6 +216,7 @@ public class FlatTabbedPaneUI @Override protected int calculateTabHeight( int tabPlacement, int tabIndex, int fontHeight ) { + int tabHeight = clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight ); return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, fontHeight ) - 2 /* was added by superclass */ ); } From f9accc2a7a75f1901d45532892a8328405754c12 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 15 Jan 2020 17:13:39 +0100 Subject: [PATCH 36/46] ProgressBar: support square painting and larger height even if no string is painted --- CHANGELOG.md | 3 ++ .../formdev/flatlaf/FlatClientProperties.java | 16 +++++++++ .../formdev/flatlaf/ui/FlatProgressBarUI.java | 34 +++++++++++++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c672da9a..6d31c84c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ FlatLaf Change Log and "Flat Darcula" themes. - TabbedPane: Support per component tab height (set client property `JTabbedPane.tabHeight` to an integer). +- ProgressBar: Support square painting (set client property + `JProgressBar.square` to `true`) and larger height even if no string is + painted (set client property `JProgressBar.largeHeight` to `true`). ## 0.24 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 09a84016..98ca89c2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -93,6 +93,22 @@ public interface FlatClientProperties */ String MINIMUM_HEIGHT = "JComponent.minimumHeight"; + /** + * Specifies whether the progress bar has always the larger height even if no string is painted. + *

+ * Component {@link javax.swing.JProgressBar}
+ * Value type {@link java.lang.Boolean} + */ + String PROGRESS_BAR_LARGE_HEIGHT = "JProgressBar.largeHeight"; + + /** + * Specifies whether the progress bar is paint with square edges. + *

+ * Component {@link javax.swing.JProgressBar}
+ * Value type {@link java.lang.Boolean} + */ + String PROGRESS_BAR_SQUARE = "JProgressBar.square"; + /** * Specifies whether the decrease/increase arrow buttons of a scrollbar are shown. *

diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java index 6fc00936..45d2c0ef 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatProgressBarUI.java @@ -16,6 +16,7 @@ package com.formdev.flatlaf.ui; +import static com.formdev.flatlaf.FlatClientProperties.*; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics; @@ -23,6 +24,7 @@ import java.awt.Graphics2D; import java.awt.Insets; import java.awt.geom.Area; import java.awt.geom.RoundRectangle2D; +import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.JProgressBar; import javax.swing.LookAndFeel; @@ -60,6 +62,8 @@ public class FlatProgressBarUI protected Dimension horizontalSize; protected Dimension verticalSize; + private PropertyChangeListener propertyChangeListener; + public static ComponentUI createUI( JComponent c ) { return new FlatProgressBarUI(); } @@ -75,11 +79,35 @@ public class FlatProgressBarUI verticalSize = UIManager.getDimension( "ProgressBar.verticalSize" ); } + @Override + protected void installListeners() { + super.installListeners(); + + propertyChangeListener = e -> { + switch( e.getPropertyName() ) { + case PROGRESS_BAR_LARGE_HEIGHT: + case PROGRESS_BAR_SQUARE: + progressBar.revalidate(); + progressBar.repaint(); + break; + } + }; + progressBar.addPropertyChangeListener( propertyChangeListener ); + } + + @Override + protected void uninstallListeners() { + super.uninstallListeners(); + + progressBar.removePropertyChangeListener( propertyChangeListener ); + propertyChangeListener = null; + } + @Override public Dimension getPreferredSize( JComponent c ) { Dimension size = super.getPreferredSize( c ); - if( progressBar.isStringPainted() ) { + if( progressBar.isStringPainted() || clientPropertyBoolean( c, PROGRESS_BAR_LARGE_HEIGHT, false ) ) { // recalculate progress height/width to make it smaller Insets insets = progressBar.getInsets(); FontMetrics fm = progressBar.getFontMetrics( progressBar.getFont() ); @@ -122,7 +150,9 @@ public class FlatProgressBarUI return; boolean horizontal = (progressBar.getOrientation() == JProgressBar.HORIZONTAL); - int arc = Math.min( UIScale.scale( this.arc ), horizontal ? height : width ); + int arc = clientPropertyBoolean( c, PROGRESS_BAR_SQUARE, false ) + ? 0 + : Math.min( UIScale.scale( this.arc ), horizontal ? height : width ); FlatUIUtils.setRenderingHints( (Graphics2D) g ); From 2f6da3e84ae91ec6a4e9f726abf6d27c9f8aa555 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 15 Jan 2020 18:13:43 +0100 Subject: [PATCH 37/46] FlatInspector: improved inspecting parent levels: `Ctrl` adds 1 level, `Shift` adds 2 levels and `Alt` adds 4 levels; no longer limit inspecting to content pane --- .../com/formdev/flatlaf/testing/FlatInspector.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java index c197d5e3..9bd3b9b8 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java @@ -71,7 +71,7 @@ public class FlatInspector private Component lastComponent; private int lastX; private int lastY; - private boolean inspectParent; + private int inspectParentLevel; private JComponent highlightFigure; private JToolTip tip; @@ -112,7 +112,9 @@ public class FlatInspector public void mouseMoved( MouseEvent e ) { lastX = e.getX(); lastY = e.getY(); - inspectParent = e.isShiftDown(); + inspectParentLevel = (e.isControlDown() ? 1 : 0) + + (e.isShiftDown() ? 2 : 0) + + (e.isAltDown() ? 4 : 0); inspect( lastX, lastY ); } }; @@ -157,10 +159,9 @@ public class FlatInspector Container contentPane = rootPane.getContentPane(); Point pt = SwingUtilities.convertPoint( rootPane.getGlassPane(), x, y, contentPane ); Component c = SwingUtilities.getDeepestComponentAt( contentPane, pt.x, pt.y ); - if( inspectParent && c != null && c != contentPane ) + for( int i = 0; i < inspectParentLevel && c != null; i++ ) { c = c.getParent(); - if( c == contentPane || (c != null && c.getParent() == contentPane) ) - c = null; + } if( c == lastComponent ) return; @@ -300,6 +301,9 @@ public class FlatInspector text += "Left-to-right: " + c.getComponentOrientation().isLeftToRight() + '\n'; text += "Parent: " + c.getParent().getClass().getName(); + if( inspectParentLevel > 0 ) + text += "\n\nParent level: " + inspectParentLevel; + return text; } From 281f014aa035ef07a43454adcdde60354194803c Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 15 Jan 2020 19:10:42 +0100 Subject: [PATCH 38/46] FlatTestFrame: support testing 3rd party lafs --- flatlaf-testing/build.gradle.kts | 4 +++ .../flatlaf/testing/FlatTestFrame.java | 34 +++++++++++++++++++ .../formdev/flatlaf/testing/FlatTestFrame.jfd | 3 +- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/flatlaf-testing/build.gradle.kts b/flatlaf-testing/build.gradle.kts index 4fd94cba..ea68160d 100644 --- a/flatlaf-testing/build.gradle.kts +++ b/flatlaf-testing/build.gradle.kts @@ -33,6 +33,10 @@ dependencies { implementation( "org.swinglabs.swingx:swingx-beaninfo:1.6.5-1" ) implementation( "com.jidesoft:jide-oss:3.6.18" ) implementation( "org.netbeans.api:org-openide-awt:RELEASE112" ) + +// implementation( "org.pushing-pixels:radiance-substance:2.5.1" ) +// implementation( "com.weblookandfeel:weblaf-ui:1.2.12" ) +// implementation( "com.jgoodies:jgoodies-looks:2.7.0" ) } java { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java index 36ac6541..97f8c5da 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java @@ -111,6 +111,30 @@ public class FlatTestFrame lafModel.addElement( new LookAndFeelInfo( name, className ) ); } + String substanceClassName = "org.pushingpixels.substance.api.skin.SubstanceGraphiteAquaLookAndFeel"; + if( SystemInfo.IS_JAVA_9_OR_LATER && isClassAvailable( substanceClassName ) ) { + lafModel.addElement( new LookAndFeelInfo( "Substance (F5)", substanceClassName ) ); + registerSwitchToLookAndFeel( KeyEvent.VK_F5, substanceClassName ); + } + + String webLafClassName = "com.alee.laf.WebLookAndFeel"; + if( isClassAvailable( webLafClassName ) ) { + lafModel.addElement( new LookAndFeelInfo( "WebLaf (F12)", webLafClassName ) ); + registerSwitchToLookAndFeel( KeyEvent.VK_F12, webLafClassName ); + } + + String looksPlasticClassName = "com.jgoodies.looks.plastic.PlasticLookAndFeel"; + if( isClassAvailable( looksPlasticClassName ) ) { + lafModel.addElement( new LookAndFeelInfo( "JGoodies Looks Plastic (F6)", looksPlasticClassName ) ); + registerSwitchToLookAndFeel( KeyEvent.VK_F6, looksPlasticClassName ); + } + + String looksWindowsClassName = "com.jgoodies.looks.windows.WindowsLookAndFeel"; + if( isClassAvailable( looksWindowsClassName ) ) { + lafModel.addElement( new LookAndFeelInfo( "JGoodies Looks Windows (F7)", looksWindowsClassName ) ); + registerSwitchToLookAndFeel( KeyEvent.VK_F7, looksWindowsClassName ); + } + lookAndFeelComboBox.setModel( lafModel ); updateScaleFactorComboBox(); @@ -203,6 +227,15 @@ public class FlatTestFrame JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); } + private boolean isClassAvailable( String className ) { + try { + Class.forName( className ); + return true; + } catch( ClassNotFoundException ex ) { + return false; + } + } + public void showFrame( Supplier contentFactory ) { this.contentFactory = contentFactory; this.content = contentFactory.get(); @@ -481,6 +514,7 @@ public class FlatTestFrame null)); //---- lookAndFeelComboBox ---- + lookAndFeelComboBox.setMaximumRowCount(20); lookAndFeelComboBox.addActionListener(e -> lookAndFeelChanged()); buttonBar.add(lookAndFeelComboBox, "cell 0 0"); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.jfd index 4a57d740..f92a2a2f 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -27,6 +27,7 @@ new FormModel { name: "buttonBar" add( new FormComponent( "com.formdev.flatlaf.demo.LookAndFeelsComboBox" ) { name: "lookAndFeelComboBox" + "maximumRowCount": 20 addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "lookAndFeelChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 0" From d50fe606eed90065345f3bb198cdb01ce8a69c49 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 16 Jan 2020 19:25:58 +0100 Subject: [PATCH 39/46] Tree on macOS: fixed `Left` and `Right` keys to collapse or expand nodes --- CHANGELOG.md | 2 + .../java/com/formdev/flatlaf/FlatLaf.java | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d31c84c..277f3789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ FlatLaf Change Log - TabbedPane: In scroll-tab-layout, the cropped line is now hidden. (issue #40) - Tree: UI default value `Tree.textBackground` now has a valid color and is no longer `null`. +- Tree on macOS: Fixed Left and Right keys to collapse or + expand nodes. - Button and ToggleButton: Support per component minimum height (set client property `JComponent.minimumHeight` to an integer). (issue #44) - Button and ToggleButton: Do not apply minimum width if button border was diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index 3d708d7e..0f1c7aa4 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -34,12 +34,15 @@ import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractButton; +import javax.swing.InputMap; import javax.swing.JLabel; import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.PopupFactory; import javax.swing.SwingUtilities; import javax.swing.UIDefaults; +import javax.swing.UIDefaults.LazyValue; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.plaf.ColorUIResource; @@ -231,6 +234,7 @@ public abstract class FlatLaf initFonts( defaults ); initIconColors( defaults, isDark() ); + initInputMaps( defaults ); // load defaults from properties List> lafClassesForDefaultsLoading = getLafClassesForDefaultsLoading(); @@ -337,6 +341,40 @@ public abstract class FlatLaf defaults.put( "Objects.BlackText", new ColorUIResource( 0x231F20 ) ); } + private void initInputMaps( UIDefaults defaults ) { + if( SystemInfo.IS_MAC ) { + // AquaLookAndFeel (the base for UI defaults on macOS) uses special + // action keys (e.g. "aquaExpandNode") for its macOS typical tree node + // expanding/collapsing, which are not available in FlatLaf. + // --> map the keys back to default Java actions + modifyInputMap( defaults, "Tree.focusInputMap", + "RIGHT", "selectChild", + "KP_RIGHT", "selectChild", + "LEFT", "selectParent", + "KP_LEFT", "selectParent", + "shift RIGHT", null, + "shift KP_RIGHT", null, + "shift LEFT", null, + "shift KP_LEFT", null, + "ctrl LEFT", null, + "ctrl KP_LEFT", null, + "ctrl RIGHT", null, + "ctrl KP_RIGHT", null + ); + defaults.put( "Tree.focusInputMap.RightToLeft", new UIDefaults.LazyInputMap( new Object[] { + "RIGHT", "selectParent", + "KP_RIGHT", "selectParent", + "LEFT", "selectChild", + "KP_LEFT", "selectChild" + } ) ); + } + } + + private void modifyInputMap( UIDefaults defaults, String key, Object... bindings ) { + // Note: not using `defaults.get(key)` here because this would resolve the lazy value + defaults.put( key, new LazyModifyInputMap( defaults.remove( key ), bindings ) ); + } + private static void reSetLookAndFeel() { EventQueue.invokeLater( () -> { LookAndFeel lookAndFeel = UIManager.getLookAndFeel(); @@ -445,4 +483,38 @@ public abstract class FlatLaf return false; } + + //---- class LazyModifyInputMap ------------------------------------------- + + private static class LazyModifyInputMap + implements LazyValue + { + private final Object baseInputMap; + private final Object[] bindings; + + public LazyModifyInputMap( Object baseInputMap, Object[] bindings ) { + this.baseInputMap = baseInputMap; + this.bindings = bindings; + } + + @Override + public Object createValue( UIDefaults table ) { + // get base input map + InputMap inputMap = (baseInputMap instanceof LazyValue) + ? (InputMap) ((LazyValue)baseInputMap).createValue( table ) + : (InputMap) baseInputMap; + + // modify input map (replace or remove) + for( int i = 0; i < bindings.length; i += 2 ) { + KeyStroke keyStroke = KeyStroke.getKeyStroke( (String) bindings[i] ); + if( bindings[i + 1] != null ) + inputMap.put( keyStroke, bindings[i + 1] ); + else + inputMap.remove( keyStroke ); + } + + return inputMap; + } + + } } From 8021f1a7fc80b3c191683de6e3d3d533487507f7 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 16 Jan 2020 23:29:35 +0100 Subject: [PATCH 40/46] ComboBox on macOS: fixed keyboard navigation and show/hide popup --- CHANGELOG.md | 1 + .../java/com/formdev/flatlaf/FlatLaf.java | 27 +++++++++-- .../formdev/flatlaf/ui/FlatComboBoxUI.java | 45 +++++++++++++++++++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 277f3789..bcffb291 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ FlatLaf Change Log longer `null`. - Tree on macOS: Fixed Left and Right keys to collapse or expand nodes. +- ComboBox on macOS: Fixed keyboard navigation and show/hide popup. - Button and ToggleButton: Support per component minimum height (set client property `JComponent.minimumHeight` to an integer). (issue #44) - Button and ToggleButton: Do not apply minimum width if button border was diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index 0f1c7aa4..b02e76f4 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -344,9 +344,26 @@ public abstract class FlatLaf private void initInputMaps( UIDefaults defaults ) { if( SystemInfo.IS_MAC ) { // AquaLookAndFeel (the base for UI defaults on macOS) uses special - // action keys (e.g. "aquaExpandNode") for its macOS typical tree node - // expanding/collapsing, which are not available in FlatLaf. - // --> map the keys back to default Java actions + // action keys (e.g. "aquaExpandNode") for some macOS specific behaviour. + // Those action keys are not available in FlatLaf, which makes it + // necessary to make some modifications. + + // combobox + defaults.put( "ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap( new Object[] { + "ESCAPE", "hidePopup", + "PAGE_UP", "pageUpPassThrough", + "PAGE_DOWN", "pageDownPassThrough", + "HOME", "homePassThrough", + "END", "endPassThrough", + "DOWN", "selectNext", + "KP_DOWN", "selectNext", + "SPACE", "spacePopup", + "ENTER", "enterPressed", + "UP", "selectPrevious", + "KP_UP", "selectPrevious" + } ) ); + + // tree node expanding/collapsing modifyInputMap( defaults, "Tree.focusInputMap", "RIGHT", "selectChild", "KP_RIGHT", "selectChild", @@ -486,6 +503,9 @@ public abstract class FlatLaf //---- class LazyModifyInputMap ------------------------------------------- + /** + * Takes a (lazy) base input map and lazily applies modifications to it specified in bindings. + */ private static class LazyModifyInputMap implements LazyValue { @@ -515,6 +535,5 @@ public abstract class FlatLaf return inputMap; } - } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index acf56ced..166efa36 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -28,6 +28,8 @@ import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseListener; @@ -35,13 +37,16 @@ import java.awt.geom.Rectangle2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; +import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; +import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JPanel; +import javax.swing.KeyStroke; import javax.swing.ListCellRenderer; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; @@ -54,6 +59,7 @@ import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.ComboPopup; import javax.swing.text.JTextComponent; import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.UIScale; /** @@ -271,6 +277,18 @@ public class FlatComboBoxUI editor.applyComponentOrientation( comboBox.getComponentOrientation() ); updateEditorColors(); + + // macOS + if( SystemInfo.IS_MAC && editor instanceof JTextComponent ) { + // delegate actions from editor text field to combobox, which is necessary + // because text field on macOS (based on Aqua LaF UI defaults) + // already handle those keys + InputMap inputMap = ((JTextComponent)editor).getInputMap(); + new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "UP" ) ); + new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_UP" ) ); + new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "DOWN" ) ); + new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_DOWN" ) ); + } } private void updateEditorColors() { @@ -608,4 +626,31 @@ public class FlatComboBoxUI rendererBorder.paintBorder( c, g, x, y, width, height ); } } + + //---- class EditorDelegateAction ----------------------------------------- + + /** + * Delegates actions from editor text field to combobox. + */ + private class EditorDelegateAction + extends AbstractAction + { + private final KeyStroke keyStroke; + + EditorDelegateAction( InputMap inputMap, KeyStroke keyStroke ) { + this.keyStroke = keyStroke; + + // add to input map + inputMap.put( keyStroke, this ); + } + + @Override + public void actionPerformed( ActionEvent e ) { + ActionListener action = comboBox.getActionForKeyStroke( keyStroke ); + if( action != null ) { + action.actionPerformed( new ActionEvent( comboBox, e.getID(), + e.getActionCommand(), e.getWhen(), e.getModifiers() ) ); + } + } + } } From f550f84acd7b3ea569aa92bc9454c3a09d3182bc Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 17 Jan 2020 01:01:30 +0100 Subject: [PATCH 41/46] Menu: fixed vertical alignment of sub-menus (issue #42) --- CHANGELOG.md | 1 + .../src/main/resources/com/formdev/flatlaf/FlatLaf.properties | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcffb291..27aeb6db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FlatLaf Change Log - Hide menu mnemonics by default and show them only when Alt key is pressed. (issue #43) +- Menu: Fixed vertical alignment of sub-menus. (issue #42) - TabbedPane: In scroll-tab-layout, the cropped line is now hidden. (issue #40) - Tree: UI default value `Tree.textBackground` now has a valid color and is no longer `null`. diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 8dc57f3f..e7505ba1 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -215,6 +215,8 @@ List.dropLineColor=@dropLineColor Menu.border=com.formdev.flatlaf.ui.FlatMarginBorder Menu.arrowIcon=com.formdev.flatlaf.icons.FlatMenuArrowIcon Menu.margin=2,2,2,2 +Menu.submenuPopupOffsetX={scaledInteger}-4 +Menu.submenuPopupOffsetY={scaledInteger}-1 #---- MenuBar ---- From 499c4dadd53ad26b1735d15a9fb0ef459e074e8c Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 17 Jan 2020 10:53:46 +0100 Subject: [PATCH 42/46] FlatDarkLaf.properties: use slightly brighter color for popup menu border --- .../main/resources/com/formdev/flatlaf/FlatDarkLaf.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties index 25fda3b0..e3245f58 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -154,7 +154,7 @@ MenuItemCheckBox.icon.disabledCheckmarkColor=#606060 #---- PopupMenu ---- -PopupMenu.borderColor=#515151 +PopupMenu.borderColor=#5e5e5e #---- ProgressBar ---- From e675d1b7e29cb2cf4baeae0a89b7f34e98086cd6 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 17 Jan 2020 11:03:48 +0100 Subject: [PATCH 43/46] show mnemonics if the active window does not have a focused component; ignore invisible components (issue #43) --- .../java/com/formdev/flatlaf/FlatLaf.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index b02e76f4..09e6d512 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -36,6 +36,7 @@ import java.util.logging.Logger; import javax.swing.AbstractButton; import javax.swing.InputMap; import javax.swing.JLabel; +import javax.swing.JRootPane; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; @@ -430,15 +431,15 @@ public abstract class FlatLaf if( SystemInfo.IS_MAC ) { // Ctrl+Alt keys must be pressed on Mac if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_ALT ) - showMnemonics( e.getID() == KeyEvent.KEY_PRESSED && e.isControlDown() && e.isAltDown() ); + showMnemonics( e.getID() == KeyEvent.KEY_PRESSED && e.isControlDown() && e.isAltDown(), e.getComponent() ); } else { // Alt key must be pressed on Windows and Linux if( keyCode == KeyEvent.VK_ALT ) - showMnemonics( e.getID() == KeyEvent.KEY_PRESSED ); + showMnemonics( e.getID() == KeyEvent.KEY_PRESSED, e.getComponent() ); } } - private static void showMnemonics( boolean show ) { + private static void showMnemonics( boolean show, Component c ) { if( show == showMnemonics ) return; @@ -449,13 +450,13 @@ public abstract class FlatLaf return; if( show ) { - // get focus owner - Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); - if( focusOwner == null ) + // get root pane + JRootPane rootPane = SwingUtilities.getRootPane( c ); + if( rootPane == null ) return; - // get focused window - Window window = SwingUtilities.windowForComponent( focusOwner ); + // get window + Window window = SwingUtilities.getWindowAncestor( rootPane ); if( window == null ) return; @@ -474,6 +475,9 @@ public abstract class FlatLaf private static void repaintMnemonics( Container container ) { for( Component c : container.getComponents() ) { + if( !c.isVisible() ) + continue; + if( hasMnemonic( c ) ) c.repaint(); From 10e2a5b1eb2b7a84d5eea402083ea8b1cfdd32da Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 17 Jan 2020 13:18:29 +0100 Subject: [PATCH 44/46] release 0.25 --- CHANGELOG.md | 2 +- README.md | 2 +- build.gradle.kts | 2 +- flatlaf-jide-oss/README.md | 2 +- flatlaf-swingx/README.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27aeb6db..77c68458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ FlatLaf Change Log ================== -## Unreleased +## 0.25 - Hide menu mnemonics by default and show them only when Alt key is pressed. (issue #43) diff --git a/README.md b/README.md index 6d2b1811..31266ee5 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ build script: groupId: com.formdev artifactId: flatlaf - version: 0.24 + version: 0.25 Otherwise download `flatlaf-.jar` here: diff --git a/build.gradle.kts b/build.gradle.kts index ad8ba89f..386bf1c3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -version = "0.24" +version = "0.25" allprojects { repositories { diff --git a/flatlaf-jide-oss/README.md b/flatlaf-jide-oss/README.md index 2014320c..762b90f1 100644 --- a/flatlaf-jide-oss/README.md +++ b/flatlaf-jide-oss/README.md @@ -26,7 +26,7 @@ build script: groupId: com.formdev artifactId: flatlaf-jide-oss - version: 0.24 + version: 0.25 Otherwise download `flatlaf-jide-oss-.jar` here: diff --git a/flatlaf-swingx/README.md b/flatlaf-swingx/README.md index a927b68e..36acb9c2 100644 --- a/flatlaf-swingx/README.md +++ b/flatlaf-swingx/README.md @@ -33,7 +33,7 @@ build script: groupId: com.formdev artifactId: flatlaf-swingx - version: 0.24 + version: 0.25 Otherwise download `flatlaf-swingx-.jar` here: From 7317ce44e73d13129b72044da974b50f2a750b3d Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 18 Jan 2020 10:25:55 +0100 Subject: [PATCH 45/46] update to Gradle 6.1 ./gradlew wrapper --gradle-version=6.1 --- gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 29 ++++++++++------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..f3d88b1c2faf2fc91d853cd5d4242b5547257070 100644 GIT binary patch delta 22808 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 delta 20005 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 nvEpR}Ffj;rE}sKLhd|1%F5dI!=ox-rLy2 Date: Sat, 18 Jan 2020 10:35:18 +0100 Subject: [PATCH 46/46] release 0.25.1 --- CHANGELOG.md | 5 +++++ README.md | 2 +- build.gradle.kts | 4 ++-- flatlaf-core/build.gradle.kts | 4 ++-- flatlaf-demo/build.gradle.kts | 2 +- flatlaf-extras/build.gradle.kts | 2 +- flatlaf-jide-oss/README.md | 2 +- flatlaf-jide-oss/build.gradle.kts | 4 ++-- flatlaf-swingx/README.md | 2 +- flatlaf-swingx/build.gradle.kts | 4 ++-- flatlaf-testing/build.gradle.kts | 2 +- 11 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c68458..dd42c9df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ FlatLaf Change Log ================== +## 0.25.1 + +Re-release of 0.25 because of problems with Maven Central. + + ## 0.25 - Hide menu mnemonics by default and show them only when Alt key is diff --git a/README.md b/README.md index 31266ee5..9e2368f0 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ build script: groupId: com.formdev artifactId: flatlaf - version: 0.25 + version: 0.25.1 Otherwise download `flatlaf-.jar` here: diff --git a/build.gradle.kts b/build.gradle.kts index 386bf1c3..7bc57e70 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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, @@ -14,7 +14,7 @@ * limitations under the License. */ -version = "0.25" +version = "0.25.1" allprojects { repositories { diff --git a/flatlaf-core/build.gradle.kts b/flatlaf-core/build.gradle.kts index 749c21da..b09ec33c 100644 --- a/flatlaf-core/build.gradle.kts +++ b/flatlaf-core/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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, @@ -106,7 +106,7 @@ publishing { licenses { license { name.set( "The Apache License, Version 2.0" ) - url.set( "http://www.apache.org/licenses/LICENSE-2.0.txt" ) + url.set( "https://www.apache.org/licenses/LICENSE-2.0.txt" ) } } diff --git a/flatlaf-demo/build.gradle.kts b/flatlaf-demo/build.gradle.kts index 20308a34..7eb88a8b 100644 --- a/flatlaf-demo/build.gradle.kts +++ b/flatlaf-demo/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/flatlaf-extras/build.gradle.kts b/flatlaf-extras/build.gradle.kts index 4e3e4025..ad3cabc1 100644 --- a/flatlaf-extras/build.gradle.kts +++ b/flatlaf-extras/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/flatlaf-jide-oss/README.md b/flatlaf-jide-oss/README.md index 762b90f1..04416ec4 100644 --- a/flatlaf-jide-oss/README.md +++ b/flatlaf-jide-oss/README.md @@ -26,7 +26,7 @@ build script: groupId: com.formdev artifactId: flatlaf-jide-oss - version: 0.25 + version: 0.25.1 Otherwise download `flatlaf-jide-oss-.jar` here: diff --git a/flatlaf-jide-oss/build.gradle.kts b/flatlaf-jide-oss/build.gradle.kts index 30da1764..c1394ef9 100644 --- a/flatlaf-jide-oss/build.gradle.kts +++ b/flatlaf-jide-oss/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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, @@ -80,7 +80,7 @@ publishing { licenses { license { name.set( "The Apache License, Version 2.0" ) - url.set( "http://www.apache.org/licenses/LICENSE-2.0.txt" ) + url.set( "https://www.apache.org/licenses/LICENSE-2.0.txt" ) } } diff --git a/flatlaf-swingx/README.md b/flatlaf-swingx/README.md index 36acb9c2..871f6068 100644 --- a/flatlaf-swingx/README.md +++ b/flatlaf-swingx/README.md @@ -33,7 +33,7 @@ build script: groupId: com.formdev artifactId: flatlaf-swingx - version: 0.25 + version: 0.25.1 Otherwise download `flatlaf-swingx-.jar` here: diff --git a/flatlaf-swingx/build.gradle.kts b/flatlaf-swingx/build.gradle.kts index e91135ed..25d2a07f 100644 --- a/flatlaf-swingx/build.gradle.kts +++ b/flatlaf-swingx/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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, @@ -80,7 +80,7 @@ publishing { licenses { license { name.set( "The Apache License, Version 2.0" ) - url.set( "http://www.apache.org/licenses/LICENSE-2.0.txt" ) + url.set( "https://www.apache.org/licenses/LICENSE-2.0.txt" ) } } diff --git a/flatlaf-testing/build.gradle.kts b/flatlaf-testing/build.gradle.kts index ea68160d..e88cf2bf 100644 --- a/flatlaf-testing/build.gradle.kts +++ b/flatlaf-testing/build.gradle.kts @@ -5,7 +5,7 @@ * 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 + * https://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,