blob: 8a53180ce4c049e2d497b95d919ebb8db740bbf4 [file] [log] [blame]
/*
* Copyright 2000-2012 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.ide.util.projectWizard;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.projectRoots.ui.ProjectJdksEditor;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.ui.ClickListener;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ListScrollingUtil;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBList;
import com.intellij.util.ArrayUtil;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.*;
public class JdkChooserPanel extends JPanel {
private JList myList = null;
private DefaultListModel myListModel = null;
private Sdk myCurrentJdk;
@Nullable private final Project myProject;
private SdkType[] myAllowedJdkTypes = null;
public JdkChooserPanel(@Nullable final Project project) {
super(new BorderLayout());
myProject = project;
myListModel = new DefaultListModel();
myList = new JBList(myListModel);
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myList.setCellRenderer(new ProjectJdkListRenderer());
myList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
myCurrentJdk = (Sdk)myList.getSelectedValue();
}
});
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
if (myProject == null) {
editJdkTable();
}
return true;
}
}.installOn(myList);
JPanel panel = new JPanel(new BorderLayout());
panel.add(ScrollPaneFactory.createScrollPane(myList), BorderLayout.CENTER);
add(panel, BorderLayout.CENTER);
if (myListModel.getSize() > 0) {
myList.setSelectedIndex(0);
}
}
/**
* Sets the JDK types which may be shown in the panel.
*
* @param allowedJdkTypes the array of JDK types which may be shown, or null if all JDK types are allowed.
* @since 7.0.3
*/
public void setAllowedJdkTypes(@Nullable final SdkType[] allowedJdkTypes) {
myAllowedJdkTypes = allowedJdkTypes;
}
public Sdk getChosenJdk() {
return myCurrentJdk;
}
public Object[] getAllJdks() {
return myListModel.toArray();
}
public void editJdkTable() {
ProjectJdksEditor editor = new ProjectJdksEditor((Sdk)myList.getSelectedValue(),
myProject != null ? myProject : ProjectManager.getInstance().getDefaultProject(),
myList);
editor.show();
if (editor.isOK()) {
Sdk selectedJdk = editor.getSelectedJdk();
updateList(selectedJdk, null);
}
}
public void updateList(final Sdk selectedJdk, final @Nullable SdkType type) {
updateList(selectedJdk, type, null);
}
public void updateList(final Sdk selectedJdk, final @Nullable SdkType type, final @Nullable Sdk[] globalSdks) {
final int[] selectedIndices = myList.getSelectedIndices();
fillList(type, globalSdks);
// restore selection
if (selectedJdk != null) {
TIntArrayList list = new TIntArrayList();
for (int i = 0; i < myListModel.size(); i++) {
final Sdk jdk = (Sdk)myListModel.getElementAt(i);
if (Comparing.strEqual(jdk.getName(), selectedJdk.getName())){
list.add(i);
}
}
final int[] indicesToSelect = list.toNativeArray();
if (indicesToSelect.length > 0) {
myList.setSelectedIndices(indicesToSelect);
}
else if (myList.getModel().getSize() > 0) {
myList.setSelectedIndex(0);
}
}
else {
if (selectedIndices.length > 0) {
myList.setSelectedIndices(selectedIndices);
}
else {
myList.setSelectedIndex(0);
}
}
myCurrentJdk = (Sdk)myList.getSelectedValue();
}
public JList getPreferredFocusedComponent() {
return myList;
}
public void fillList(final @Nullable SdkType type, final @Nullable Sdk[] globalSdks) {
myListModel.clear();
final Sdk[] jdks;
if (myProject == null || myProject.isDefault()) {
final Sdk[] allJdks = globalSdks != null ? globalSdks : ProjectJdkTable.getInstance().getAllJdks();
jdks = getCompatibleJdks(type, Arrays.asList(allJdks));
}
else {
final ProjectSdksModel projectJdksModel = ProjectStructureConfigurable.getInstance(myProject).getProjectJdksModel();
if (!projectJdksModel.isInitialized()){ //should be initialized
projectJdksModel.reset(myProject);
}
final Collection<Sdk> collection = projectJdksModel.getProjectSdks().values();
jdks = getCompatibleJdks(type, collection);
}
Arrays.sort(jdks, new Comparator<Sdk>() {
public int compare(final Sdk o1, final Sdk o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
});
for (Sdk jdk : jdks) {
myListModel.addElement(jdk);
}
}
private Sdk[] getCompatibleJdks(final @Nullable SdkType type, final Collection<Sdk> collection) {
final Set<Sdk> compatibleJdks = new HashSet<Sdk>();
for (Sdk projectJdk : collection) {
if (isCompatibleJdk(projectJdk, type)) {
compatibleJdks.add(projectJdk);
}
}
return compatibleJdks.toArray(new Sdk[compatibleJdks.size()]);
}
private boolean isCompatibleJdk(final Sdk projectJdk, final @Nullable SdkType type) {
if (type != null) {
return projectJdk.getSdkType() == type;
}
if (myAllowedJdkTypes != null) {
return ArrayUtil.indexOf(myAllowedJdkTypes, projectJdk.getSdkType()) >= 0;
}
return true;
}
public JComponent getDefaultFocusedComponent() {
return myList;
}
public void selectJdk(Sdk defaultJdk) {
final int index = myListModel.indexOf(defaultJdk);
if (index >= 0) {
myList.setSelectedIndex(index);
}
}
public void addSelectionListener(final ListSelectionListener listener) {
myList.addListSelectionListener(listener);
}
private static Sdk showDialog(final Project project, String title, final Component parent, Sdk jdkToSelect) {
final JdkChooserPanel jdkChooserPanel = new JdkChooserPanel(project);
jdkChooserPanel.fillList(null, null);
final MyDialog dialog = jdkChooserPanel.new MyDialog(parent);
if (title != null) {
dialog.setTitle(title);
}
if (jdkToSelect != null) {
jdkChooserPanel.selectJdk(jdkToSelect);
} else {
ListScrollingUtil.ensureSelectionExists(jdkChooserPanel.myList);
}
new DoubleClickListener() {
@Override
protected boolean onDoubleClick(MouseEvent e) {
dialog.clickDefaultButton();
return true;
}
}.installOn(jdkChooserPanel.myList);
dialog.show();
return dialog.isOK() ? jdkChooserPanel.getChosenJdk() : null;
}
public static Sdk chooseAndSetJDK(final Project project) {
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
final Sdk jdk = showDialog(project, ProjectBundle.message("module.libraries.target.jdk.select.title"), WindowManagerEx.getInstanceEx().getFrame(project), projectJdk);
if (jdk == null) {
return null;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
ProjectRootManager.getInstance(project).setProjectSdk(jdk);
}
});
return jdk;
}
public class MyDialog extends DialogWrapper implements ListSelectionListener {
public MyDialog(Component parent) {
super(parent, true);
setTitle(IdeBundle.message("title.select.jdk"));
init();
myList.addListSelectionListener(this);
updateOkButton();
}
protected String getDimensionServiceKey() {
return "#com.intellij.ide.util.projectWizard.JdkChooserPanel.MyDialog";
}
public void valueChanged(ListSelectionEvent e) {
updateOkButton();
}
private void updateOkButton() {
setOKActionEnabled(myList.getSelectedValue() != null);
}
public void dispose() {
myList.removeListSelectionListener(this);
super.dispose();
}
protected JComponent createCenterPanel() {
return JdkChooserPanel.this;
}
@NotNull
protected Action[] createActions() {
return new Action[]{new ConfigureAction(), getOKAction(), getCancelAction()};
}
public JComponent getPreferredFocusedComponent() {
return myList;
}
private final class ConfigureAction extends AbstractAction {
public ConfigureAction() {
super(IdeBundle.message("button.configure.e"));
putValue(Action.MNEMONIC_KEY, new Integer('E'));
}
public void actionPerformed(ActionEvent e) {
editJdkTable();
}
}
}
}