IDEA-74403 android layout preview: always show rendering process for long rendering sessions

This commit is contained in:
Eugene Kudelevsky
2011-09-27 20:16:14 +04:00
parent 101c5d56a8
commit a94373e7a9
3 changed files with 82 additions and 27 deletions
@@ -1,9 +1,12 @@
package org.jetbrains.android.uipreview;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.HyperlinkLabel;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.AsyncProcessIcon;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -15,7 +18,7 @@
/**
* @author Eugene.Kudelevsky
*/
public class AndroidLayoutPreviewPanel extends JPanel {
public class AndroidLayoutPreviewPanel extends JPanel implements Disposable {
private static final double EPS = 0.0000001;
private static final double MAX_ZOOM_FACTOR = 2.0;
private static final double ZOOM_STEP = 1.25;
@@ -23,7 +26,6 @@ public class AndroidLayoutPreviewPanel extends JPanel {
private RenderingErrorMessage myErrorMessage;
private String myWarnMessage;
private BufferedImage myImage;
private JBLabel myProgressLabel;
private final HyperlinkLabel myErrorLabel = new HyperlinkLabel("", Color.BLUE, getBackground(), Color.BLUE);
@@ -46,6 +48,8 @@ public class AndroidLayoutPreviewPanel extends JPanel {
}
};
private AsyncProcessIcon myProgressIcon;
public AndroidLayoutPreviewPanel() {
super(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true, true));
setBackground(Color.WHITE);
@@ -62,12 +66,18 @@ public class AndroidLayoutPreviewPanel extends JPanel {
});
myErrorLabel.setOpaque(false);
myProgressLabel = new JBLabel("Rendering...");
myProgressLabel.setIcon(Messages.getInformationIcon());
myProgressLabel.setVisible(false);
final JPanel progressPanel = new JPanel();
progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.X_AXIS));
myProgressIcon = new AsyncProcessIcon("Android layout rendering");
Disposer.register(this, myProgressIcon);
progressPanel.add(Box.createHorizontalGlue());
progressPanel.add(myProgressIcon);
progressPanel.add(new JBLabel(" "));
progressPanel.setOpaque(false);
myProgressIcon.setVisible(false);
add(progressPanel);
add(myErrorLabel);
add(myProgressLabel);
add(new MyImagePanelWrapper());
}
@@ -77,14 +87,13 @@ public class AndroidLayoutPreviewPanel extends JPanel {
}
public void showProgress() {
myProgressLabel.setVisible(true);
myErrorLabel.setVisible(false);
myImagePanel.setVisible(false);
myProgressIcon.setVisible(true);
myProgressIcon.resume();
}
@Nullable
public BufferedImage getImage() {
return myImage;
public void hideProgress() {
myProgressIcon.suspend();
myProgressIcon.setVisible(false);
}
private void doRevalidate() {
@@ -102,7 +111,6 @@ public class AndroidLayoutPreviewPanel extends JPanel {
}
public void update() {
myProgressLabel.setVisible(false);
myImagePanel.setVisible(true);
if (myErrorMessage != null) {
myErrorLabel.setHyperlinkText(myErrorMessage.myBeforeLinkText,
@@ -218,6 +226,10 @@ public class AndroidLayoutPreviewPanel extends JPanel {
return myZoomToFit;
}
@Override
public void dispose() {
}
private class MyImagePanelWrapper extends JLayeredPane {
public MyImagePanelWrapper() {
add(myImagePanel);
@@ -5,10 +5,10 @@ import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.resources.configuration.LanguageQualifier;
import com.android.ide.common.resources.configuration.RegionQualifier;
import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
import com.android.resources.UiMode;
import com.android.resources.NightMode;
import com.android.resources.ResourceType;
import com.android.resources.ScreenSize;
import com.android.resources.UiMode;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.intellij.ide.ui.ListCellRendererWrapper;
@@ -23,6 +23,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -97,6 +98,8 @@ class AndroidLayoutPreviewToolWindowForm implements Disposable {
private final AndroidLayoutPreviewToolWindowSettings mySettings;
public AndroidLayoutPreviewToolWindowForm(final Project project, AndroidLayoutPreviewToolWindowManager toolWindowManager) {
Disposer.register(this, myPreviewPanel);
myToolWindowManager = toolWindowManager;
mySettings = AndroidLayoutPreviewToolWindowSettings.getInstance(project);
@@ -5,7 +5,6 @@ import com.android.sdklib.IAndroidTarget;
import com.intellij.ProjectTopics;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -13,6 +12,8 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootEvent;
@@ -35,6 +36,7 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.containers.HashMap;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.android.dom.layout.LayoutDomFileDescription;
@@ -53,6 +55,8 @@ import org.jetbrains.annotations.Nullable;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -242,15 +246,12 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
myRenderingQueue.queue(new Update("render") {
@Override
public void run() {
if (showProgress || myToolWindowForm.getPreviewPanel().getImage() == null) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
myToolWindowForm.getPreviewPanel().showProgress();
}
}, ModalityState.defaultModalityState());
}
doRender(facet, layoutXmlText);
ProgressManager.getInstance().runProcess(new Runnable() {
@Override
public void run() {
doRender(facet, layoutXmlText);
}
}, new MyProgressIndicator());
}
@Override
@@ -355,7 +356,7 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
}
});
}
private void showStackStace(@NotNull Throwable t) {
final String stackTrace = getStackTrace(t);
final DialogWrapper wrapper = new DialogWrapper(myProject, false) {
@@ -372,11 +373,11 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
panel.add(ScrollPaneFactory.createScrollPane(textArea));
return panel;
}
};
};
wrapper.setTitle("Stack trace");
wrapper.show();
}
@NotNull
private static String getStackTrace(@NotNull Throwable t) {
final StringWriter stringWriter = new StringWriter();
@@ -517,4 +518,43 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
processFileEditorChange(layoutXmlEditor);
}
}
private class MyProgressIndicator extends ProgressIndicatorBase {
private final Object myLock = new Object();
@Override
public void start() {
super.start();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
final Timer timer = UIUtil.createNamedTimer("Android rendering progress timer", 1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
synchronized (myLock) {
if (isRunning()) {
myToolWindowForm.getPreviewPanel().showProgress();
}
}
}
});
timer.setRepeats(false);
timer.start();
}
});
}
@Override
public void stop() {
synchronized (myLock) {
super.stop();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
myToolWindowForm.getPreviewPanel().hideProgress();
}
});
}
}
}
}