Skip to content

Commit 1793153

Browse files
Harmonized filtering UI (#62)
* Make generic FilterPanel and FilterSidebar classes for use with other tools * Additional Refactor of FilterPanel and implement consistent filtering techniques in Thread View * Ktlint formatting pass * Fix NPE when updateData() is called with no sorting active * Introduce ListFilterPanel to avoid repetitive class impls. * Fix typo * Updates to harmonized-filtering-ui (#63) - Eliminate some duplication - Fix a perf issue with sorting --------- Co-authored-by: Paul Griffith <pgriffith@ia.io> Co-authored-by: Paul Griffith <39345262+paul-griffith@users.noreply.github.com>
1 parent 01f5ab5 commit 1793153

File tree

23 files changed

+497
-516
lines changed

23 files changed

+497
-516
lines changed

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ flatlaf-jide = { group = "com.formdev", name = "flatlaf-jide-oss", version.ref =
3535
flatlaf-swingx = { group = "com.formdev", name = "flatlaf-swingx", version.ref = "flatlaf" }
3636
flatlaf-themes = { group = "com.formdev", name = "flatlaf-intellij-themes", version.ref = "flatlaf" }
3737
flatlaf-fonts-roboto = { group = "com.formdev", name = "flatlaf-fonts-roboto", version = "2.137" }
38+
flatlaf-fonts-roboto-mono = { group = "com.formdev", name = "flatlaf-fonts-roboto-mono", version = "3.000" }
3839
jide-common = { group = "com.formdev", name = "jide-oss", version = "3.7.12" }
3940
swingx = { group = "org.swinglabs.swingx", name = "swingx-all", version = "1.6.5-1" }
4041
rsyntaxtextarea = { group = "com.fifesoft", name = "rsyntaxtextarea", version = "3.3.4" }
@@ -64,6 +65,7 @@ flatlaf = [
6465
"flatlaf-swingx",
6566
"flatlaf-themes",
6667
"flatlaf-fonts-roboto",
68+
"flatlaf-fonts-roboto-mono",
6769
]
6870
kotest = [
6971
"kotest-junit",

src/main/kotlin/io/github/inductiveautomation/kindling/MainPanel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.formdev.flatlaf.extras.FlatSVGIcon
66
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector
77
import com.formdev.flatlaf.extras.components.FlatTextArea
88
import com.formdev.flatlaf.fonts.roboto.FlatRobotoFont
9+
import com.formdev.flatlaf.fonts.roboto_mono.FlatRobotoMonoFont
910
import com.formdev.flatlaf.util.SystemInfo
1011
import com.jidesoft.swing.StyleRange.STYLE_UNDERLINED
1112
import io.github.inductiveautomation.kindling.core.ClipboardTool
@@ -358,9 +359,11 @@ class MainPanel : JPanel(MigLayout("ins 6, fill")) {
358359

359360
private fun lafSetup() {
360361
FlatRobotoFont.install()
362+
FlatRobotoMonoFont.install()
361363
FlatLaf.setPreferredFontFamily(FlatRobotoFont.FAMILY)
362364
FlatLaf.setPreferredLightFontFamily(FlatRobotoFont.FAMILY_LIGHT)
363365
FlatLaf.setPreferredSemiboldFontFamily(FlatRobotoFont.FAMILY_SEMIBOLD)
366+
FlatLaf.setPreferredMonospacedFontFamily(FlatRobotoMonoFont.FAMILY)
364367
applyTheme(false)
365368

366369
UIManager.getDefaults().apply {

src/main/kotlin/io/github/inductiveautomation/kindling/cache/CacheView.kt

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import io.github.inductiveautomation.kindling.utils.Action
2020
import io.github.inductiveautomation.kindling.utils.EDT_SCOPE
2121
import io.github.inductiveautomation.kindling.utils.FileFilter
2222
import io.github.inductiveautomation.kindling.utils.FlatScrollPane
23+
import io.github.inductiveautomation.kindling.utils.HorizontalSplitPane
2324
import io.github.inductiveautomation.kindling.utils.ReifiedJXTable
25+
import io.github.inductiveautomation.kindling.utils.VerticalSplitPane
2426
import io.github.inductiveautomation.kindling.utils.getLogger
2527
import io.github.inductiveautomation.kindling.utils.getValue
2628
import io.github.inductiveautomation.kindling.utils.jFrame
@@ -41,8 +43,6 @@ import java.sql.PreparedStatement
4143
import java.util.zip.GZIPInputStream
4244
import javax.swing.Icon
4345
import javax.swing.JLabel
44-
import javax.swing.JSplitPane
45-
import javax.swing.SwingConstants
4646
import javax.swing.table.DefaultTableModel
4747
import kotlin.io.path.CopyActionResult
4848
import kotlin.io.path.ExperimentalPathApi
@@ -234,19 +234,14 @@ class CacheView(private val path: Path) : ToolPanel() {
234234
)
235235
}
236236

237-
private val mainSplitPane = JSplitPane(
238-
SwingConstants.HORIZONTAL,
239-
JSplitPane(
240-
SwingConstants.VERTICAL,
237+
private val mainSplitPane = HorizontalSplitPane(
238+
VerticalSplitPane(
241239
FlatScrollPane(table),
242240
details,
243-
).apply {
244-
resizeWeight = 0.5
245-
},
241+
),
246242
FlatScrollPane(schemaList),
247-
).apply {
248-
resizeWeight = 0.75
249-
}
243+
resizeWeight = 0.75,
244+
)
250245

251246
private fun Serializable.toDetail(): Detail = when (this) {
252247
is BasicHistoricalRecord -> toDetail()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.github.inductiveautomation.kindling.core
2+
3+
import io.github.inductiveautomation.kindling.utils.Column
4+
import io.github.inductiveautomation.kindling.utils.add
5+
import java.util.EventListener
6+
import javax.swing.JComponent
7+
import javax.swing.JPopupMenu
8+
import javax.swing.event.EventListenerList
9+
10+
fun interface Filter<T> {
11+
/**
12+
* Return true if this filter should display this item.
13+
*/
14+
fun filter(item: T): Boolean
15+
}
16+
17+
fun interface FilterChangeListener : EventListener {
18+
fun filterChanged()
19+
}
20+
21+
abstract class FilterPanel<T> : Filter<T> {
22+
abstract val tabName: String
23+
abstract fun isFilterApplied(): Boolean
24+
abstract val component: JComponent
25+
26+
protected val listeners = EventListenerList()
27+
28+
fun addFilterChangeListener(listener: FilterChangeListener) {
29+
listeners.add(listener)
30+
}
31+
32+
abstract fun reset()
33+
34+
abstract fun customizePopupMenu(
35+
menu: JPopupMenu,
36+
column: Column<out T, *>,
37+
event: T,
38+
)
39+
}

src/main/kotlin/io/github/inductiveautomation/kindling/idb/generic/GenericView.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package io.github.inductiveautomation.kindling.idb.generic
33
import io.github.inductiveautomation.kindling.core.ToolPanel
44
import io.github.inductiveautomation.kindling.utils.Action
55
import io.github.inductiveautomation.kindling.utils.FlatScrollPane
6+
import io.github.inductiveautomation.kindling.utils.HorizontalSplitPane
7+
import io.github.inductiveautomation.kindling.utils.VerticalSplitPane
68
import io.github.inductiveautomation.kindling.utils.attachPopupMenu
79
import io.github.inductiveautomation.kindling.utils.javaType
810
import io.github.inductiveautomation.kindling.utils.menuShortcutKeyMaskEx
@@ -20,7 +22,6 @@ import javax.swing.JButton
2022
import javax.swing.JMenuItem
2123
import javax.swing.JPanel
2224
import javax.swing.JPopupMenu
23-
import javax.swing.JSplitPane
2425
import javax.swing.JTextArea
2526
import javax.swing.KeyStroke
2627
import javax.swing.tree.DefaultTreeModel
@@ -151,21 +152,17 @@ class GenericView(connection: Connection) : ToolPanel("ins 0, fill, hidemode 3")
151152
}
152153

153154
add(
154-
JSplitPane(
155-
JSplitPane.HORIZONTAL_SPLIT,
155+
HorizontalSplitPane(
156156
FlatScrollPane(tree).apply {
157157
preferredSize = Dimension(200, 10)
158158
},
159-
JSplitPane(
160-
JSplitPane.VERTICAL_SPLIT,
159+
VerticalSplitPane(
161160
FlatScrollPane(queryPanel),
162161
results,
163-
).apply {
164-
resizeWeight = 0.2
165-
},
166-
).apply {
167-
resizeWeight = 0.1
168-
},
162+
resizeWeight = 0.2,
163+
),
164+
resizeWeight = 0.1,
165+
),
169166
"push, grow",
170167
)
171168
}

src/main/kotlin/io/github/inductiveautomation/kindling/log/LevelPanel.kt

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,17 @@ package io.github.inductiveautomation.kindling.log
22

33
import io.github.inductiveautomation.kindling.utils.Action
44
import io.github.inductiveautomation.kindling.utils.Column
5-
import io.github.inductiveautomation.kindling.utils.FilterList
5+
import io.github.inductiveautomation.kindling.utils.FilterListPanel
66
import io.github.inductiveautomation.kindling.utils.FilterModel
7-
import io.github.inductiveautomation.kindling.utils.FlatScrollPane
8-
import io.github.inductiveautomation.kindling.utils.add
9-
import io.github.inductiveautomation.kindling.utils.getAll
10-
import javax.swing.JComponent
117
import javax.swing.JPopupMenu
12-
import javax.swing.event.EventListenerList
13-
14-
internal class LevelPanel(rawData: List<LogEvent>) : LogFilterPanel {
15-
private val filterList: FilterList = FilterList()
16-
override val component: JComponent = FlatScrollPane(filterList)
17-
18-
private val listenerList = EventListenerList()
198

9+
internal class LevelPanel(rawData: List<LogEvent>) : FilterListPanel<LogEvent>("Level") {
2010
init {
2111
filterList.setModel(FilterModel(rawData.groupingBy { it.level?.name }.eachCount()))
2212
filterList.selectAll()
23-
24-
filterList.checkBoxListSelectionModel.addListSelectionListener { e ->
25-
if (!e.valueIsAdjusting) {
26-
listenerList.getAll<FilterChangeListener>().forEach(FilterChangeListener::filterChanged)
27-
}
28-
}
2913
}
3014

31-
override val tabName: String = "Level"
32-
override fun isFilterApplied() = filterList.checkBoxListSelectedValues.size != filterList.model.size - 1
33-
override fun filter(event: LogEvent): Boolean = event.level?.name in filterList.checkBoxListSelectedValues
34-
override fun addFilterChangeListener(listener: FilterChangeListener) {
35-
listenerList.add(listener)
36-
}
15+
override fun filter(item: LogEvent): Boolean = item.level?.name in filterList.checkBoxListSelectedValues
3716

3817
override fun customizePopupMenu(menu: JPopupMenu, column: Column<out LogEvent, *>, event: LogEvent) {
3918
val level = event.level
@@ -52,6 +31,4 @@ internal class LevelPanel(rawData: List<LogEvent>) : LogFilterPanel {
5231
)
5332
}
5433
}
55-
56-
override fun reset() = filterList.selectAll()
5734
}

0 commit comments

Comments
 (0)