IDEA: improve dev server console

This commit is contained in:
Alexey Andreev 2018-12-17 15:46:29 +03:00
parent d7d4dc1571
commit b1e04da597
5 changed files with 194 additions and 25 deletions

View File

@ -86,7 +86,7 @@ public final class BenchmarkStarter {
private static void render() { private static void render() {
CanvasRenderingContext2D context = (CanvasRenderingContext2D) canvas.getContext("2d"); CanvasRenderingContext2D context = (CanvasRenderingContext2D) canvas.getContext("2d");
context.setFillStyle("white"); context.setFillStyle("white");
context.setStrokeStyle("red"); context.setStrokeStyle("grey");
context.fillRect(0, 0, 600, 600); context.fillRect(0, 0, 600, 600);
context.save(); context.save();
context.translate(0, 600); context.translate(0, 600);

View File

@ -22,7 +22,6 @@ import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunConfigurationModule; import com.intellij.execution.configurations.RunConfigurationModule;
import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.facet.FacetManager;
import com.intellij.openapi.module.Module; import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.options.SettingsEditor;
@ -31,17 +30,14 @@ import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.xmlb.XmlSerializer; import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag; import com.intellij.util.xmlb.annotations.Tag;
import java.util.ArrayList; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import org.jdom.Element; import org.jdom.Element;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.teavm.idea.TeaVMFacetType;
import org.teavm.idea.devserver.ui.TeaVMDevServerSettingsEditor; import org.teavm.idea.devserver.ui.TeaVMDevServerSettingsEditor;
public class TeaVMDevServerConfiguration public class TeaVMDevServerConfiguration extends ModuleBasedConfiguration<RunConfigurationModule> {
extends ModuleBasedConfiguration<RunConfigurationModule> {
private String mainClass = ""; private String mainClass = "";
private String jdkPath; private String jdkPath;
private int port = 9090; private int port = 9090;
@ -59,15 +55,7 @@ public class TeaVMDevServerConfiguration
@Override @Override
public Collection<Module> getValidModules() { public Collection<Module> getValidModules() {
Module[] modules = ModuleManager.getInstance(getProject()).getModules(); return Arrays.asList(ModuleManager.getInstance(getProject()).getModules());
List<Module> validModules = new ArrayList<>();
for (Module module : modules) {
FacetManager facetManager = FacetManager.getInstance(module);
if (facetManager.getFacetByType(TeaVMFacetType.TYPE_ID) != null) {
validModules.add(module);
}
}
return validModules;
} }
@Override @Override

View File

@ -26,7 +26,6 @@ import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.util.JavaParametersUtil; import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.openapi.module.Module; import com.intellij.openapi.module.Module;
@ -44,6 +43,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.teavm.idea.DaemonUtil; import org.teavm.idea.DaemonUtil;
import org.teavm.idea.DevServerRunnerListener; import org.teavm.idea.DevServerRunnerListener;
import org.teavm.idea.devserver.ui.TeaVMDevServerConsole;
public class TeaVMDevServerRunState implements RunProfileState { public class TeaVMDevServerRunState implements RunProfileState {
private final TeaVMDevServerConfiguration configuration; private final TeaVMDevServerConfiguration configuration;
@ -84,9 +84,9 @@ public class TeaVMDevServerRunState implements RunProfileState {
config.maxHeap = configuration.getMaxHeap(); config.maxHeap = configuration.getMaxHeap();
try { try {
ConsoleView console = consoleBuilder.getConsole(); TeaVMDevServerConsole console = new TeaVMDevServerConsole(consoleBuilder.getConsole());
ProcessHandlerImpl processHandler = new ProcessHandlerImpl(config, console); ProcessHandlerImpl processHandler = new ProcessHandlerImpl(config, console);
console.attachToProcess(processHandler); console.getUnderlyingConsole().attachToProcess(processHandler);
processHandler.start(); processHandler.start();
return new DefaultExecutionResult(console, processHandler); return new DefaultExecutionResult(console, processHandler);
} catch (IOException e) { } catch (IOException e) {
@ -106,16 +106,18 @@ public class TeaVMDevServerRunState implements RunProfileState {
class ProcessHandlerImpl extends ProcessHandler implements DevServerRunnerListener { class ProcessHandlerImpl extends ProcessHandler implements DevServerRunnerListener {
private DevServerConfiguration config; private DevServerConfiguration config;
private ConsoleView console; private TeaVMDevServerConsole console;
private DevServerInfo info; private DevServerInfo info;
ProcessHandlerImpl(DevServerConfiguration config, ConsoleView console) { ProcessHandlerImpl(DevServerConfiguration config, TeaVMDevServerConsole console) {
this.config = config; this.config = config;
this.console = console; this.console = console;
} }
void start() throws IOException { void start() throws IOException {
info = DevServerRunner.start(DaemonUtil.detectClassPath().toArray(new String[0]), config, this); info = DevServerRunner.start(DaemonUtil.detectClassPath().toArray(new String[0]), config, this);
console.setServerManager(info.server);
startNotify();
} }
@Override @Override
@ -146,16 +148,17 @@ public class TeaVMDevServerRunState implements RunProfileState {
@Override @Override
public void error(String text) { public void error(String text) {
console.print(text + System.lineSeparator(), ConsoleViewContentType.ERROR_OUTPUT); console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.ERROR_OUTPUT);
} }
@Override @Override
public void info(String text) { public void info(String text) {
console.print(text + System.lineSeparator(), ConsoleViewContentType.NORMAL_OUTPUT); console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.NORMAL_OUTPUT);
} }
@Override @Override
public void stopped(int code) { public void stopped(int code) {
console.stop();
notifyProcessTerminated(code); notifyProcessTerminated(code);
} }
} }

View File

@ -0,0 +1,174 @@
/*
* Copyright 2018 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.idea.devserver.ui;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ExecutionConsole;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import org.teavm.idea.devserver.DevServerBuildResult;
import org.teavm.idea.devserver.DevServerManager;
import org.teavm.idea.devserver.DevServerManagerListener;
public class TeaVMDevServerConsole extends JPanel implements ExecutionConsole {
private ConsoleView underlyingConsole;
private DevServerManager serverManager;
private ServerListenerImpl serverListener;
private JButton rebuildButton = new JButton("Clean and rebuild");
private JProgressBar progressBar = new JProgressBar(0, 1000);
private volatile boolean rebuildPending;
private volatile boolean building;
public TeaVMDevServerConsole(ConsoleView underlyingConsole) {
this.underlyingConsole = underlyingConsole;
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.weightx = 1;
constraints.weighty = 1;
constraints.fill = GridBagConstraints.BOTH;
constraints.insets.bottom = 5;
constraints.gridwidth = GridBagConstraints.REMAINDER;
add(underlyingConsole.getComponent(), constraints);
constraints = new GridBagConstraints();
constraints.insets.right = 5;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_START;
add(rebuildButton, constraints);
constraints.insets.right = 0;
constraints.fill = GridBagConstraints.BOTH;
add(progressBar, constraints);
progressBar.setVisible(false);
progressBar.setStringPainted(true);
rebuildButton.addActionListener(e -> rebuildProject());
}
public ConsoleView getUnderlyingConsole() {
return underlyingConsole;
}
@Override
public JComponent getComponent() {
return this;
}
@Override
public JComponent getPreferredFocusableComponent() {
return underlyingConsole.getPreferredFocusableComponent();
}
@Override
public void dispose() {
if (serverListener != null) {
try {
UnicastRemoteObject.unexportObject(serverListener, true);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
underlyingConsole.dispose();
}
public void setServerManager(DevServerManager serverManager) {
this.serverManager = serverManager;
try {
serverListener = new ServerListenerImpl();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
try {
serverManager.addListener(serverListener);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
private void rebuildProject() {
if (!building) {
invalidateAndBuild();
} else if (!rebuildPending) {
rebuildPending = true;
try {
serverManager.cancelBuild();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
}
private void invalidateAndBuild() {
try {
serverManager.invalidateCache();
serverManager.buildProject();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
public void stop() {
progressBar.setVisible(false);
rebuildButton.setEnabled(false);
}
class ServerListenerImpl extends UnicastRemoteObject implements DevServerManagerListener {
private NumberFormat percentFormat = NumberFormat.getPercentInstance();
ServerListenerImpl() throws RemoteException {
}
@Override
public void compilationStarted() {
building = true;
progressBar.setValue(0);
progressBar.setVisible(true);
}
@Override
public void compilationProgress(double progress) {
building = true;
progressBar.setValue((int) (progress * 10));
progressBar.setString(percentFormat.format(progress / 100));
progressBar.setVisible(true);
}
@Override
public void compilationComplete(DevServerBuildResult result) {
progressBar.setVisible(false);
building = false;
}
@Override
public void compilationCancelled() {
progressBar.setVisible(false);
building = false;
if (rebuildPending) {
invalidateAndBuild();
}
}
}
}

View File

@ -139,7 +139,11 @@ public class TeaVMDevServerSettingsPanel extends JPanel {
configuration.setPathToFile(pathToFileField.getText()); configuration.setPathToFile(pathToFileField.getText());
configuration.setIndicator(indicatorField.isSelected()); configuration.setIndicator(indicatorField.isSelected());
configuration.setAutomaticallyReloaded(autoReloadField.isSelected()); configuration.setAutomaticallyReloaded(autoReloadField.isSelected());
configuration.setMaxHeap(Integer.parseInt(maxHeapField.getText())); if (!maxHeapField.getText().isEmpty()) {
configuration.setPort(Integer.parseInt(portField.getText())); configuration.setMaxHeap(Integer.parseInt(maxHeapField.getText()));
}
if (!portField.getText().isEmpty()) {
configuration.setPort(Integer.parseInt(portField.getText()));
}
} }
} }