11package com.github.pemistahl.lingua.app.multilanguage
22
33import com.github.pemistahl.lingua.api.Language
4+ import com.github.pemistahl.lingua.api.LanguageDetector
45import java.awt.Dimension
56import java.awt.GridBagConstraints
67import java.awt.GridBagLayout
8+ import java.awt.Insets
79import java.awt.Toolkit
810import javax.swing.BorderFactory
911import javax.swing.JFrame
1012import javax.swing.JLabel
13+ import javax.swing.JPanel
14+ import javax.swing.JProgressBar
1115import javax.swing.JScrollPane
1216import javax.swing.SwingUtilities
1317import javax.swing.ToolTipManager
@@ -36,8 +40,9 @@ internal fun openMultiLanguageDetectionGui() {
3640 c.gridheight = 2 // To cover both text area and summary label below it
3741 frame.add(LanguageSelectionPanel (model, languages, colorMap), c)
3842 }
43+
44+ val textArea = MultiLanguageTextArea (model, colorMap)
3945 run {
40- val textArea = MultiLanguageTextArea (model, colorMap)
4146 textArea.border = BorderFactory .createEmptyBorder(3 , 3 , 3 , 3 )
4247
4348 val scrollPane = JScrollPane (textArea)
@@ -51,44 +56,90 @@ internal fun openMultiLanguageDetectionGui() {
5156 c.weighty = 1.0
5257 frame.add(scrollPane, c)
5358 }
59+
5460 run {
5561 val noSectionsText = " Sections: 0"
5662 val summaryLabel = JLabel (noSectionsText)
57- summaryLabel.border = BorderFactory .createEmptyBorder(3 , 3 , 3 , 3 )
58- model.addListener {
59- val sections = it.getSections()
60- if (sections.isEmpty()) {
61- summaryLabel.text = noSectionsText
62- } else {
63- val detectedLanguages =
64- sections.map { s -> s.language }
65- .groupingBy { l -> l }
66- .eachCount()
67- .entries
68- .sortedWith { a, b ->
69- // Sort highest count first
70- val diff = b.value - a.value
71- if (diff != 0 ) return @sortedWith diff
72-
73- return @sortedWith a.key.compareTo(b.key)
74- }
75- .map { e -> " ${e.key} (${e.value} )" }
76- summaryLabel.text = " Sections: ${sections.size} ; Languages: ${detectedLanguages.joinToString(" , " )} "
77- }
63+
64+ val progressBar = JProgressBar ()
65+ // Don't shrink progressbar when label becomes too large
66+ progressBar.minimumSize = progressBar.preferredSize
67+
68+ model.addListener(
69+ object : DetectionProgressListener {
70+ override fun detectionStarted () {
71+ progressBar.isIndeterminate = true
72+ progressBar.toolTipText = " Language detection in progress"
73+
74+ // Don't clear or change label text to avoid flashing text when user is currently typing
75+ }
76+
77+ override fun detectionFinished (sections : List <LanguageDetector .LanguageSection >) {
78+ progressBar.isIndeterminate = false
79+ progressBar.toolTipText = " Language detection finished"
80+
81+ if (sections.isEmpty()) {
82+ summaryLabel.text = noSectionsText
83+ } else {
84+ val detectedLanguages =
85+ sections.map { s -> s.language }
86+ .groupingBy { l -> l }
87+ .eachCount()
88+ .entries
89+ .sortedWith { a, b ->
90+ // Sort highest count first
91+ val diff = b.value - a.value
92+ if (diff != 0 ) return @sortedWith diff
93+
94+ return @sortedWith a.key.compareTo(b.key)
95+ }
96+ .map { e -> " ${e.key} (${e.value} )" }
97+
98+ summaryLabel.text =
99+ " Sections: ${sections.size} ; Languages: ${detectedLanguages.joinToString(" , " )} "
100+ }
101+ }
102+ },
103+ )
104+
105+ val footerPanel = JPanel (GridBagLayout ())
106+ run {
107+ val c = GridBagConstraints ()
108+ c.gridx = 0
109+ c.gridy = 0
110+ c.fill = GridBagConstraints .HORIZONTAL
111+ c.weightx = 1.0
112+ // Add spacing between label and progressbar
113+ c.insets = Insets (0 , 0 , 0 , 3 )
114+ footerPanel.add(summaryLabel, c)
115+ }
116+ run {
117+ val c = GridBagConstraints ()
118+ c.gridx = 1
119+ c.gridy = 0
120+ c.fill = GridBagConstraints .HORIZONTAL
121+ footerPanel.add(progressBar, c)
78122 }
79123
80- val c = GridBagConstraints ()
81- c.gridx = 1
82- c.gridy = GridBagConstraints .RELATIVE
83- c.fill = GridBagConstraints .HORIZONTAL
84- frame.add(summaryLabel, c)
124+ run {
125+ val c = GridBagConstraints ()
126+ c.gridx = 1
127+ c.gridy = GridBagConstraints .RELATIVE
128+ c.fill = GridBagConstraints .HORIZONTAL
129+ c.insets = Insets (3 , 3 , 3 , 3 )
130+ frame.add(footerPanel, c)
131+ }
85132 }
86133
87134 val screenSize: Dimension = Toolkit .getDefaultToolkit().screenSize
88- frame.preferredSize = Dimension (screenSize.width / 3 , screenSize.height / 3 )
135+ frame.preferredSize = Dimension (screenSize.width / 2 , screenSize.height / 2 )
89136 frame.pack()
90137 // Center on screen
91138 frame.setLocationRelativeTo(null )
139+
140+ // Update initial state
141+ textArea.detectLanguages()
142+
92143 frame.isVisible = true
93144 }
94145}
0 commit comments