'Use alternative JRE' option reworked: checkbox removed, it now shows name of default JRE (IDEA-145791), icons and descriptions for JDK items added

This commit is contained in:
nik
2015-10-01 13:08:14 +03:00
parent 309727d069
commit 93055338f8
18 changed files with 561 additions and 58 deletions
@@ -209,7 +209,7 @@
</constraints>
<properties/>
</component>
<component id="b2d36" class="com.intellij.execution.ui.AlternativeJREPanel" binding="myAlternativeJREPanel">
<component id="b2d36" class="com.intellij.execution.ui.JrePathEditor" binding="myJrePathEditor">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<AppletConfiguration> 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<AppletConfiguration> impl
myModuleSelector = new ConfigurationModuleSelector(project, getModuleComponent());
myJrePathEditor.setDefaultJreSelector(DefaultJreSelector.fromModuleDependencies(getModuleComponent(), true));
myTablePlace.setLayout(new BorderLayout());
myParameters = new ListTableModel<AppletConfiguration.AppletParameter>(PARAMETER_COLUMNS);
myTable = new TableView(myParameters);
@@ -241,7 +243,8 @@ public class AppletConfigurable extends SettingsEditor<AppletConfiguration> 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<AppletConfiguration> 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<AppletConfiguration> impl
myModule.setAnchor(anchor);
myPolicyFile.setAnchor(anchor);
myVMParameters.setAnchor(anchor);
myAlternativeJREPanel.setAnchor(anchor);
myJrePathEditor.setAnchor(anchor);
myHtmlFileLabel.setAnchor(anchor);
}
@@ -40,7 +40,7 @@
<text resource-bundle="messages/ExecutionBundle" key="application.configuration.use.classpath.and.jdk.of.module.label"/>
</properties>
</component>
<component id="e88bd" class="com.intellij.execution.ui.AlternativeJREPanel" binding="myAlternativeJREPanel">
<component id="e88bd" class="com.intellij.execution.ui.JrePathEditor" binding="myJrePathEditor">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<ApplicationConfigura
private JPanel myWholePanel;
private final ConfigurationModuleSelector myModuleSelector;
private AlternativeJREPanel myAlternativeJREPanel;
private JrePathEditor myJrePathEditor;
private JCheckBox myShowSwingInspectorCheckbox;
private final JreVersionDetector myVersionDetector;
private final Project myProject;
@@ -58,6 +55,7 @@ public class ApplicationConfigurable extends SettingsEditor<ApplicationConfigura
public ApplicationConfigurable(final Project project) {
myProject = project;
myModuleSelector = new ConfigurationModuleSelector(project, myModule.getComponent());
myJrePathEditor.setDefaultJreSelector(DefaultJreSelector.fromSourceRootsDependencies(myModule.getComponent(), getMainClassField()));
myCommonProgramParameters.setModuleContext(myModuleSelector.getModule());
myModule.getComponent().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -67,7 +65,7 @@ public class ApplicationConfigurable extends SettingsEditor<ApplicationConfigura
ClassBrowser.createApplicationClassBrowser(project, myModuleSelector).setField(getMainClassField());
myVersionDetector = new JreVersionDetector();
myAnchor = UIUtil.mergeComponentsWithAnchor(myMainClass, myCommonProgramParameters, myAlternativeJREPanel, myModule);
myAnchor = UIUtil.mergeComponentsWithAnchor(myMainClass, myCommonProgramParameters, myJrePathEditor, myModule);
}
public void applyEditorTo(final ApplicationConfiguration configuration) throws ConfigurationException {
@@ -76,8 +74,8 @@ public class ApplicationConfigurable extends SettingsEditor<ApplicationConfigura
final String className = getMainClassField().getText();
final PsiClass aClass = myModuleSelector.findClass(className);
configuration.MAIN_CLASS_NAME = aClass != null ? JavaExecutionUtil.getRuntimeQualifiedName(aClass) : className;
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();
configuration.ENABLE_SWING_INSPECTOR = (myVersionDetector.isJre50Configured(configuration) || myVersionDetector.isModuleJre50Configured(configuration)) && myShowSwingInspectorCheckbox.isSelected();
updateShowSwingInspector(configuration);
@@ -87,7 +85,7 @@ public class ApplicationConfigurable extends SettingsEditor<ApplicationConfigura
myCommonProgramParameters.reset(configuration);
myModuleSelector.reset(configuration);
getMainClassField().setText(configuration.MAIN_CLASS_NAME != null ? configuration.MAIN_CLASS_NAME.replaceAll("\\$", "\\.") : "");
myAlternativeJREPanel.init(configuration.ALTERNATIVE_JRE_PATH, configuration.ALTERNATIVE_JRE_PATH_ENABLED);
myJrePathEditor.setPathOrName(configuration.ALTERNATIVE_JRE_PATH, configuration.ALTERNATIVE_JRE_PATH_ENABLED);
updateShowSwingInspector(configuration);
}
@@ -144,7 +142,7 @@ public class ApplicationConfigurable extends SettingsEditor<ApplicationConfigura
this.myAnchor = anchor;
myMainClass.setAnchor(anchor);
myCommonProgramParameters.setAnchor(anchor);
myAlternativeJREPanel.setAnchor(anchor);
myJrePathEditor.setAnchor(anchor);
myModule.setAnchor(anchor);
}
}
@@ -19,7 +19,7 @@
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="a09fc" class="com.intellij.execution.ui.AlternativeJREPanel" binding="myAlternativeJREPanel">
<component id="a09fc" class="com.intellij.execution.ui.JrePathEditor" binding="myJrePathEditor">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<JarApplicationCon
private LabeledComponent<ModulesComboBox> 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("<whole project>");
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<JarApplicationCon
public void resetEditorFrom(final JarApplicationConfiguration configuration) {
myCommonProgramParameters.reset(configuration);
myJarPathComponent.getComponent().setText(FileUtil.toSystemDependentName(configuration.getJarPath()));
myAlternativeJREPanel.init(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
myJrePathEditor.setPathOrName(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled()
);
myModuleComponent.getComponent().setSelectedModule(configuration.getModule());
}
@@ -87,7 +90,7 @@ public class JarApplicationConfigurable extends SettingsEditor<JarApplicationCon
public void setAnchor(@Nullable JComponent anchor) {
myAnchor = anchor;
myCommonProgramParameters.setAnchor(anchor);
myAlternativeJREPanel.setAnchor(anchor);
myJrePathEditor.setAnchor(anchor);
myJarPathComponent.setAnchor(anchor);
}
}
@@ -17,10 +17,7 @@ package com.intellij.execution.testDiscovery;
import com.intellij.application.options.ModulesComboBox;
import com.intellij.execution.MethodBrowser;
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.ide.util.ClassFilter;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.options.SettingsEditor;
@@ -54,7 +51,7 @@ public class TestDiscoveryConfigurable<T extends TestDiscoveryConfiguration> ext
private JPanel myWholePanel = new JPanel(new BorderLayout());
private LabeledComponent<ModulesComboBox> myModule = new LabeledComponent<ModulesComboBox>();
private CommonJavaParametersPanel myCommonJavaParameters = new CommonJavaParametersPanel();
private AlternativeJREPanel myAlternativeJREPanel = new AlternativeJREPanel();
private JrePathEditor myJrePathEditor;
private LabeledComponent<EditorTextFieldWithBrowseButton> myClass = new LabeledComponent<EditorTextFieldWithBrowseButton>();
private LabeledComponent<EditorTextFieldWithBrowseButton> myMethod = new LabeledComponent<EditorTextFieldWithBrowseButton>();
@@ -170,11 +167,12 @@ public class TestDiscoveryConfigurable<T extends TestDiscoveryConfiguration> 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<T extends TestDiscoveryConfiguration> 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<T extends TestDiscoveryConfiguration> 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<String, String> position = configuration.getPosition();
if (position != null) {
myPositionRb.setSelected(true);
@@ -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<TextFieldWithHistory> myPathField;
@@ -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<String?, String>
open fun addChangeListener(listener: Runnable) {
}
fun getDescriptionString(): String {
val (name, description) = getNameAndDescription()
return " (${name ?: "<no JRE>"} - $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<String?, String> {
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
}
@@ -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<JrePathEditor.JreComboBoxItem> myComboBoxModel;
public JreComboboxEditor(SortedComboBoxModel<JrePathEditor.JreComboBoxItem> 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();
}
}
@@ -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<JreComboBoxItem> myComboBoxModel;
private String myPreviousCustomJrePath;
public JrePathEditor(DefaultJreSelector defaultJreSelector) {
this();
setDefaultJreSelector(defaultJreSelector);
}
/**
* This constructor can be used in UI forms. <strong>Don't forget to call {@link #setDefaultJreSelector(DefaultJreSelector)}!</strong>
*/
public JrePathEditor() {
myLabel = new JBLabel(ExecutionBundle.message("run.configuration.jre.label"));
myComboBoxModel = new SortedComboBoxModel<JreComboBoxItem>(new Comparator<JreComboBoxItem>() {
@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<String> jrePaths = new HashSet<String>();
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<JreComboBoxItem>() {
@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;
}
}
}
@@ -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 <A, B> Pair<A, B>.component1() = this.first
operator fun <A, B> Pair<A, B>.component2() = this.second
@@ -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
@@ -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<PluginRunConfig
private final LabeledComponent<RawCommandLineEditor> myVMParameters = new LabeledComponent<RawCommandLineEditor>();
private final LabeledComponent<RawCommandLineEditor> myProgramParameters = new LabeledComponent<RawCommandLineEditor>();
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<PluginRunConfig
});
setAnchor(myModuleLabel);
myJrePathEditor = new JrePathEditor(DefaultJreSelector.fromModuleDependencies(myModules, true));
}
@Override
@@ -131,7 +133,7 @@ public class PluginRunConfigurationEditor extends SettingsEditor<PluginRunConfig
myModules.setSelectedModule(prc.getModule());
getVMParameters().setText(prc.VM_PARAMETERS);
getProgramParameters().setText(prc.PROGRAM_PARAMETERS);
myAlternativeJREPanel.init(prc.getAlternativeJrePath(), prc.isAlternativeJreEnabled());
myJrePathEditor.setPathOrName(prc.getAlternativeJrePath(), prc.isAlternativeJreEnabled());
}
@@ -140,8 +142,8 @@ public class PluginRunConfigurationEditor extends SettingsEditor<PluginRunConfig
prc.setModule(myModules.getSelectedModule());
prc.VM_PARAMETERS = getVMParameters().getText();
prc.PROGRAM_PARAMETERS = getProgramParameters().getText();
prc.setAlternativeJrePath(myAlternativeJREPanel.getPath());
prc.setAlternativeJreEnabled(myAlternativeJREPanel.isPathEnabled());
prc.setAlternativeJrePath(myJrePathEditor.getJrePathOrName());
prc.setAlternativeJreEnabled(myJrePathEditor.isAlternativeJreSelected());
}
@Override
@@ -174,7 +176,7 @@ public class PluginRunConfigurationEditor extends SettingsEditor<PluginRunConfig
gc.gridy = 4;
gc.gridwidth = 2;
wholePanel.add(myAlternativeJREPanel, gc);
wholePanel.add(myJrePathEditor, gc);
gc.gridy = 5;
wholePanel.add(myShowLogs, gc);
return wholePanel;
@@ -68,7 +68,7 @@
<text resource-bundle="messages/ExecutionBundle" key="application.configuration.use.classpath.and.jdk.of.module.label"/>
</properties>
</component>
<component id="e5163" class="com.intellij.execution.ui.AlternativeJREPanel" binding="myAlternativeJREPanel">
<component id="e5163" class="com.intellij.execution.ui.JrePathEditor" binding="myJrePathEditor">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<T extends JUnitConfiguration> 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<T extends JUnitConfiguration> 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<T extends JUnitConfiguration> 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<T extends JUnitConfiguration> 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<T extends JUnitConfiguration> 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));
@@ -158,7 +158,7 @@
<text resource-bundle="messages/ExecutionBundle" key="application.configuration.use.classpath.and.jdk.of.module.label"/>
</properties>
</component>
<component id="baac2" class="com.intellij.execution.ui.AlternativeJREPanel" binding="alternateJDK">
<component id="baac2" class="com.intellij.execution.ui.JrePathEditor" binding="alternateJDK">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<T extends TestNGConfiguration> extends Se
private LabeledComponent<EditorTextFieldWithBrowseButton> classField;
private LabeledComponent<ModulesComboBox> moduleClasspath;
private AlternativeJREPanel alternateJDK;
private JrePathEditor alternateJDK;
private final ConfigurationModuleSelector moduleSelector;
private JRadioButton suiteTest;
private JRadioButton packageTest;
@@ -136,6 +137,7 @@ public class TestNGConfigurationEditor<T extends TestNGConfiguration> 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<T extends TestNGConfiguration> 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<T extends TestNGConfiguration> 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<String, String> entry : propertiesList) {