diff --git a/java/debugger/backend/src/com/intellij/java/debugger/impl/backend/BackendJavaDebuggerLuxActionsApi.kt b/java/debugger/backend/src/com/intellij/java/debugger/impl/backend/BackendJavaDebuggerLuxActionsApi.kt
index d298b51345be..a8212fb80188 100644
--- a/java/debugger/backend/src/com/intellij/java/debugger/impl/backend/BackendJavaDebuggerLuxActionsApi.kt
+++ b/java/debugger/backend/src/com/intellij/java/debugger/impl/backend/BackendJavaDebuggerLuxActionsApi.kt
@@ -1,7 +1,9 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.debugger.impl.backend
+import com.intellij.debugger.actions.CreateRendererActionUtils
import com.intellij.debugger.engine.JavaDebugProcess
+import com.intellij.debugger.engine.JavaValue
import com.intellij.debugger.memory.action.CalculateRetainedSizeActionUtil
import com.intellij.debugger.memory.action.DebuggerTreeAction
import com.intellij.debugger.memory.filtering.ClassInstancesProvider
@@ -35,4 +37,12 @@ internal class BackendJavaDebuggerLuxActionsApi : JavaDebuggerLuxActionsApi {
CalculateRetainedSizeActionUtil.showDialog(xValue, nodeName, process)
}
}
+
+ override suspend fun showCreateRendererDialog(xValueId: XValueId) {
+ val xValueModel = BackendXValueModel.findById(xValueId) ?: return
+ val javaValue = xValueModel.xValue as? JavaValue ?: return
+ withContext(Dispatchers.EDT) {
+ CreateRendererActionUtils.showCreateRendererDialog(javaValue)
+ }
+ }
}
\ No newline at end of file
diff --git a/java/debugger/impl/resources/META-INF/java-debugger.xml b/java/debugger/impl/resources/META-INF/java-debugger.xml
index 40490ede4527..170c8ff8d0c1 100644
--- a/java/debugger/impl/resources/META-INF/java-debugger.xml
+++ b/java/debugger/impl/resources/META-INF/java-debugger.xml
@@ -285,11 +285,6 @@
-
-
-
-
-
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererActionUtils.java
similarity index 60%
rename from java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java
rename to java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererActionUtils.java
index 046a675b3ca0..600a26438226 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererActionUtils.java
@@ -2,61 +2,30 @@
package com.intellij.debugger.actions;
import com.intellij.debugger.JavaDebuggerBundle;
-import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.SuspendContextImpl;
-import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
-import com.intellij.debugger.impl.DebuggerContextImpl;
+import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.settings.UserRenderersConfigurable;
import com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer;
-import com.intellij.openapi.actionSystem.ActionUpdateThread;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.options.ConfigurableBase;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.sun.jdi.Type;
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
-
-public class CreateRendererAction extends AnAction {
- @Override
- public void update(@NotNull AnActionEvent e) {
- final List values = ViewAsGroup.getSelectedValues(e);
- if (values.size() != 1) {
- e.getPresentation().setEnabledAndVisible(false);
- }
- }
-
- @Override
- public @NotNull ActionUpdateThread getActionUpdateThread() {
- return ActionUpdateThread.BGT;
- }
-
- @Override
- public void actionPerformed(final @NotNull AnActionEvent event) {
- final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(event.getDataContext());
- final List values = ViewAsGroup.getSelectedValues(event);
- if (values.size() != 1) {
- return;
- }
-
- final JavaValue javaValue = values.get(0);
-
- final DebugProcessImpl process = debuggerContext.getDebugProcess();
- if (process == null) {
- return;
- }
-
- final Project project = event.getProject();
-
- javaValue.getEvaluationContext().getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
+@ApiStatus.Internal
+public final class CreateRendererActionUtils {
+ public static void showCreateRendererDialog(final JavaValue javaValue) {
+ EvaluationContextImpl evaluationContext = javaValue.getEvaluationContext();
+ Project project = evaluationContext.getProject();
+ evaluationContext.getManagerThread().schedule(new SuspendContextCommandImpl(evaluationContext.getSuspendContext()) {
@Override
- public void threadAction(@NotNull SuspendContextImpl suspendContext) {
+ public void contextAction(@NotNull SuspendContextImpl suspendContext) {
Type type = javaValue.getDescriptor().getType();
final String name = type != null ? type.name() : null;
DebuggerUIUtil.invokeLater(() -> {
diff --git a/java/debugger/shared/resources/intellij.java.debugger.impl.shared.xml b/java/debugger/shared/resources/intellij.java.debugger.impl.shared.xml
index 1bfd2eac9a5f..d089c734f44f 100644
--- a/java/debugger/shared/resources/intellij.java.debugger.impl.shared.xml
+++ b/java/debugger/shared/resources/intellij.java.debugger.impl.shared.xml
@@ -59,6 +59,10 @@
+
+
+
+
diff --git a/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/CreateRendererAction.kt b/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/CreateRendererAction.kt
new file mode 100644
index 000000000000..97b6723ef72f
--- /dev/null
+++ b/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/CreateRendererAction.kt
@@ -0,0 +1,32 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.java.debugger.impl.shared.actions
+
+import com.intellij.java.debugger.impl.shared.rpc.JavaDebuggerLuxActionsApi
+import com.intellij.openapi.actionSystem.ActionUpdateThread
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.actionSystem.remoting.ActionRemoteBehaviorSpecification
+import com.intellij.xdebugger.impl.frame.XDebugManagerProxy
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
+import kotlinx.coroutines.launch
+
+private class CreateRendererAction : AnAction(), ActionRemoteBehaviorSpecification.FrontendOtherwiseBackend {
+ override fun update(e: AnActionEvent) {
+ val values = getSelectedJavaValuesWithDescriptors(e)
+ e.presentation.setEnabledAndVisible(values.size == 1)
+ }
+
+ override fun actionPerformed(e: AnActionEvent) {
+ val session = DebuggerUIUtil.getSessionProxy(e) ?: return
+ val (_, xValue, _) = getSelectedJavaValuesWithDescriptors(e).singleOrNull() ?: return
+ session.coroutineScope.launch {
+ XDebugManagerProxy.getInstance().withId(xValue, session) { xValueId ->
+ JavaDebuggerLuxActionsApi.getInstance().showCreateRendererDialog(xValueId)
+ }
+ }
+ }
+
+ override fun getActionUpdateThread(): ActionUpdateThread {
+ return ActionUpdateThread.BGT
+ }
+}
diff --git a/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/ViewAsGroup.kt b/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/ViewAsGroup.kt
index 5582f8d8adab..2bdf43f4cf0a 100644
--- a/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/ViewAsGroup.kt
+++ b/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/actions/ViewAsGroup.kt
@@ -98,7 +98,7 @@ private fun getApplicableRenderers(project: Project, values: List> {
+internal fun getSelectedJavaValuesWithDescriptors(event: AnActionEvent): List> {
val selectedNodes = XDebuggerTree.getSelectedNodes(event.dataContext)
return selectedNodes.map { it to it.valueContainer }
.map { it to it.second.xValueDescriptorAsync?.getNow(null) }
diff --git a/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/rpc/JavaDebuggerLuxActionsApi.kt b/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/rpc/JavaDebuggerLuxActionsApi.kt
index c3a912a15502..877a64802862 100644
--- a/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/rpc/JavaDebuggerLuxActionsApi.kt
+++ b/java/debugger/shared/src/com/intellij/java/debugger/impl/shared/rpc/JavaDebuggerLuxActionsApi.kt
@@ -11,6 +11,7 @@ import fleet.rpc.remoteApiDescriptor
interface JavaDebuggerLuxActionsApi : RemoteApi {
suspend fun showInstancesDialog(xValueId: XValueId)
suspend fun showCalculateRetainedSizeDialog(xValueId: XValueId, nodeName: String)
+ suspend fun showCreateRendererDialog(xValueId: XValueId)
companion object {
@JvmStatic