ColoredTextContainer — avoid Swing dependency, ability to copy frames (as in JS debugger, now it is supported for all debuggers)

This commit is contained in:
Vladimir Krivosheev
2013-07-26 14:42:08 +02:00
parent 9371c1af7e
commit 77dd374c5b
5 changed files with 54 additions and 51 deletions
@@ -0,0 +1,13 @@
package com.intellij.ui;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public interface ColoredTextContainer {
void append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes);
void setIcon(@Nullable final Icon icon);
void setToolTipText(String text);
}
@@ -47,7 +47,7 @@ import java.util.Locale;
* @author Vladimir Kondratyev
*/
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "FieldAccessedSynchronizedAndUnsynchronized", "UnusedDeclaration"})
public class SimpleColoredComponent extends JComponent implements Accessible {
public class SimpleColoredComponent extends JComponent implements Accessible, ColoredTextContainer {
private static final boolean isOracleRetina = UIUtil.isRetina() && SystemInfo.isOracleJvm;
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.SimpleColoredComponent");
@@ -99,7 +99,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
private boolean myAutoInvalidate = !(this instanceof TreeCellRenderer);
private AccessibleContext myContext = new MyAccessibleContext();
private final AccessibleContext myContext = new MyAccessibleContext();
private boolean myIconOnTheRight = false;
private boolean myTransparentIconBackground;
@@ -132,6 +132,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
* @param fragment text fragment
* @param attributes text attributes
*/
@Override
public final void append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes) {
append(fragment, attributes, myMainTextLastIndex < 0);
}
@@ -220,6 +221,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
* Sets a new component icon
* @param icon icon
*/
@Override
public final void setIcon(final @Nullable Icon icon) {
myIcon = icon;
revalidateAndRepaint();
@@ -524,6 +526,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
}
}
@Override
protected void paintComponent(final Graphics g) {
try {
_doPaint(g);
@@ -822,15 +825,18 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
myInsets = insets;
}
@Override
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
g.setColor(Color.BLACK);
UIUtil.drawDottedRectangle(g, x, y, x + width - 1, y + height - 1);
}
@Override
public Insets getBorderInsets(final Component c) {
return myInsets;
}
@Override
public boolean isBorderOpaque() {
return true;
}
@@ -902,6 +908,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
myUrl = url;
}
@Override
public void run() {
BrowserUtil.launchBrowser(myUrl);
}
@@ -17,16 +17,13 @@
package com.intellij.xdebugger.frame;
import com.intellij.icons.AllIcons;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* Represents a frame of execution stack. The selected frame is shown in 'Variables' panel of 'Debug' tool window.
* Override {@link XValueContainer#computeChildren} to show local variable, parameters, fields available in the frame
@@ -62,15 +59,6 @@ public abstract class XStackFrame extends XValueContainer {
return null;
}
/**
* Customize presentation of the stack frame in frames list
*
* @param component component
*/
public void customizePresentation(SimpleColoredComponent component) {
customizePresentation(new ColoredTextContainerComponent(component));
}
/**
* Customize presentation of the stack frame in frames list
* @param component component
@@ -78,36 +66,12 @@ public abstract class XStackFrame extends XValueContainer {
public void customizePresentation(ColoredTextContainer component) {
XSourcePosition position = getSourcePosition();
if (position != null) {
//FileColorManager.getInstance()
component.append(position.getFile().getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
component.append(":" + (position.getLine()+1), SimpleTextAttributes.REGULAR_ATTRIBUTES);
component.append(":" + (position.getLine() + 1), SimpleTextAttributes.REGULAR_ATTRIBUTES);
component.setIcon(AllIcons.Debugger.StackFrame);
}
else {
component.append(XDebuggerBundle.message("invalid.frame"), SimpleTextAttributes.ERROR_ATTRIBUTES);
}
}
public interface ColoredTextContainer {
void append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes);
void setIcon(@Nullable final Icon icon);
}
static class ColoredTextContainerComponent implements ColoredTextContainer {
private final SimpleColoredComponent component;
ColoredTextContainerComponent(SimpleColoredComponent component) {
this.component = component;
}
@Override
public void append(@NotNull String fragment, @NotNull SimpleTextAttributes attributes) {
component.append(fragment, attributes);
}
@Override
public void setIcon(@Nullable Icon icon) {
component.setIcon(icon);
}
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.FileColorManager;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.TextTransferrable;
@@ -47,13 +48,16 @@ public class XDebuggerFramesList extends DebuggerFramesList {
doInit();
}
@Override
protected ListCellRenderer createListRenderer() {
return new XDebuggerFrameListRenderer(myProject);
}
@Override
protected void onFrameChanged(final Object selectedValue) {
if (mySelectedFrame != selectedValue) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
repaint();
}
@@ -76,6 +80,7 @@ public class XDebuggerFramesList extends DebuggerFramesList {
myColorsManager = FileColorManager.getInstance(project);
}
@Override
protected void customizeCellRenderer(final JList list,
final Object value,
final int index,
@@ -118,7 +123,7 @@ public class XDebuggerFramesList extends DebuggerFramesList {
return defaultTransferHandler;
}
private static class MyColoredTextContainer implements XStackFrame.ColoredTextContainer {
private static class MyColoredTextContainer implements ColoredTextContainer {
private final StringBuilder builder = new StringBuilder();
@Override
public void append(@NotNull String fragment, @NotNull SimpleTextAttributes attributes) {
@@ -128,9 +133,14 @@ public class XDebuggerFramesList extends DebuggerFramesList {
@Override
public void setIcon(@Nullable Icon icon) {
}
@Override
public void setToolTipText(String text) {
}
}
private static class MyListTransferHandler extends TransferHandler {
@Override
protected Transferable createTransferable(JComponent c) {
if (!(c instanceof XDebuggerFramesList)) {
return null;
@@ -171,6 +181,7 @@ public class XDebuggerFramesList extends DebuggerFramesList {
return new TextTransferrable(htmlBuf.toString(), plainBuf.toString());
}
@Override
public int getSourceActions(JComponent c) {
return COPY;
}
@@ -2,7 +2,7 @@ package org.intellij.plugins.xsltDebugger.impl;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PlatformIcons;
import com.intellij.xdebugger.XSourcePosition;
@@ -23,7 +23,7 @@ import java.util.List;
public class XsltStackFrame extends XStackFrame {
private final Debugger.Frame myFrame;
private final XsltDebuggerSession myDebuggerSession;
private XSourcePosition myPosition;
private final XSourcePosition myPosition;
public XsltStackFrame(Debugger.Frame frame, XsltDebuggerSession debuggerSession) {
myFrame = frame;
@@ -47,17 +47,19 @@ public class XsltStackFrame extends XStackFrame {
}
@Override
public void customizePresentation(SimpleColoredComponent component) {
public void customizePresentation(ColoredTextContainer component) {
if (myDebuggerSession.getCurrentState() == Debugger.State.SUSPENDED) {
try {
_customizePresentation(component);
} catch (VMPausedException ignore) {
} catch (DebuggerStoppedException ignore) {
}
catch (VMPausedException ignore) {
}
catch (DebuggerStoppedException ignore) {
}
}
}
private void _customizePresentation(SimpleColoredComponent component) {
private void _customizePresentation(ColoredTextContainer component) {
final Debugger.Frame frame = myFrame;
if (frame instanceof Debugger.StyleFrame) {
component.append(((Debugger.StyleFrame)frame).getInstruction(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
@@ -78,7 +80,7 @@ public class XsltStackFrame extends XStackFrame {
} else {
component.append(frame.getURI() + ":" + frame.getLineNumber(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
} catch (Exception e) {
} catch (Exception ignored) {
component.append(frame.getURI() + ":" + frame.getLineNumber(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
@@ -96,7 +98,7 @@ public class XsltStackFrame extends XStackFrame {
} else {
super.computeChildren(node);
}
} catch (VMPausedException e) {
} catch (VMPausedException ignored) {
node.setErrorMessage(VMPausedException.MESSAGE);
}
}
@@ -200,7 +202,7 @@ public class XsltStackFrame extends XStackFrame {
try {
final Value eval = myFrame.eval(expression);
callback.evaluated(new MyValue(new ExpressionResult(eval)));
} catch (VMPausedException e) {
} catch (VMPausedException ignored) {
callback.errorOccurred(VMPausedException.MESSAGE);
} catch (Debugger.EvaluationException e) {
callback.errorOccurred(e.getMessage() != null ? e.getMessage() : e.toString());
@@ -214,27 +216,33 @@ public class XsltStackFrame extends XStackFrame {
myValue = value;
}
@Override
@SuppressWarnings({ "ConstantConditions" })
public String getURI() {
return null;
}
@Override
public int getLineNumber() {
return -1;
}
@Override
public boolean isGlobal() {
return false;
}
@Override
public Kind getKind() {
return Kind.EXPRESSION;
}
@Override
public String getName() {
return "result";
}
@Override
public Value getValue() {
return myValue;
}