simplify API — TextBrowseFolderListener

JSDebug settings editor — file chooser must use the same logic as RC producer
This commit is contained in:
Vladimir Krivosheev
2013-09-13 15:46:26 +02:00
parent 8429da0dc7
commit b26f1f01a0
8 changed files with 101 additions and 49 deletions
@@ -16,12 +16,12 @@
package com.intellij.ide.util.projectWizard;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.BrowseFilesListener;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.ui.TextBrowseFolderListener;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
@@ -64,26 +64,17 @@ public class JavaSettingsStep extends SdkSettingsStep {
private void addSourcePath(SettingsStep settingsStep) {
Project project = settingsStep.getContext().getProject();
ComponentWithBrowseButton.BrowseFolderActionListener<JTextField> listener =
new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>(
IdeBundle.message("prompt.select.source.directory"), null, mySourcePath, project, BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT)
{
@Override
protected void onFileChoosen(VirtualFile chosenFile) {
String contentEntryPath = myModuleBuilder.getContentEntryPath();
String path = chosenFile.getPath();
if (contentEntryPath != null) {
int i = StringUtil.commonPrefixLength(contentEntryPath, path);
mySourcePath.setText(path.substring(i));
}
else {
mySourcePath.setText(path);
}
}
};
mySourcePath.addBrowseFolderListener(project, listener);
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
descriptor.setTitle(IdeBundle.message("prompt.select.source.directory"));
mySourcePath.addBrowseFolderListener(new TextBrowseFolderListener(descriptor, project) {
@NotNull
@Override
protected String chosenFileToResultingText(@NotNull VirtualFile chosenFile) {
String contentEntryPath = myModuleBuilder.getContentEntryPath();
String path = chosenFile.getPath();
return contentEntryPath == null ? path : path.substring(StringUtil.commonPrefixLength(contentEntryPath, path));
}
});
myCreateSourceRoot.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -255,6 +255,7 @@ public class FileChooserDescriptor implements Cloneable {
return this;
}
@Override
public final Object clone() {
try {
return super.clone();
@@ -42,6 +42,7 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.List;
@@ -84,6 +85,7 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
setPreferredSize(new Dimension(size.width + preferredSize.width + 2, SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel() ? preferredSize.height : preferredSize.height + 2));
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
myBrowseButton.setEnabled(enabled && myButtonEnabled);
@@ -129,9 +131,11 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
public void addBrowseFolderListener(@Nullable Project project, final BrowseFolderActionListener<Comp> actionListener, boolean autoRemoveOnHide) {
if (autoRemoveOnHide) {
new LazyUiDisposable<ComponentWithBrowseButton<Comp>>(null, this, this) {
@Override
protected void initialize(@NotNull Disposable parent, @NotNull ComponentWithBrowseButton<Comp> child, @Nullable Project project) {
addActionListener(actionListener);
Disposer.register(child, new Disposable() {
@Override
public void dispose() {
removeActionListener(actionListener);
}
@@ -143,6 +147,7 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
}
}
@Override
public void dispose() {
}
@@ -159,12 +164,13 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
myBrowseButton = browseButton;
}
@Override
public void actionPerformed(AnActionEvent e){
myBrowseButton.doClick();
}
public void registerShortcut(JComponent textField) {
ShortcutSet shiftEnter = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK));
ShortcutSet shiftEnter = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK));
registerCustomShortcutSet(shiftEnter, textField);
myBrowseButton.setToolTipText(KeymapUtil.getShortcutsText(shiftEnter.getShortcuts()));
}
@@ -177,10 +183,10 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
public static class BrowseFolderActionListener<T extends JComponent> implements ActionListener {
private final String myTitle;
private final String myDescription;
private final ComponentWithBrowseButton<T> myTextComponent;
protected ComponentWithBrowseButton<T> myTextComponent;
private final TextComponentAccessor<T> myAccessor;
private final Project myProject;
private final FileChooserDescriptor myFileChooserDescriptor;
protected final FileChooserDescriptor myFileChooserDescriptor;
public BrowseFolderActionListener(@Nullable String title, @Nullable String description, ComponentWithBrowseButton<T> textField, @Nullable Project project, FileChooserDescriptor fileChooserDescriptor, TextComponentAccessor<T> accessor) {
myTitle = title;
@@ -191,6 +197,7 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
myAccessor = accessor;
}
@Override
public void actionPerformed(ActionEvent e){
FileChooserDescriptor fileChooserDescriptor = (FileChooserDescriptor)myFileChooserDescriptor.clone();
if (myTitle != null) {
@@ -199,9 +206,8 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
if (myDescription != null) {
fileChooserDescriptor.setDescription(myDescription);
}
VirtualFile initialFile = getInitialFile();
FileChooser.chooseFiles(fileChooserDescriptor, myProject, initialFile, new Consumer<List<VirtualFile>>() {
FileChooser.chooseFiles(fileChooserDescriptor, myProject, getInitialFile(), new Consumer<List<VirtualFile>>() {
@Override
public void consume(List<VirtualFile> files) {
onFileChoosen(files.get(0));
@@ -212,7 +218,7 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
@Nullable
protected VirtualFile getInitialFile() {
String directoryName = getComponentText();
if (StringUtil.isEmptyOrSpaces(directoryName) || directoryName == null) {
if (StringUtil.isEmptyOrSpaces(directoryName)) {
return null;
}
@@ -231,22 +237,29 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
return myAccessor.getText(myTextComponent.getChildComponent()).trim();
}
protected void onFileChoosen(VirtualFile chosenFile) {
myAccessor.setText(myTextComponent.getChildComponent(), chosenFile.getPresentableUrl());
@NotNull
protected String chosenFileToResultingText(@NotNull VirtualFile chosenFile) {
return chosenFile.getPresentableUrl();
}
protected void onFileChoosen(@NotNull VirtualFile chosenFile) {
myAccessor.setText(myTextComponent.getChildComponent(), chosenFileToResultingText(chosenFile));
}
}
@Override
public final void requestFocus() {
myComponent.requestFocus();
}
@Override
public final void setNextFocusableComponent(Component aComponent) {
super.setNextFocusableComponent(aComponent);
myComponent.setNextFocusableComponent(aComponent);
}
private KeyEvent myCurrentEvent = null;
@Override
protected final boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if (condition == WHEN_FOCUSED && myCurrentEvent != e)
try {
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2013 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.ui;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class TextBrowseFolderListener extends ComponentWithBrowseButton.BrowseFolderActionListener<JTextField> {
public TextBrowseFolderListener(@NotNull FileChooserDescriptor fileChooserDescriptor) {
this(fileChooserDescriptor, null);
}
public TextBrowseFolderListener(@NotNull FileChooserDescriptor fileChooserDescriptor, @Nullable Project project) {
super(null, null, null, project, fileChooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
}
void setOwnerComponent(@NotNull TextFieldWithBrowseButton component) {
myTextComponent = component;
}
FileChooserDescriptor gFileChooserDescriptor() {
return myFileChooserDescriptor;
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.project.Project;
import com.intellij.ui.TextAccessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -53,6 +54,12 @@ public class TextFieldWithBrowseButton extends ComponentWithBrowseButton<JTextFi
installPathCompletion(fileChooserDescriptor);
}
public void addBrowseFolderListener(@NotNull TextBrowseFolderListener listener) {
listener.setOwnerComponent(this);
addBrowseFolderListener(null, listener, true);
installPathCompletion(listener.gFileChooserDescriptor());
}
protected void installPathCompletion(final FileChooserDescriptor fileChooserDescriptor) {
installPathCompletion(fileChooserDescriptor, null);
}
@@ -71,10 +78,12 @@ public class TextFieldWithBrowseButton extends ComponentWithBrowseButton<JTextFi
/**
* @return trimmed text
*/
@Override
public String getText(){
return getTextField().getText();
}
@Override
public void setText(final String text){
getTextField().setText(text);
}
@@ -106,6 +115,7 @@ public class TextFieldWithBrowseButton extends ComponentWithBrowseButton<JTextFi
super(browseActionListener);
}
@Override
protected void installPathCompletion(final FileChooserDescriptor fileChooserDescriptor) {
}
}
@@ -63,7 +63,8 @@ public class LocationNameFieldsBinding {
project,
descriptor,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
protected void onFileChoosen(VirtualFile chosenFile) {
@Override
protected void onFileChoosen(@NotNull VirtualFile chosenFile) {
myBaseDir = chosenFile.getPath();
if (isProjectNameChanged(nameTextField.getText()) && !nameTextField.getText().equals(chosenFile.getName())) {
myExternalModify = true;
@@ -115,6 +116,7 @@ public class LocationNameFieldsBinding {
private class NameFieldDocument extends PlainDocument {
public NameFieldDocument(final JTextField projectNameTextField, final TextFieldWithBrowseButton locationField) {
addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(final DocumentEvent e) {
if (!myModifyingLocation && !myExternalModify) {
myModifyingProjectName = true;
@@ -125,6 +127,7 @@ public class LocationNameFieldsBinding {
});
}
@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
boolean ok = true;
for (int idx = 0; idx < str.length() && ok; idx++) {
@@ -198,7 +198,7 @@ public class VcsMappingConfigurationDialog extends DialogWrapper {
}
@Override
protected void onFileChoosen(final VirtualFile chosenFile) {
protected void onFileChoosen(@NotNull final VirtualFile chosenFile) {
String oldText = myDirectoryTextField.getText();
super.onFileChoosen(chosenFile);
final VcsDescriptor wrapper = (VcsDescriptor) myVCSComboBox.getSelectedItem();
@@ -3,7 +3,6 @@ package com.intellij.ide.browsers;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.io.URLUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,23 +65,17 @@ public final class UrlImpl implements Url {
@Override
public String toDecodedForm(boolean skipQueryAndFragment) {
StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(scheme).append("://");
if (authority != null) {
builder.append(authority);
}
if (path != null) {
builder.append(getPath());
}
if (!skipQueryAndFragment && parameters != null) {
builder.append(parameters);
}
return builder.toString();
StringBuilder builder = new StringBuilder().append(scheme).append("://");
if (authority != null) {
builder.append(authority);
}
finally {
StringBuilderSpinAllocator.dispose(builder);
if (path != null) {
builder.append(getPath());
}
if (!skipQueryAndFragment && parameters != null) {
builder.append(parameters);
}
return builder.toString();
}
@Override