diff --git a/samples/benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java b/samples/benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java index 3fab3cd1c..78b207c0e 100644 --- a/samples/benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java +++ b/samples/benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java @@ -86,7 +86,7 @@ public final class BenchmarkStarter { private static void render() { CanvasRenderingContext2D context = (CanvasRenderingContext2D) canvas.getContext("2d"); context.setFillStyle("white"); - context.setStrokeStyle("red"); + context.setStrokeStyle("grey"); context.fillRect(0, 0, 600, 600); context.save(); context.translate(0, 600); diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerConfiguration.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerConfiguration.java index 7e505d2eb..c1b2e6b7e 100644 --- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerConfiguration.java +++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerConfiguration.java @@ -22,7 +22,6 @@ import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.RunConfigurationModule; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.facet.FacetManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; 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.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; -import java.util.List; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.teavm.idea.TeaVMFacetType; import org.teavm.idea.devserver.ui.TeaVMDevServerSettingsEditor; -public class TeaVMDevServerConfiguration - extends ModuleBasedConfiguration { +public class TeaVMDevServerConfiguration extends ModuleBasedConfiguration { private String mainClass = ""; private String jdkPath; private int port = 9090; @@ -59,15 +55,7 @@ public class TeaVMDevServerConfiguration @Override public Collection getValidModules() { - Module[] modules = ModuleManager.getInstance(getProject()).getModules(); - List validModules = new ArrayList<>(); - for (Module module : modules) { - FacetManager facetManager = FacetManager.getInstance(module); - if (facetManager.getFacetByType(TeaVMFacetType.TYPE_ID) != null) { - validModules.add(module); - } - } - return validModules; + return Arrays.asList(ModuleManager.getInstance(getProject()).getModules()); } @Override diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java index 3c7ff10b9..2641eec53 100644 --- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java +++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java @@ -26,7 +26,6 @@ import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; -import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.util.JavaParametersUtil; import com.intellij.openapi.module.Module; @@ -44,6 +43,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.teavm.idea.DaemonUtil; import org.teavm.idea.DevServerRunnerListener; +import org.teavm.idea.devserver.ui.TeaVMDevServerConsole; public class TeaVMDevServerRunState implements RunProfileState { private final TeaVMDevServerConfiguration configuration; @@ -84,9 +84,9 @@ public class TeaVMDevServerRunState implements RunProfileState { config.maxHeap = configuration.getMaxHeap(); try { - ConsoleView console = consoleBuilder.getConsole(); + TeaVMDevServerConsole console = new TeaVMDevServerConsole(consoleBuilder.getConsole()); ProcessHandlerImpl processHandler = new ProcessHandlerImpl(config, console); - console.attachToProcess(processHandler); + console.getUnderlyingConsole().attachToProcess(processHandler); processHandler.start(); return new DefaultExecutionResult(console, processHandler); } catch (IOException e) { @@ -106,16 +106,18 @@ public class TeaVMDevServerRunState implements RunProfileState { class ProcessHandlerImpl extends ProcessHandler implements DevServerRunnerListener { private DevServerConfiguration config; - private ConsoleView console; + private TeaVMDevServerConsole console; private DevServerInfo info; - ProcessHandlerImpl(DevServerConfiguration config, ConsoleView console) { + ProcessHandlerImpl(DevServerConfiguration config, TeaVMDevServerConsole console) { this.config = config; this.console = console; } void start() throws IOException { info = DevServerRunner.start(DaemonUtil.detectClassPath().toArray(new String[0]), config, this); + console.setServerManager(info.server); + startNotify(); } @Override @@ -146,16 +148,17 @@ public class TeaVMDevServerRunState implements RunProfileState { @Override public void error(String text) { - console.print(text + System.lineSeparator(), ConsoleViewContentType.ERROR_OUTPUT); + console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.ERROR_OUTPUT); } @Override public void info(String text) { - console.print(text + System.lineSeparator(), ConsoleViewContentType.NORMAL_OUTPUT); + console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.NORMAL_OUTPUT); } @Override public void stopped(int code) { + console.stop(); notifyProcessTerminated(code); } } diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java new file mode 100644 index 000000000..4c03ee508 --- /dev/null +++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java @@ -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(); + } + } + } +} diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerSettingsPanel.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerSettingsPanel.java index 1369cee88..1f1d791dd 100644 --- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerSettingsPanel.java +++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerSettingsPanel.java @@ -139,7 +139,11 @@ public class TeaVMDevServerSettingsPanel extends JPanel { configuration.setPathToFile(pathToFileField.getText()); configuration.setIndicator(indicatorField.isSelected()); configuration.setAutomaticallyReloaded(autoReloadField.isSelected()); - configuration.setMaxHeap(Integer.parseInt(maxHeapField.getText())); - configuration.setPort(Integer.parseInt(portField.getText())); + if (!maxHeapField.getText().isEmpty()) { + configuration.setMaxHeap(Integer.parseInt(maxHeapField.getText())); + } + if (!portField.getText().isEmpty()) { + configuration.setPort(Integer.parseInt(portField.getText())); + } } }