@@ -35,6 +35,7 @@ import java.beans.PropertyChangeListener
35
35
import javax.swing.*
36
36
import javax.swing.border.CompoundBorder
37
37
import cc.unitmesh.devti.sketch.ui.patch.readText
38
+ import kotlinx.coroutines.Job
38
39
39
40
/* *
40
41
* Display shire file render prompt and have a sample file as view
@@ -54,6 +55,7 @@ open class McpPreviewEditor(
54
55
55
56
private val mcpServerManager = CustomMcpServerManager .instance(project)
56
57
private val allTools = mutableMapOf<String , List <Tool >>()
58
+ private var loadingJob: Job ? = null
57
59
58
60
data class ChatbotConfig (
59
61
var temperature : Double = 0.7 ,
@@ -70,6 +72,10 @@ open class McpPreviewEditor(
70
72
private val borderColor = JBColor (0xE5E7EB , 0x3C3F41 ) // Equivalent to Tailwind gray-200
71
73
private val primaryBlue = JBColor (0x3B82F6 , 0x589DF6 ) // Equivalent to Tailwind blue-500
72
74
private val textGray = JBColor (0x6B7280 , 0x9DA0A8 ) // Equivalent to Tailwind gray-500
75
+
76
+ // Constants for UI sizing
77
+ private val MAX_TOOL_CARD_HEIGHT = 180
78
+ private val TOOL_CARD_WIDTH = 300
73
79
74
80
init {
75
81
createUI()
@@ -78,14 +84,28 @@ open class McpPreviewEditor(
78
84
79
85
private fun loadTools () {
80
86
val content = runReadAction { virtualFile.readText() }
81
- CoroutineScope (Dispatchers .IO ).launch {
82
- allTools.putAll(mcpServerManager.collectServerInfos(content))
83
- SwingUtilities .invokeLater {
84
- addTools()
87
+ loadingJob?.cancel()
88
+ loadingJob = CoroutineScope (Dispatchers .IO ).launch {
89
+ val serverConfigs = mcpServerManager.getServerConfigs(content)
90
+ serverConfigs?.forEach { (serverName, serverConfig) ->
91
+ try {
92
+ val tools = mcpServerManager.collectServerInfo(serverName, serverConfig)
93
+ if (tools.isNotEmpty()) {
94
+ allTools[serverName] = tools
95
+ // Update UI after each server's tools are loaded
96
+ SwingUtilities .invokeLater {
97
+ updateToolsContainer()
98
+ }
99
+ }
100
+ } catch (e: Exception ) {
101
+ // Handle exception for this server but continue with others
102
+ println (" Error loading tools from server $serverName : ${e.message} " )
103
+ }
85
104
}
86
105
}
87
106
}
88
107
108
+
89
109
private fun createUI () {
90
110
val headerPanel = panel {
91
111
row {
@@ -203,27 +223,24 @@ open class McpPreviewEditor(
203
223
mainPanel.add(bottomPanel, BorderLayout .SOUTH )
204
224
}
205
225
206
- private fun addTools () {
226
+ private fun updateToolsContainer () {
207
227
toolsContainer.removeAll()
208
-
228
+
209
229
if (allTools.isEmpty()) {
210
230
val noToolsLabel = JBLabel (" No tools available. Please check MCP server configuration." ).apply {
211
231
font = JBUI .Fonts .label(14.0f )
212
232
foreground = textGray
213
233
}
214
234
toolsContainer.add(noToolsLabel)
215
- toolsContainer.revalidate()
216
- toolsContainer.repaint()
217
- return
218
- }
219
-
220
- allTools.forEach { (serverName, tools) ->
221
- tools.forEach { tool ->
222
- val toolCard = createToolCard(serverName, tool)
223
- toolsContainer.add(toolCard)
235
+ } else {
236
+ allTools.forEach { (serverName, tools) ->
237
+ tools.forEach { tool ->
238
+ val toolCard = createToolCard(serverName, tool)
239
+ toolsContainer.add(toolCard)
240
+ }
224
241
}
225
242
}
226
-
243
+
227
244
toolsContainer.revalidate()
228
245
toolsContainer.repaint()
229
246
}
@@ -235,6 +252,9 @@ open class McpPreviewEditor(
235
252
BorderFactory .createLineBorder(borderColor),
236
253
JBUI .Borders .empty(16 )
237
254
)
255
+ // Set preferred width and maximum height
256
+ preferredSize = Dimension (TOOL_CARD_WIDTH , MAX_TOOL_CARD_HEIGHT )
257
+ maximumSize = Dimension (Integer .MAX_VALUE , MAX_TOOL_CARD_HEIGHT )
238
258
}
239
259
240
260
// Card header with icon placeholder and title
@@ -269,14 +289,22 @@ open class McpPreviewEditor(
269
289
add(titleWrapper, BorderLayout .CENTER )
270
290
}
271
291
292
+ // Make description scrollable if it's too long
272
293
val descriptionText = tool.description ? : " No description available"
273
- val descLabel = JBLabel (" $ descriptionText (from $serverName )" ).apply {
294
+ val descLabel = JBLabel (" <html><body style='width: ${ TOOL_CARD_WIDTH - 50 } px'> $ descriptionText (from $serverName )</body></html> " ).apply {
274
295
font = JBUI .Fonts .label(14.0f )
275
296
foreground = textGray
276
297
}
298
+
299
+ val descScrollPane = JBScrollPane (descLabel).apply {
300
+ border = BorderFactory .createEmptyBorder()
301
+ verticalScrollBar.unitIncrement = 8
302
+ background = UIUtil .getPanelBackground()
303
+ preferredSize = Dimension (TOOL_CARD_WIDTH - 32 , 70 ) // Control description height
304
+ }
277
305
278
306
headerPanel.add(titleRow, BorderLayout .NORTH )
279
- headerPanel.add(descLabel , BorderLayout .SOUTH )
307
+ headerPanel.add(descScrollPane , BorderLayout .CENTER )
280
308
281
309
// Card footer with button
282
310
val footerPanel = JPanel (BorderLayout ()).apply {
@@ -494,5 +522,7 @@ open class McpPreviewEditor(
494
522
override fun getPreferredFocusedComponent (): JComponent ? = chatInput
495
523
override fun addPropertyChangeListener (listener : PropertyChangeListener ) {}
496
524
override fun removePropertyChangeListener (listener : PropertyChangeListener ) {}
497
- override fun dispose () {}
525
+ override fun dispose () {
526
+ loadingJob?.cancel()
527
+ }
498
528
}
0 commit comments