From 9e476630279a7844b1ee3984c21084c0eb725237 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:04:42 -0700 Subject: [PATCH] Update flatlaf to v3.4.1 (#153) * Fix some UI bugs, use new split pane expandable side feature --- gradle/libs.versions.toml | 2 +- .../inductiveautomation/kindling/MainPanel.kt | 8 +- .../kindling/idb/generic/DBMetaDataTree.kt | 47 ++-- .../kindling/idb/generic/GenericView.kt | 249 +++++++++--------- .../kindling/idb/metrics/MetricCard.kt | 3 +- .../kindling/log/LogPanel.kt | 2 +- .../kindling/log/MDCPanel.kt | 10 +- .../kindling/log/TimePanel.kt | 25 +- .../kindling/utils/Components.kt | 50 ++-- .../kindling/xml/XmlViewer.kt | 4 +- .../xml/logback/SelectedLoggerCard.kt | 3 +- .../kindling/zip/views/gwbk/GwbkStatsView.kt | 3 +- .../resources/icons/bx-subdirectory-left.svg | 3 + 13 files changed, 220 insertions(+), 189 deletions(-) create mode 100644 src/main/resources/icons/bx-subdirectory-left.svg diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 910a5034..b7b5a506 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ java = "21" kotlin = "1.9.22" coroutines = "1.8.0" -flatlaf = "3.4" +flatlaf = "3.4.1" kotest = "5.8.1" ignition = "8.1.20" jackson = "2.17.0" diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/MainPanel.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/MainPanel.kt index f59ecd31..c5ef95e8 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/MainPanel.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/MainPanel.kt @@ -136,7 +136,7 @@ class MainPanel : JPanel(MigLayout("ins 6, fill, hidemode 3")) { private val landingPanel = JPanel(MigLayout("ins 0, fillx", "[center, grow]")).apply { add( JLabel("Open...").apply { - font = font.deriveFont(24F) + putClientProperty("FlatLaf.styleClass", "h1") }, ) for (tools in Tool.sortedByTitle.chunked(3)) { @@ -148,10 +148,8 @@ class MainPanel : JPanel(MigLayout("ins 6, fill, hidemode 3")) { } private fun toolTile(tool: Tool): JButton { - return JButton().apply { - text = tool.title - font = font.deriveFont(18F) - icon = tool.icon.derive(2F) + return JButton(tool.title, tool.icon.derive(2F)).apply { + putClientProperty("FlatLaf.styleClass", "h2.regular") iconTextGap = 20 verticalTextPosition = BOTTOM horizontalTextPosition = CENTER diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/DBMetaDataTree.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/DBMetaDataTree.kt index fdee555b..945b6738 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/DBMetaDataTree.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/DBMetaDataTree.kt @@ -2,14 +2,10 @@ package io.github.inductiveautomation.kindling.idb.generic import com.formdev.flatlaf.extras.FlatSVGIcon import com.formdev.flatlaf.extras.components.FlatTree -import com.jidesoft.swing.StyledLabelBuilder import com.jidesoft.swing.TreeSearchable -import com.jidesoft.tree.StyledTreeCellRenderer import io.github.inductiveautomation.kindling.utils.asActionIcon import io.github.inductiveautomation.kindling.utils.toFileSizeLabel -import java.awt.Font -import javax.swing.JTree -import javax.swing.UIManager +import io.github.inductiveautomation.kindling.utils.treeCellRenderer import javax.swing.tree.TreeModel import javax.swing.tree.TreePath import javax.swing.tree.TreeSelectionModel @@ -21,36 +17,27 @@ class DBMetaDataTree(treeModel: TreeModel) : FlatTree() { setShowsRootHandles(true) selectionModel.selectionMode = TreeSelectionModel.SINGLE_TREE_SELECTION setCellRenderer( - object : StyledTreeCellRenderer() { - override fun customizeStyledLabel(tree: JTree, value: Any?, sel: Boolean, expanded: Boolean, leaf: Boolean, row: Int, focused: Boolean) { - super.customizeStyledLabel(tree, value, sel, expanded, leaf, row, focused) - clearStyleRanges() - - foreground = when { - selected && focused -> UIManager.getColor("Tree.selectionForeground") - selected -> UIManager.getColor("Tree.selectionInactiveForeground") - else -> UIManager.getColor("Tree.textForeground") + treeCellRenderer { _, value, selected, _, _, _, hasFocus -> + when (value) { + is Table -> { + text = buildString { + append(value.name) + append(" ") + append("(${value.size.toFileSizeLabel()})") + } + icon = TABLE_ICON.asActionIcon(selected && hasFocus) } - when (value) { - is Table -> { - StyledLabelBuilder().apply { - add(value.name) - add(" ") - add("(${value.size.toFileSizeLabel()})", Font.ITALIC) - }.configure(this) - icon = TABLE_ICON.asActionIcon(selected || focused) - } - is Column -> { - StyledLabelBuilder().apply { - add(value.name) - add(" ") - add(value.type.takeIf { it.isNotEmpty() } ?: "UNKNOWN", Font.ITALIC) - }.configure(this) - icon = COLUMN_ICON.asActionIcon(selected || focused) + is Column -> { + text = buildString { + append(value.name) + append(" ") + append(value.type.takeIf { it.isNotEmpty() } ?: "UNKNOWN") } + icon = COLUMN_ICON.asActionIcon(selected && hasFocus) } } + this }, ) diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/GenericView.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/GenericView.kt index 19c9783a..2ad2b6a9 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/GenericView.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/GenericView.kt @@ -1,7 +1,11 @@ package io.github.inductiveautomation.kindling.idb.generic import com.formdev.flatlaf.extras.FlatSVGIcon +import com.formdev.flatlaf.extras.components.FlatSplitPane +import com.formdev.flatlaf.util.SystemInfo import com.jidesoft.comparator.AlphanumComparator +import io.github.inductiveautomation.kindling.core.Kindling.Preferences.UI.Theme +import io.github.inductiveautomation.kindling.core.Theme.Companion.theme import io.github.inductiveautomation.kindling.core.ToolPanel import io.github.inductiveautomation.kindling.utils.Action import io.github.inductiveautomation.kindling.utils.ButtonPanel @@ -16,6 +20,9 @@ import io.github.inductiveautomation.kindling.utils.javaType import io.github.inductiveautomation.kindling.utils.menuShortcutKeyMaskEx import io.github.inductiveautomation.kindling.utils.toList import net.miginfocom.swing.MigLayout +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea +import org.fife.ui.rsyntaxtextarea.SyntaxConstants +import org.fife.ui.rtextarea.RTextScrollPane import java.awt.event.KeyEvent import java.sql.Connection import java.sql.JDBCType @@ -28,7 +35,6 @@ import javax.swing.JButton import javax.swing.JMenuItem import javax.swing.JPanel import javax.swing.JPopupMenu -import javax.swing.JTextArea import javax.swing.JToggleButton import javax.swing.KeyStroke import javax.swing.tree.DefaultTreeModel @@ -85,10 +91,9 @@ class SortableTree(val tables: List) { val tree = DBMetaDataTree(DefaultTreeModel(root)) - private val sortActions: List = - TableComparator.entries.map { tableComparator -> - SortAction(tableComparator) - } + private val sortActions: List = TableComparator.entries.map { tableComparator -> + SortAction(tableComparator) + } inner class SortAction(comparator: TableComparator) : Action( description = comparator.tooltip, @@ -102,149 +107,156 @@ class SortableTree(val tables: List
) { var comparator: TableComparator by actionValue("tableComparator", comparator) } - private fun createSortButtons(): ButtonGroup = - ButtonGroup().apply { - for (sortAction in sortActions) { - add( - JToggleButton( - Action( - description = sortAction.description, - icon = sortAction.icon, - selected = sortAction.selected, - ) { e -> - sortAction.actionPerformed(e) - }, - ), - ) - } + private fun createSortButtons(): ButtonGroup = ButtonGroup().apply { + for (sortAction in sortActions) { + add( + JToggleButton( + Action( + description = sortAction.description, + icon = sortAction.icon, + selected = sortAction.selected, + ) { e -> + sortAction.actionPerformed(e) + }, + ), + ) } + } private val sortButtons = createSortButtons() - val component = - ButtonPanel(sortButtons).apply { - add(FlatScrollPane(tree), "newline, push, grow") - } + val component = ButtonPanel(sortButtons).apply { + add(FlatScrollPane(tree), "newline, push, grow") + } } class GenericView(connection: Connection) : ToolPanel("ins 0, fill, hidemode 3") { @Suppress("SqlResolve") - private val tables: List
= - connection - .executeQuery("""SELECT name FROM main.sqlite_schema WHERE type = "table" ORDER BY name""") - .toList { resultSet -> - resultSet.getString(1) - }.mapIndexed { i, tableName -> - Table( - name = tableName, - _parent = { sortableTree.root }, - columns = connection - .executeQuery("""PRAGMA table_xinfo("$tableName");""") - .toList { resultSet -> - Column( - name = resultSet["name"], - type = resultSet["type"], - notNull = resultSet["notnull"], - defaultValue = resultSet["dflt_value"], - primaryKey = resultSet["pk"], - hidden = resultSet["hidden"], - _parent = { sortableTree.root.getChildAt(i) }, - ) - }, - size = connection - .executeQuery("""SELECT SUM("pgsize") FROM "dbstat" WHERE name='$tableName'""")[1], - ) - } + private val tables: List
= connection + .executeQuery("""SELECT name FROM main.sqlite_schema WHERE type = "table" ORDER BY name""") + .toList { resultSet -> + resultSet.getString(1) + }.mapIndexed { i, tableName -> + Table( + name = tableName, + _parent = { sortableTree.root }, + columns = connection + .executeQuery("""PRAGMA table_xinfo("$tableName");""") + .toList { resultSet -> + Column( + name = resultSet["name"], + type = resultSet["type"], + notNull = resultSet["notnull"], + defaultValue = resultSet["dflt_value"], + primaryKey = resultSet["pk"], + hidden = resultSet["hidden"], + _parent = { sortableTree.root.getChildAt(i) }, + ) + }, + size = connection + .executeQuery("""SELECT SUM("pgsize") FROM "dbstat" WHERE name='$tableName'""")[1], + ) + } private val sortableTree = SortableTree(tables) - private val query = JTextArea(0, 0) + private val query = RSyntaxTextArea().apply { + syntaxEditingStyle = SyntaxConstants.SYNTAX_STYLE_SQL - private val execute = - Action(name = "Execute") { - results.result = - if (!query.text.isNullOrEmpty()) { - try { - connection.executeQuery(query.text) - .use { resultSet -> - val columnCount = resultSet.metaData.columnCount - val names = List(columnCount) { i -> resultSet.metaData.getColumnName(i + 1) } - val types = - List(columnCount) { i -> - val timestamp = - TIMESTAMP_COLUMN_NAMES.any { - resultSet.metaData.getColumnName(i + 1).contains(it, true) - } + theme = Theme.currentValue - if (timestamp) { - Timestamp::class.java - } else { - val sqlType = resultSet.metaData.getColumnType(i + 1) - val jdbcType = JDBCType.valueOf(sqlType) - jdbcType.javaType - } - } + Theme.addChangeListener { newTheme -> + theme = newTheme + } + } - val data = - resultSet.toList { - List(columnCount) { i -> - // SQLite stores booleans as ints, we'll use actual booleans to make things easier - if (types[i] == Boolean::class.javaObjectType) { - resultSet.getObject(i + 1) == 1 - } else { - resultSet.getObject(i + 1) - } - } - } + private val execute = Action( + name = "Execute", + description = "Execute (${if (SystemInfo.isMacOS) "⌘" else "Ctrl"} + Enter)", + icon = FlatSVGIcon("icons/bx-subdirectory-left.svg").asActionIcon(), + accelerator = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, menuShortcutKeyMaskEx), + ) { + results.result = if (!query.text.isNullOrEmpty()) { + try { + connection.executeQuery(query.text) + .use { resultSet -> + val columnCount = resultSet.metaData.columnCount + val names = List(columnCount) { i -> + resultSet.metaData.getColumnName(i + 1) + } + val types = List(columnCount) { i -> + val timestamp = + TIMESTAMP_COLUMN_NAMES.any { + resultSet.metaData.getColumnName(i + 1).contains(it, true) + } - QueryResult.Success(names, types, data) + if (timestamp) { + Timestamp::class.java + } else { + val sqlType = resultSet.metaData.getColumnType(i + 1) + val jdbcType = JDBCType.valueOf(sqlType) + jdbcType.javaType } - } catch (e: Exception) { - QueryResult.Error(e.message ?: "Error") + } + + val data = resultSet.toList { + List(columnCount) { i -> + // SQLite stores booleans as ints, we'll use actual booleans to make things easier + if (types[i] == Boolean::class.javaObjectType) { + resultSet.getObject(i + 1) == 1 + } else { + resultSet.getObject(i + 1) + } + } + } + + QueryResult.Success(names, types, data) } - } else { - QueryResult.Error("Enter a query in the text field above") - } + } catch (e: Exception) { + QueryResult.Error(e.message ?: "Error") + } + } else { + QueryResult.Error("Enter a query in the text field above") } + } - private val queryPanel = - JPanel(MigLayout("ins 0, fill")).apply { - add(JButton(execute), "wrap") - add(query, "push, grow") - } + private val queryPanel = JPanel(MigLayout("ins 0, fill")).apply { + add(RTextScrollPane(query), "push, grow, wrap") + add(JButton(execute), "ax right, wrap") + } private val results = ResultsPanel() init { val ctrlEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, menuShortcutKeyMaskEx) getInputMap(WHEN_IN_FOCUSED_WINDOW).put(ctrlEnter, "execute") + query.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(ctrlEnter, "execute") actionMap.put("execute", execute) + query.actionMap.put("execute", execute) sortableTree.tree.attachPopupMenu { event -> val path = getClosestPathForLocation(event.x, event.y) when (val node = path?.lastPathComponent) { - is Table -> - JPopupMenu().apply { - add( - JMenuItem( - Action("SELECT * FROM ${node.name}") { - query.text = "SELECT * FROM ${node.name};" - }, - ), - ) - } + is Table -> JPopupMenu().apply { + add( + JMenuItem( + Action("SELECT * FROM ${node.name}") { + query.text = "SELECT * FROM ${node.name};" + }, + ), + ) + } - is Column -> - JPopupMenu().apply { - val table = path.parentPath.lastPathComponent as Table - add( - JMenuItem( - Action("SELECT ${node.name} FROM ${table.name}") { - query.text = "SELECT ${node.name} FROM ${table.name}" - }, - ), - ) - } + is Column -> JPopupMenu().apply { + val table = path.parentPath.lastPathComponent as Table + add( + JMenuItem( + Action("SELECT ${node.name} FROM ${table.name}") { + query.text = "SELECT ${node.name} FROM ${table.name}" + }, + ), + ) + } else -> null } @@ -254,9 +266,10 @@ class GenericView(connection: Connection) : ToolPanel("ins 0, fill, hidemode 3") HorizontalSplitPane( sortableTree.component, VerticalSplitPane( - FlatScrollPane(queryPanel), + queryPanel, results, resizeWeight = 0.2, + expandableSide = FlatSplitPane.ExpandableSide.both, ), resizeWeight = 0.1, ), diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/idb/metrics/MetricCard.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/idb/metrics/MetricCard.kt index f374bbf4..7a00079a 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/idb/metrics/MetricCard.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/idb/metrics/MetricCard.kt @@ -13,7 +13,6 @@ import org.jfree.chart.annotations.XYLineAnnotation import org.jfree.data.statistics.Regression import org.jfree.data.xy.XYDataset import java.awt.BasicStroke -import java.awt.Font import java.text.DecimalFormat import java.text.FieldPosition import java.text.NumberFormat @@ -60,7 +59,7 @@ class MetricCard(val metric: Metric, data: List) : JPanel(MigLayout( init { add( JLabel(metric.name, CENTER).apply { - font = font.deriveFont(Font.BOLD, 14.0F) + putClientProperty("FlatLaf.styleClass", "h3") }, "span, pushx, growx", ) diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/log/LogPanel.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/log/LogPanel.kt index d4e86b58..d2408d85 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/log/LogPanel.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/log/LogPanel.kt @@ -198,7 +198,7 @@ class LogPanel( VerticalSplitPane( HorizontalSplitPane( sidebar, - JPanel(MigLayout("fill")).apply { + JPanel(MigLayout("ins 0, fill")).apply { add(header, "wrap, growx") add(tableScrollPane, "grow, push") }, diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/log/MDCPanel.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/log/MDCPanel.kt index 21acd468..eb96f9ab 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/log/MDCPanel.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/log/MDCPanel.kt @@ -134,6 +134,7 @@ internal class MDCPanel(events: List) : FilterPanel() } private val removeFilter = Action( + name = "Remove", description = "Remove Selected Filter", icon = FlatSVGIcon("icons/bx-minus.svg").asActionIcon(), ) { @@ -156,7 +157,7 @@ internal class MDCPanel(events: List) : FilterPanel() } private val removeAllFilters = Action( - name = "Clear", + name = "Clear All", description = "Remove All Filters", icon = FlatSVGIcon("icons/bx-x.svg").asActionIcon(), ) { @@ -200,7 +201,12 @@ internal class MDCPanel(events: List) : FilterPanel() add(keyCombo, "growx, wrap, wmax 100%") add(valueCombo, "growx, wrap, wmax 100%") add(JButton(addFilter), "align right, split") - add(JButton(removeFilter), "gapx 2") + add( + JButton(removeFilter).apply { + hideActionText = true + }, + "gapx 2", + ) add(FlatScrollPane(filterTable), "newline, pushy, grow") add(JButton(removeAllFilters), "align right, newline") } diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/log/TimePanel.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/log/TimePanel.kt index 49ad1034..9ffd3a7a 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/log/TimePanel.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/log/TimePanel.kt @@ -51,6 +51,7 @@ import javax.swing.SpinnerNumberModel import javax.swing.SwingConstants import javax.swing.UIManager import javax.swing.border.LineBorder +import kotlin.math.absoluteValue internal class TimePanel( data: List, @@ -130,7 +131,8 @@ internal class TimePanel( private fun selectTime(timeToSelect: Instant) { val table = containingLogPanel?.table ?: return - val modelIndex = (table.model as LogsModel<*>).data.indexOfFirst { it.timestamp.truncatedTo(ChronoUnit.MINUTES) == timeToSelect } + val modelIndex = (table.model as LogsModel<*>).data + .indexOfFirst { it.timestamp.truncatedTo(ChronoUnit.MINUTES) == timeToSelect } if (modelIndex == -1) return val viewIndex = table.convertRowIndexToView(modelIndex) @@ -313,10 +315,20 @@ class DateTimeSelector( for (amount in listOf(-30L, -15, -5, -1, 1L, 5, 15, 30)) { add( FlatButton().apply { - action = - Action("%+d".format(amount)) { - time = time.plusSeconds(amount * 60) - } + action = Action( + name = "%+d".format(amount), + description = buildString { + append(if (amount > 0) "Add" else "Subtract") + append(" ") + append(amount.absoluteValue) + append(" minute") + if (amount.absoluteValue > 1) { + append("s") + } + }, + ) { + time = time.plusSeconds(amount * 60) + } margin = Insets(1, 1, 1, 1) }, "w 12.5%, sgx", @@ -449,7 +461,8 @@ private object DensityColumns : ColumnList() { private val minuteFormatter: DateTimeFormatter get() { if (!this::_formatter.isInitialized) { - _formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm").withZone(LogViewer.SelectedTimeZone.currentValue) + _formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm") + .withZone(LogViewer.SelectedTimeZone.currentValue) } if (_formatter.zone != LogViewer.SelectedTimeZone.currentValue) { _formatter = _formatter.withZone(LogViewer.SelectedTimeZone.currentValue) diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/utils/Components.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/utils/Components.kt index 4f0c1f99..b59ce427 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/utils/Components.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/utils/Components.kt @@ -5,6 +5,8 @@ package io.github.inductiveautomation.kindling.utils import com.formdev.flatlaf.FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING import com.formdev.flatlaf.FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING_LARGE import com.formdev.flatlaf.extras.components.FlatScrollPane +import com.formdev.flatlaf.extras.components.FlatSplitPane +import com.formdev.flatlaf.extras.components.FlatSplitPane.ExpandableSide import com.formdev.flatlaf.util.SystemInfo import com.jidesoft.swing.StyledLabel import com.jidesoft.swing.StyledLabelBuilder @@ -17,7 +19,6 @@ import javax.swing.ButtonGroup import javax.swing.JFrame import javax.swing.JPanel import javax.swing.JSplitPane -import javax.swing.SwingConstants import javax.swing.border.EmptyBorder inline fun FlatScrollPane( @@ -78,31 +79,44 @@ fun HorizontalSplitPane( left: Component, right: Component, resizeWeight: Double = 0.5, + expandableSide: ExpandableSide = ExpandableSide.right, block: JSplitPane.() -> Unit = {}, -) = JSplitPane(SwingConstants.VERTICAL, left, right).apply { - isOneTouchExpandable = true - this.resizeWeight = resizeWeight - addComponentListener( - object : ComponentAdapter() { - override fun componentShown(e: ComponentEvent?) { - setDividerLocation(resizeWeight) - } - }, - ) - - block() -} +) = createSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right, resizeWeight, expandableSide, block) fun VerticalSplitPane( top: Component, bottom: Component, resizeWeight: Double = 0.5, + // the top ("left") is the one that's allowed to expand + expandableSide: ExpandableSide = ExpandableSide.left, block: JSplitPane.() -> Unit = {}, -) = JSplitPane(SwingConstants.HORIZONTAL, top, bottom).apply { - isOneTouchExpandable = true - this.resizeWeight = resizeWeight +) = createSplitPane(JSplitPane.VERTICAL_SPLIT, top, bottom, resizeWeight, expandableSide, block) - block() +private fun createSplitPane( + orientation: Int, + left: Component, + right: Component, + resizeWeight: Double, + expandableSide: ExpandableSide, + block: JSplitPane.() -> Unit, +): FlatSplitPane { + return FlatSplitPane().apply { + this.orientation = orientation + this.leftComponent = left + this.rightComponent = right + this.isOneTouchExpandable = true + this.expandableSide = expandableSide + this.resizeWeight = resizeWeight + addComponentListener( + object : ComponentAdapter() { + override fun componentShown(e: ComponentEvent?) { + setDividerLocation(resizeWeight) + } + }, + ) + + block() + } } /** diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/xml/XmlViewer.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/xml/XmlViewer.kt index 40b804fd..b85e5db3 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/xml/XmlViewer.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/xml/XmlViewer.kt @@ -16,8 +16,8 @@ internal class XmlViewer(file: List) : JPanel(MigLayout("ins 6, fill, hi syntaxEditingStyle = "text/xml" theme = Theme.currentValue - Theme.addChangeListener { - theme = Theme.currentValue + Theme.addChangeListener { newValue -> + theme = newValue } }, ), diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/xml/logback/SelectedLoggerCard.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/xml/logback/SelectedLoggerCard.kt index a6075579..e4cc6c3b 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/xml/logback/SelectedLoggerCard.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/xml/logback/SelectedLoggerCard.kt @@ -2,7 +2,6 @@ package io.github.inductiveautomation.kindling.xml.logback import com.formdev.flatlaf.extras.FlatSVGIcon import net.miginfocom.swing.MigLayout -import java.awt.Font import java.awt.event.ItemEvent import javax.swing.JButton import javax.swing.JCheckBox @@ -71,7 +70,7 @@ internal class SelectedLoggerCard( add( JLabel(logger.name).apply { - font = font.deriveFont(Font.BOLD, 14F) + putClientProperty("FlatLaf.styleClass", "h3") }, ) add(closeButton, "right, wrap") diff --git a/src/main/kotlin/io/github/inductiveautomation/kindling/zip/views/gwbk/GwbkStatsView.kt b/src/main/kotlin/io/github/inductiveautomation/kindling/zip/views/gwbk/GwbkStatsView.kt index 1d392238..adb7dc9c 100644 --- a/src/main/kotlin/io/github/inductiveautomation/kindling/zip/views/gwbk/GwbkStatsView.kt +++ b/src/main/kotlin/io/github/inductiveautomation/kindling/zip/views/gwbk/GwbkStatsView.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import net.miginfocom.swing.MigLayout -import java.awt.Font import java.nio.file.Path import java.nio.file.spi.FileSystemProvider import javax.swing.Icon @@ -52,7 +51,7 @@ class GwbkStatsView( private infix fun StatisticCalculator.renderedWith(renderer: StatisticRenderer): JPanel { val headerLabel = JLabel(renderer.title, renderer.icon, SwingConstants.LEFT).apply { - font = font.deriveFont(Font.BOLD, 14F) + putClientProperty("FlatLaf.styleClass", "h3") } val subtitleLabel = JLabel() val throbber = JLabel(FlatSVGIcon("icons/bx-loader-circle.svg")) diff --git a/src/main/resources/icons/bx-subdirectory-left.svg b/src/main/resources/icons/bx-subdirectory-left.svg new file mode 100644 index 00000000..e3e45e35 --- /dev/null +++ b/src/main/resources/icons/bx-subdirectory-left.svg @@ -0,0 +1,3 @@ + + +