diff --git a/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.form b/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.form
index decd17c17f37..bf72b5d62644 100644
--- a/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.form
+++ b/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.form
@@ -209,7 +209,7 @@
-
+
diff --git a/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.java b/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.java
index 5e23915c7be3..741dec6024a2 100644
--- a/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.java
+++ b/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurable.java
@@ -18,7 +18,8 @@ package com.intellij.execution.applet;
import com.intellij.application.options.ModulesComboBox;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.impl.CheckableRunConfigurationEditor;
-import com.intellij.execution.ui.AlternativeJREPanel;
+import com.intellij.execution.ui.DefaultJreSelector;
+import com.intellij.execution.ui.JrePathEditor;
import com.intellij.execution.ui.ClassBrowser;
import com.intellij.execution.ui.ConfigurationModuleSelector;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
@@ -64,7 +65,7 @@ public class AppletConfigurable extends SettingsEditor impl
private JBLabel myClassNameLabel;
private JBLabel myWidthLabel;
private JLabel myHeightLabel;
- private AlternativeJREPanel myAlternativeJREPanel;
+ private JrePathEditor myJrePathEditor;
private final ButtonGroup myAppletRadioButtonGroup;
private JComponent anchor;
@@ -116,6 +117,7 @@ public class AppletConfigurable extends SettingsEditor impl
myModuleSelector = new ConfigurationModuleSelector(project, getModuleComponent());
+ myJrePathEditor.setDefaultJreSelector(DefaultJreSelector.fromModuleDependencies(getModuleComponent(), true));
myTablePlace.setLayout(new BorderLayout());
myParameters = new ListTableModel(PARAMETER_COLUMNS);
myTable = new TableView(myParameters);
@@ -241,7 +243,8 @@ public class AppletConfigurable extends SettingsEditor impl
myParameters.setItems(cloneParameters(Arrays.asList(appletParameters)));
}
myModuleSelector.reset(configuration);
- myAlternativeJREPanel.init(configuration.ALTERNATIVE_JRE_PATH, configuration.ALTERNATIVE_JRE_PATH_ENABLED);
+ myJrePathEditor
+ .setPathOrName(configuration.ALTERNATIVE_JRE_PATH, configuration.ALTERNATIVE_JRE_PATH_ENABLED);
}
private RawCommandLineEditor getVMParametersComponent() {
@@ -275,8 +278,8 @@ public class AppletConfigurable extends SettingsEditor impl
catch (NumberFormatException e) {
}
configuration.HTML_USED = myURL.isSelected();
- configuration.ALTERNATIVE_JRE_PATH = myAlternativeJREPanel.getPath();
- configuration.ALTERNATIVE_JRE_PATH_ENABLED = myAlternativeJREPanel.isPathEnabled();
+ configuration.ALTERNATIVE_JRE_PATH = myJrePathEditor.getJrePathOrName();
+ configuration.ALTERNATIVE_JRE_PATH_ENABLED = myJrePathEditor.isAlternativeJreSelected();
}
private void createUIComponents() {
@@ -294,7 +297,7 @@ public class AppletConfigurable extends SettingsEditor impl
myModule.setAnchor(anchor);
myPolicyFile.setAnchor(anchor);
myVMParameters.setAnchor(anchor);
- myAlternativeJREPanel.setAnchor(anchor);
+ myJrePathEditor.setAnchor(anchor);
myHtmlFileLabel.setAnchor(anchor);
}
diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.form b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.form
index 9803e48deb67..40fd90c71d4a 100644
--- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.form
+++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.form
@@ -40,7 +40,7 @@
-
+
diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java
index 0f6b641976c5..3b2f95687b8c 100644
--- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java
+++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java
@@ -19,10 +19,7 @@ import com.intellij.application.options.ModulesComboBox;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.configurations.ConfigurationUtil;
-import com.intellij.execution.ui.AlternativeJREPanel;
-import com.intellij.execution.ui.ClassBrowser;
-import com.intellij.execution.ui.CommonJavaParametersPanel;
-import com.intellij.execution.ui.ConfigurationModuleSelector;
+import com.intellij.execution.ui.*;
import com.intellij.execution.util.JreVersionDetector;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
@@ -49,7 +46,7 @@ public class ApplicationConfigurable extends SettingsEditor
-
+
diff --git a/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java b/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java
index 03758cd031cb..d39ea40ece63 100644
--- a/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java
+++ b/java/execution/impl/src/com/intellij/execution/jar/JarApplicationConfigurable.java
@@ -16,7 +16,8 @@
package com.intellij.execution.jar;
import com.intellij.application.options.ModulesComboBox;
-import com.intellij.execution.ui.AlternativeJREPanel;
+import com.intellij.execution.ui.DefaultJreSelector;
+import com.intellij.execution.ui.JrePathEditor;
import com.intellij.execution.ui.CommonJavaParametersPanel;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.options.ConfigurationException;
@@ -38,22 +39,23 @@ public class JarApplicationConfigurable extends SettingsEditor myModuleComponent;
private JPanel myWholePanel;
- private AlternativeJREPanel myAlternativeJREPanel;
+ private JrePathEditor myJrePathEditor;
private final Project myProject;
private JComponent myAnchor;
public JarApplicationConfigurable(final Project project) {
myProject = project;
- myAnchor = UIUtil.mergeComponentsWithAnchor(myJarPathComponent, myCommonProgramParameters, myAlternativeJREPanel);
+ myAnchor = UIUtil.mergeComponentsWithAnchor(myJarPathComponent, myCommonProgramParameters, myJrePathEditor);
ModulesComboBox modulesComboBox = myModuleComponent.getComponent();
modulesComboBox.allowEmptySelection("");
modulesComboBox.fillModules(project);
+ myJrePathEditor.setDefaultJreSelector(DefaultJreSelector.fromModuleDependencies(modulesComboBox, true));
}
public void applyEditorTo(final JarApplicationConfiguration configuration) throws ConfigurationException {
myCommonProgramParameters.applyTo(configuration);
- configuration.setAlternativeJrePath(myAlternativeJREPanel.getPath());
- configuration.setAlternativeJrePathEnabled(myAlternativeJREPanel.isPathEnabled());
+ configuration.setAlternativeJrePath(myJrePathEditor.getJrePathOrName());
+ configuration.setAlternativeJrePathEnabled(myJrePathEditor.isAlternativeJreSelected());
configuration.setJarPath(FileUtil.toSystemIndependentName(myJarPathComponent.getComponent().getText()));
configuration.setModule(myModuleComponent.getComponent().getSelectedModule());
}
@@ -61,7 +63,8 @@ public class JarApplicationConfigurable extends SettingsEditor ext
private JPanel myWholePanel = new JPanel(new BorderLayout());
private LabeledComponent myModule = new LabeledComponent();
private CommonJavaParametersPanel myCommonJavaParameters = new CommonJavaParametersPanel();
- private AlternativeJREPanel myAlternativeJREPanel = new AlternativeJREPanel();
+ private JrePathEditor myJrePathEditor;
private LabeledComponent myClass = new LabeledComponent();
private LabeledComponent myMethod = new LabeledComponent();
@@ -170,11 +167,12 @@ public class TestDiscoveryConfigurable ext
myWholePanel.add(classpathPanel, BorderLayout.SOUTH);
classpathPanel.add(myModule, BorderLayout.NORTH);
- classpathPanel.add(myAlternativeJREPanel, BorderLayout.CENTER);
+ myJrePathEditor = new JrePathEditor(DefaultJreSelector.fromModuleDependencies(getModulesComponent(), false));
+ classpathPanel.add(myJrePathEditor, BorderLayout.CENTER);
UIUtil.setEnabled(myCommonJavaParameters.getProgramParametersComponent(), false, true);
setAnchor(myModule.getLabel());
- myAlternativeJREPanel.setAnchor(myModule.getLabel());
+ myJrePathEditor.setAnchor(myModule.getLabel());
myCommonJavaParameters.setAnchor(myModule.getLabel());
}
@@ -186,8 +184,8 @@ public class TestDiscoveryConfigurable ext
public void applyEditorTo(final TestDiscoveryConfiguration configuration) {
applyHelpersTo(configuration);
- configuration.setAlternativeJrePath(myAlternativeJREPanel.getPath());
- configuration.setAlternativeJrePathEnabled(myAlternativeJREPanel.isPathEnabled());
+ configuration.setAlternativeJrePath(myJrePathEditor.getJrePathOrName());
+ configuration.setAlternativeJrePathEnabled(myJrePathEditor.isAlternativeJreSelected());
configuration.setPosition(myPositionRb.isSelected() ? Pair.create(myClass.getComponent().getText().trim(),
myMethod.getComponent().getText().trim()) : null);
if (myChangesRb.isSelected()) {
@@ -203,7 +201,8 @@ public class TestDiscoveryConfigurable ext
public void resetEditorFrom(final TestDiscoveryConfiguration configuration) {
myCommonJavaParameters.reset(configuration);
getModuleSelector().reset(configuration);
- myAlternativeJREPanel.init(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
+ myJrePathEditor
+ .setPathOrName(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
final Pair position = configuration.getPosition();
if (position != null) {
myPositionRb.setSelected(true);
diff --git a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
index f2e7f79ff5ee..5a6d49282394 100644
--- a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
+++ b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
@@ -42,6 +42,8 @@ import java.util.ArrayList;
/**
* User: anna
* Date: Jun 21, 2005
+ *
+ * @deprecated use {@link JrePathEditor} instead
*/
public class AlternativeJREPanel extends JPanel implements PanelWithAnchor {
private final ComponentWithBrowseButton myPathField;
diff --git a/java/execution/impl/src/com/intellij/execution/ui/DefaultJreSelector.kt b/java/execution/impl/src/com/intellij/execution/ui/DefaultJreSelector.kt
new file mode 100644
index 000000000000..ddce492ca934
--- /dev/null
+++ b/java/execution/impl/src/com/intellij/execution/ui/DefaultJreSelector.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * 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.
+ */
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * 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 com.intellij.execution.ui
+
+import com.intellij.application.options.ModulesComboBox
+import com.intellij.execution.configurations.JavaParameters
+import com.intellij.execution.util.JavaParametersUtil
+import com.intellij.openapi.editor.event.DocumentAdapter
+import com.intellij.openapi.editor.event.DocumentEvent
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.roots.ModuleRootManager
+import com.intellij.openapi.roots.ProjectRootManager
+import com.intellij.openapi.util.Pair
+import com.intellij.openapi.util.component1
+import com.intellij.openapi.util.component2
+import com.intellij.ui.EditorTextFieldWithBrowseButton
+
+/**
+ * @author nik
+ */
+
+abstract class DefaultJreSelector {
+ companion object {
+ @JvmStatic
+ fun projectSdk(project: Project): DefaultJreSelector = ProjectSdkSelector(project)
+
+ @JvmStatic
+ fun fromModuleDependencies(moduleComboBox: ModulesComboBox, productionOnly: Boolean): DefaultJreSelector
+ = SdkFromModuleDependencies(moduleComboBox, {productionOnly})
+
+ @JvmStatic
+ fun fromSourceRootsDependencies(moduleComboBox: ModulesComboBox, classSelector: EditorTextFieldWithBrowseButton): DefaultJreSelector
+ = SdkFromSourceRootDependencies(moduleComboBox, classSelector)
+ }
+
+ abstract fun getNameAndDescription(): Pair
+ open fun addChangeListener(listener: Runnable) {
+ }
+
+ fun getDescriptionString(): String {
+ val (name, description) = getNameAndDescription()
+ return " (${name ?: ""} - $description)"
+ }
+
+
+ class ProjectSdkSelector(val project: Project): DefaultJreSelector() {
+ override fun getNameAndDescription() = Pair.create(ProjectRootManager.getInstance(project).projectSdkName, "project SDK")
+ }
+
+ open class SdkFromModuleDependencies(val moduleComboBox: ModulesComboBox, val productionOnly: () -> Boolean): DefaultJreSelector() {
+ override fun getNameAndDescription(): Pair {
+ val module = moduleComboBox.selectedModule ?: return Pair.create(null, "module not specified")
+
+ val productionOnly = productionOnly()
+ val jdkToRun = JavaParameters.getJdkToRunModule(module, productionOnly)
+ val moduleJdk = ModuleRootManager.getInstance(module).sdk
+ if (moduleJdk == null || jdkToRun == null) {
+ return Pair.create(null, "module not specified")
+ }
+ if (moduleJdk.homeDirectory == jdkToRun.homeDirectory) {
+ return Pair.create(moduleJdk.name, "SDK of '${module.name}' module")
+ }
+ return Pair.create(jdkToRun.name, "newest SDK from '${module.name}' module${if (productionOnly) "" else " test"} dependencies")
+ }
+
+ override fun addChangeListener(listener: Runnable) {
+ moduleComboBox.addActionListener { listener.run() }
+ }
+ }
+
+ class SdkFromSourceRootDependencies(moduleComboBox: ModulesComboBox, val classSelector: EditorTextFieldWithBrowseButton)
+ : SdkFromModuleDependencies(moduleComboBox, { isClassInProductionSources(moduleComboBox, classSelector) }) {
+ override fun addChangeListener(listener: Runnable) {
+ super.addChangeListener(listener)
+ classSelector.childComponent.addDocumentListener(object : DocumentAdapter() {
+ override fun documentChanged(e: DocumentEvent?) {
+ listener.run()
+ }
+ })
+ }
+ }
+
+}
+
+private fun isClassInProductionSources(moduleSelector: ModulesComboBox, classSelector: EditorTextFieldWithBrowseButton): Boolean {
+ val module = moduleSelector.selectedModule ?: return false
+ return JavaParametersUtil.isClassInProductionSources(classSelector.text, module) ?: false
+}
diff --git a/java/execution/impl/src/com/intellij/execution/ui/JreComboboxEditor.java b/java/execution/impl/src/com/intellij/execution/ui/JreComboboxEditor.java
new file mode 100644
index 000000000000..ee32962dfdf1
--- /dev/null
+++ b/java/execution/impl/src/com/intellij/execution/ui/JreComboboxEditor.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * 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 com.intellij.execution.ui;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.ui.SortedComboBoxModel;
+import com.intellij.ui.components.JBTextField;
+import com.intellij.util.ui.StatusText;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicComboBoxEditor;
+
+/**
+ * @author nik
+ */
+class JreComboboxEditor extends BasicComboBoxEditor {
+ private final SortedComboBoxModel myComboBoxModel;
+
+ public JreComboboxEditor(SortedComboBoxModel comboBoxModel) {
+ myComboBoxModel = comboBoxModel;
+ }
+
+ @Override
+ public void setItem(Object anObject) {
+ editor.setText(anObject == null ? "" : ((JrePathEditor.JreComboBoxItem)anObject).getPresentableText());
+ }
+
+ @Override
+ public Object getItem() {
+ String text = editor.getText().trim();
+ for (JrePathEditor.JreComboBoxItem item : myComboBoxModel.getItems()) {
+ if (item.getPresentableText().equals(text)) {
+ return item;
+ }
+ }
+ return new JrePathEditor.CustomJreItem(FileUtil.toSystemIndependentName(text));
+ }
+
+ @Override
+ protected JTextField createEditorComponent() {
+ return new JBTextField();
+ }
+
+ public StatusText getEmptyText() {
+ return getEditorComponent().getEmptyText();
+ }
+
+ public JBTextField getEditorComponent() {
+ return (JBTextField)super.getEditorComponent();
+ }
+}
diff --git a/java/execution/impl/src/com/intellij/execution/ui/JrePathEditor.java b/java/execution/impl/src/com/intellij/execution/ui/JrePathEditor.java
new file mode 100644
index 000000000000..7d24016a1ccd
--- /dev/null
+++ b/java/execution/impl/src/com/intellij/execution/ui/JrePathEditor.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * 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 com.intellij.execution.ui;
+
+import com.intellij.execution.ExecutionBundle;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.BrowseFilesListener;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ui.OrderEntryAppearanceService;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.TextComponentAccessor;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.util.ui.StatusText;
+import net.miginfocom.swing.MigLayout;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.File;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class JrePathEditor extends JPanel implements PanelWithAnchor {
+ private static final String DEFAULT_JRE_TEXT = "Default";
+ private final ComboboxWithBrowseButton myPathField;
+ private final JBLabel myLabel;
+ private final JreComboboxEditor myComboboxEditor;
+ private final DefaultJreItem myDefaultJreItem;
+ private DefaultJreSelector myDefaultJreSelector;
+ private JComponent myAnchor;
+ private final SortedComboBoxModel myComboBoxModel;
+ private String myPreviousCustomJrePath;
+
+ public JrePathEditor(DefaultJreSelector defaultJreSelector) {
+ this();
+ setDefaultJreSelector(defaultJreSelector);
+ }
+
+ /**
+ * This constructor can be used in UI forms. Don't forget to call {@link #setDefaultJreSelector(DefaultJreSelector)}!
+ */
+ public JrePathEditor() {
+ myLabel = new JBLabel(ExecutionBundle.message("run.configuration.jre.label"));
+
+ myComboBoxModel = new SortedComboBoxModel(new Comparator() {
+ @Override
+ public int compare(JreComboBoxItem o1, JreComboBoxItem o2) {
+ int result = Comparing.compare(o1.getOrder(), o2.getOrder());
+ if (result != 0) {
+ return result;
+ }
+ return o1.getPresentableText().compareToIgnoreCase(o2.getPresentableText());
+ }
+ });
+ myDefaultJreItem = new DefaultJreItem();
+ myComboBoxModel.add(myDefaultJreItem);
+ final Sdk[] allJDKs = ProjectJdkTable.getInstance().getAllJdks();
+ for (Sdk sdk : allJDKs) {
+ myComboBoxModel.add(new SdkAsJreItem(sdk));
+ }
+
+ final Set jrePaths = new HashSet();
+ for (JreProvider provider : JreProvider.EP_NAME.getExtensions()) {
+ String path = provider.getJrePath();
+ if (!StringUtil.isEmpty(path)) {
+ jrePaths.add(path);
+ myComboBoxModel.add(new CustomJreItem(path));
+ }
+ }
+
+ for (Sdk jdk : allJDKs) {
+ String homePath = jdk.getHomePath();
+
+ if (!SystemInfo.isMac) {
+ final File jre = new File(jdk.getHomePath(), "jre");
+ if (jre.isDirectory()) {
+ homePath = jre.getPath();
+ }
+ }
+ if (jrePaths.add(homePath)) {
+ myComboBoxModel.add(new CustomJreItem(homePath));
+ }
+ }
+ ComboBox comboBox = new ComboBox(myComboBoxModel);
+ comboBox.setEditable(true);
+ comboBox.setRenderer(new ColoredListCellRendererWrapper() {
+ @Override
+ protected void doCustomize(JList list, JreComboBoxItem value, int index, boolean selected, boolean hasFocus) {
+ value.render(this, selected);
+ }
+ });
+ myComboboxEditor = new JreComboboxEditor(myComboBoxModel);
+ myComboboxEditor.getEditorComponent().setTextToTriggerEmptyTextStatus(DEFAULT_JRE_TEXT);
+ comboBox.setEditor(myComboboxEditor);
+ myPathField = new ComboboxWithBrowseButton(comboBox);
+ myPathField.addBrowseFolderListener(ExecutionBundle.message("run.configuration.select.alternate.jre.label"),
+ ExecutionBundle.message("run.configuration.select.jre.dir.label"),
+ null, BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR,
+ TextComponentAccessor.STRING_COMBOBOX_WHOLE_TEXT);
+
+ setLayout(new MigLayout("ins 0, gap 10, fill, flowx"));
+ add(myLabel, "shrinkx");
+ add(myPathField, "growx, pushx");
+
+ InsertPathAction.addTo(myComboboxEditor.getEditorComponent());
+
+ setAnchor(myLabel);
+
+ updateUI();
+ }
+
+ @Nullable
+ public String getJrePathOrName() {
+ JreComboBoxItem jre = getSelectedJre();
+ if (jre instanceof DefaultJreItem) {
+ return myPreviousCustomJrePath;
+ }
+ return jre.getPresentableText();
+ }
+
+ public boolean isAlternativeJreSelected() {
+ return !(getSelectedJre() instanceof DefaultJreItem);
+ }
+
+ private JreComboBoxItem getSelectedJre() {
+ return (JreComboBoxItem)myPathField.getComboBox().getSelectedItem();
+ }
+
+ public void setDefaultJreSelector(DefaultJreSelector defaultJreSelector) {
+ myDefaultJreSelector = defaultJreSelector;
+ myDefaultJreSelector.addChangeListener(new Runnable() {
+ @Override
+ public void run() {
+ updateDefaultJrePresentation();
+ }
+ });
+ }
+
+ public void setPathOrName(@Nullable String pathOrName, boolean useAlternativeJre) {
+ JreComboBoxItem toSelect = myDefaultJreItem;
+ if (!StringUtil.isEmpty(pathOrName)) {
+ myPreviousCustomJrePath = pathOrName;
+ JreComboBoxItem alternative = findOrAddCustomJre(pathOrName);
+ if (useAlternativeJre) {
+ toSelect = alternative;
+ }
+ }
+ myPathField.getChildComponent().setSelectedItem(toSelect);
+ updateDefaultJrePresentation();
+ }
+
+ private void updateDefaultJrePresentation() {
+ StatusText text = myComboboxEditor.getEmptyText();
+ text.clear();
+ text.appendText(DEFAULT_JRE_TEXT, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ text.appendText(myDefaultJreSelector.getDescriptionString(), SimpleTextAttributes.GRAY_ATTRIBUTES);
+ }
+
+ private JreComboBoxItem findOrAddCustomJre(@NotNull String pathOrName) {
+ for (JreComboBoxItem item : myComboBoxModel.getItems()) {
+ if (item instanceof CustomJreItem && FileUtil.pathsEqual(pathOrName, ((CustomJreItem)item).myPath)
+ || item.getPresentableText().equals(pathOrName)) {
+ return item;
+ }
+ }
+ CustomJreItem item = new CustomJreItem(pathOrName);
+ myComboBoxModel.add(item);
+ return item;
+ }
+
+ @Override
+ public JComponent getAnchor() {
+ return myAnchor;
+ }
+
+ @Override
+ public void setAnchor(JComponent anchor) {
+ myAnchor = anchor;
+ myLabel.setAnchor(anchor);
+ }
+
+ interface JreComboBoxItem {
+ void render(SimpleColoredComponent component, boolean selected);
+ String getPresentableText();
+ int getOrder();
+ }
+
+ private static class SdkAsJreItem implements JreComboBoxItem {
+ private final Sdk mySdk;
+
+ public SdkAsJreItem(Sdk sdk) {
+ mySdk = sdk;
+ }
+
+ @Override
+ public void render(SimpleColoredComponent component, boolean selected) {
+ OrderEntryAppearanceService.getInstance().forJdk(mySdk, false, selected, true).customize(component);
+ }
+
+ @Override
+ public String getPresentableText() {
+ return mySdk.getName();
+ }
+
+ @Override
+ public int getOrder() {
+ return 1;
+ }
+ }
+
+ static class CustomJreItem implements JreComboBoxItem {
+ private final String myPath;
+
+ public CustomJreItem(String path) {
+ myPath = path;
+ }
+
+ @Override
+ public void render(SimpleColoredComponent component, boolean selected) {
+ component.append(getPresentableText());
+ component.setIcon(AllIcons.Nodes.Folder);
+ }
+
+ @Override
+ public String getPresentableText() {
+ return FileUtil.toSystemDependentName(myPath);
+ }
+
+ @Override
+ public int getOrder() {
+ return 2;
+ }
+ }
+
+ private class DefaultJreItem implements JreComboBoxItem {
+ @Override
+ public void render(SimpleColoredComponent component, boolean selected) {
+ component.append(DEFAULT_JRE_TEXT);
+ component.append(myDefaultJreSelector.getDescriptionString(), SimpleTextAttributes.GRAY_ATTRIBUTES);
+ }
+
+ @Override
+ public String getPresentableText() {
+ return DEFAULT_JRE_TEXT;
+ }
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+ }
+}
+
diff --git a/platform/platform-impl/src/com/intellij/openapi/util/extensions.kt b/platform/platform-impl/src/com/intellij/openapi/util/extensions.kt
new file mode 100644
index 000000000000..34c17de215e8
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/util/extensions.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * 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.
+ */
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * 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 com.intellij.openapi.util
+
+/**
+ * Put here extension functions and variables for classes from util/util-rt modules
+ */
+
+operator fun Pair.component1() = this.first
+operator fun Pair.component2() = this.second
diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties
index 5454e5bd38f0..3c9e8a0a4429 100644
--- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties
+++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties
@@ -173,6 +173,7 @@ run.configuration.java.vm.parameters.label=&VM options:
run.configuration.program.parameters=Program a&rguments:
run.configuration.working.directory.label=&Working directory:
run.configuration.use.alternate.jre.checkbox=Use alternative &JRE:
+run.configuration.jre.label=&JRE:
run.configuration.select.alternate.jre.label=Select Alternative JRE
run.configuration.select.jre.dir.label=Select directory with JRE to run with
run.configuration.arguments.help.panel.copy.action.name=Copy
diff --git a/plugins/devkit/src/run/PluginRunConfigurationEditor.java b/plugins/devkit/src/run/PluginRunConfigurationEditor.java
index 9749d3adca18..bb2701c37633 100644
--- a/plugins/devkit/src/run/PluginRunConfigurationEditor.java
+++ b/plugins/devkit/src/run/PluginRunConfigurationEditor.java
@@ -18,7 +18,8 @@ package org.jetbrains.idea.devkit.run;
import com.intellij.application.options.ModulesComboBox;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.LogFileOptions;
-import com.intellij.execution.ui.AlternativeJREPanel;
+import com.intellij.execution.ui.DefaultJreSelector;
+import com.intellij.execution.ui.JrePathEditor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
@@ -53,7 +54,7 @@ public class PluginRunConfigurationEditor extends SettingsEditor myVMParameters = new LabeledComponent();
private final LabeledComponent myProgramParameters = new LabeledComponent();
private JComponent anchor;
- private final AlternativeJREPanel myAlternativeJREPanel = new AlternativeJREPanel();
+ private final JrePathEditor myJrePathEditor;
@NonNls private final JCheckBox myShowLogs = new JCheckBox(DevKitBundle.message("show.smth", "idea.log"));
@@ -98,6 +99,7 @@ public class PluginRunConfigurationEditor extends SettingsEditor
-
+
diff --git a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java
index 0278535a81be..3bf98f3732c8 100644
--- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java
+++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java
@@ -26,10 +26,7 @@ import com.intellij.execution.junit.JUnitUtil;
import com.intellij.execution.junit.TestClassFilter;
import com.intellij.execution.testframework.SourceScope;
import com.intellij.execution.testframework.TestSearchScope;
-import com.intellij.execution.ui.AlternativeJREPanel;
-import com.intellij.execution.ui.ClassBrowser;
-import com.intellij.execution.ui.CommonJavaParametersPanel;
-import com.intellij.execution.ui.ConfigurationModuleSelector;
+import com.intellij.execution.ui.*;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.ClassFilter;
import com.intellij.ide.util.PackageChooserDialog;
@@ -98,7 +95,7 @@ public class JUnitConfigurable extends SettingsEdi
private JRadioButton mySingleModuleScope;
private JRadioButton myModuleWDScope;
private TextFieldWithBrowseButton myPatternTextField;
- private AlternativeJREPanel myAlternativeJREPanel;
+ private JrePathEditor myJrePathEditor;
private JComboBox myForkCb;
private JBLabel myTestLabel;
private JComboBox myTypeChooser;
@@ -113,6 +110,7 @@ public class JUnitConfigurable extends SettingsEdi
myProject = project;
myModel = new JUnitConfigurationModel(project);
myModuleSelector = new ConfigurationModuleSelector(project, getModulesComponent());
+ myJrePathEditor.setDefaultJreSelector(DefaultJreSelector.fromModuleDependencies(getModulesComponent(), false));
myCommonJavaParameters.setModuleContext(myModuleSelector.getModule());
myCommonJavaParameters.setHasModuleMacro();
myModule.getComponent().addActionListener(new ActionListener() {
@@ -247,7 +245,7 @@ public class JUnitConfigurable extends SettingsEdi
UIUtil.setEnabled(myCommonJavaParameters.getProgramParametersComponent(), false, true);
setAnchor(mySearchForTestsLabel);
- myAlternativeJREPanel.setAnchor(myModule.getLabel());
+ myJrePathEditor.setAnchor(myModule.getLabel());
myCommonJavaParameters.setAnchor(myModule.getLabel());
}
@@ -273,8 +271,8 @@ public class JUnitConfigurable extends SettingsEdi
else if (myModuleWDScope.isSelected()) {
data.setScope(TestSearchScope.MODULE_WITH_DEPENDENCIES);
}
- configuration.setAlternativeJrePath(myAlternativeJREPanel.getPath());
- configuration.setAlternativeJrePathEnabled(myAlternativeJREPanel.isPathEnabled());
+ configuration.setAlternativeJrePath(myJrePathEditor.getJrePathOrName());
+ configuration.setAlternativeJrePathEnabled(myJrePathEditor.isAlternativeJreSelected());
myCommonJavaParameters.applyTo(configuration);
configuration.setForkMode((String)myForkCb.getSelectedItem());
@@ -301,7 +299,8 @@ public class JUnitConfigurable extends SettingsEdi
else {
myWholeProjectScope.setSelected(true);
}
- myAlternativeJREPanel.init(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
+ myJrePathEditor
+ .setPathOrName(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
myForkCb.setSelectedItem(configuration.getForkMode());
final int count = configuration.getRepeatCount();
myRepeatCountField.setText(String.valueOf(count));
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form
index d6144e862d76..6dcebbbfb117 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.form
@@ -158,7 +158,7 @@
-
+
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java
index eb91dac65e7e..856cb84027cc 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java
@@ -28,7 +28,8 @@ import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.MethodBrowser;
import com.intellij.execution.configuration.BrowseModuleValueActionListener;
import com.intellij.execution.testframework.TestSearchScope;
-import com.intellij.execution.ui.AlternativeJREPanel;
+import com.intellij.execution.ui.DefaultJreSelector;
+import com.intellij.execution.ui.JrePathEditor;
import com.intellij.execution.ui.CommonJavaParametersPanel;
import com.intellij.execution.ui.ConfigurationModuleSelector;
import com.intellij.icons.AllIcons;
@@ -80,7 +81,7 @@ public class TestNGConfigurationEditor extends Se
private LabeledComponent classField;
private LabeledComponent moduleClasspath;
- private AlternativeJREPanel alternateJDK;
+ private JrePathEditor alternateJDK;
private final ConfigurationModuleSelector moduleSelector;
private JRadioButton suiteTest;
private JRadioButton packageTest;
@@ -136,6 +137,7 @@ public class TestNGConfigurationEditor extends Se
model.setListener(this);
createView();
moduleSelector = new ConfigurationModuleSelector(project, getModulesComponent());
+ alternateJDK.setDefaultJreSelector(DefaultJreSelector.fromModuleDependencies(getModulesComponent(), false));
commonJavaParameters.setModuleContext(moduleSelector.getModule());
moduleClasspath.getComponent().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -311,7 +313,7 @@ public class TestNGConfigurationEditor extends Se
packagesInProject.setSelected(true);
}
evaluateModuleClassPath();
- alternateJDK.init(config.ALTERNATIVE_JRE_PATH, config.ALTERNATIVE_JRE_PATH_ENABLED);
+ alternateJDK.setPathOrName(config.ALTERNATIVE_JRE_PATH, config.ALTERNATIVE_JRE_PATH_ENABLED);
propertiesList.clear();
propertiesList.addAll(data.TEST_PROPERTIES.entrySet());
propertiesTableModel.setParameterList(propertiesList);
@@ -338,8 +340,8 @@ public class TestNGConfigurationEditor extends Se
data.setScope(TestSearchScope.MODULE_WITH_DEPENDENCIES);
}
commonJavaParameters.applyTo(config);
- config.ALTERNATIVE_JRE_PATH = alternateJDK.getPath();
- config.ALTERNATIVE_JRE_PATH_ENABLED = alternateJDK.isPathEnabled();
+ config.ALTERNATIVE_JRE_PATH = alternateJDK.getJrePathOrName();
+ config.ALTERNATIVE_JRE_PATH_ENABLED = alternateJDK.isAlternativeJreSelected();
data.TEST_PROPERTIES.clear();
for (Map.Entry entry : propertiesList) {