com.google.idea.blaze.android.resources.actions.BlazeCreateResourceDirectoryDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.google.idea.blaze.android.resources.actions.BlazeCreateResourceDirectoryDialog.java

Source

/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.blaze.android.resources.actions;

import com.android.resources.ResourceFolderType;
import com.intellij.CommonBundle;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.EnumComboBoxModel;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.components.JBLabel;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Insets;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jetbrains.android.actions.CreateResourceDirectoryDialogBase;
import org.jetbrains.android.actions.ElementCreatingValidator;
import org.jetbrains.android.uipreview.DeviceConfiguratorPanel;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Dialog to decide where to create a res/ subdirectory (e.g., layout/, values-foo/, etc.) and how
 * to name the subdirectory based on resource type and chosen configuration.
 */
public class BlazeCreateResourceDirectoryDialog extends CreateResourceDirectoryDialogBase {

    private JComboBox myResourceTypeComboBox;
    private JPanel myDeviceConfiguratorWrapper;
    private JTextField myDirectoryNameTextField;
    private JPanel myContentPanel;
    private JBLabel myErrorLabel;
    private ComboboxWithBrowseButton myResDirCombo;
    private JBLabel myResDirLabel;

    private final DeviceConfiguratorPanel myDeviceConfiguratorPanel;
    private ElementCreatingValidator myValidator;
    private ValidatorFactory myValidatorFactory;
    private PsiDirectory myResDirectory;
    private DataContext myDataContext;

    public BlazeCreateResourceDirectoryDialog(Project project, @Nullable Module module,
            @Nullable ResourceFolderType resType, @Nullable PsiDirectory resDirectory,
            @Nullable DataContext dataContext, ValidatorFactory validatorFactory) {
        super(project);
        setupUi();
        myResDirectory = resDirectory;
        myDataContext = dataContext;
        myValidatorFactory = validatorFactory;
        myResourceTypeComboBox.setModel(new EnumComboBoxModel<>(ResourceFolderType.class));
        myResourceTypeComboBox.setRenderer(new ListCellRendererWrapper() {
            @Override
            public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
                if (value instanceof ResourceFolderType) {
                    setText(((ResourceFolderType) value).getName());
                }
            }
        });

        myDeviceConfiguratorPanel = setupDeviceConfigurationPanel(myResourceTypeComboBox, myDirectoryNameTextField,
                myErrorLabel);
        myDeviceConfiguratorWrapper.add(myDeviceConfiguratorPanel, BorderLayout.CENTER);
        myResourceTypeComboBox.addActionListener(e -> myDeviceConfiguratorPanel.applyEditors());

        if (resType != null) {
            myResourceTypeComboBox.setSelectedItem(resType);
            myResourceTypeComboBox.setEnabled(false);
        } else {
            // Select values by default if not otherwise specified
            myResourceTypeComboBox.setSelectedItem(ResourceFolderType.VALUES);
        }

        // If myResDirectory is known before this, just use that.
        myResDirLabel.setVisible(false);
        myResDirCombo.setVisible(false);
        myResDirCombo.addBrowseFolderListener(project, FileChooserDescriptorFactory.createSingleFolderDescriptor());
        if (myResDirectory == null) {
            assert dataContext != null;
            assert module != null;
            // Try to figure out from context (e.g., right click in project view).
            VirtualFile contextFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
            if (contextFile != null) {
                PsiManager manager = PsiManager.getInstance(project);
                VirtualFile virtualDirectory = BlazeCreateResourceUtils.getResDirFromDataContext(contextFile);
                PsiDirectory directory = virtualDirectory != null ? manager.findDirectory(virtualDirectory) : null;
                if (directory != null) {
                    myResDirectory = directory;
                } else {
                    // As a last resort, if we have poor context
                    // e.g., from File > New w/ a .java file open, set up the UI.
                    BlazeCreateResourceUtils.setupResDirectoryChoices(module.getProject(), contextFile,
                            myResDirLabel, myResDirCombo);
                }
            }
        }

        myDeviceConfiguratorPanel.updateAll();
        setOKActionEnabled(myDirectoryNameTextField.getText().length() > 0);
        init();
    }

    @Override
    protected void doOKAction() {
        final String dirName = myDirectoryNameTextField.getText();
        assert dirName != null;
        PsiDirectory resourceDirectory = getResourceDirectory();
        if (resourceDirectory == null) {
            Module module = LangDataKeys.MODULE.getData(myDataContext);
            Messages.showErrorDialog(AndroidBundle.message("check.resource.dir.error", module),
                    CommonBundle.getErrorTitle());
            // Not much the user can do, just close the dialog.
            super.doOKAction();
            return;
        }
        myValidator = myValidatorFactory.create(resourceDirectory);
        if (myValidator.checkInput(dirName) && myValidator.canClose(dirName)) {
            super.doOKAction();
        }
    }

    @Override
    protected String getDimensionServiceKey() {
        return "BlazeCreateResourceDirectoryDialog";
    }

    @Override
    public JComponent getPreferredFocusedComponent() {
        if (myResourceTypeComboBox.isEnabled()) {
            return myResourceTypeComboBox;
        } else {
            return myDirectoryNameTextField;
        }
    }

    @Override
    @NotNull
    public PsiElement[] getCreatedElements() {
        return myValidator != null ? myValidator.getCreatedElements() : PsiElement.EMPTY_ARRAY;
    }

    @Nullable
    private PsiDirectory getResourceDirectory() {
        if (myResDirectory != null) {
            return myResDirectory;
        }
        if (myResDirCombo.isVisible()) {
            Module contextModule = LangDataKeys.MODULE.getData(myDataContext);
            assert contextModule != null;
            return BlazeCreateResourceUtils.getResDirFromUI(contextModule.getProject(), myResDirCombo);
        }
        return null;
    }

    @Nullable
    @Override
    protected JComponent createCenterPanel() {
        return myContentPanel;
    }

    /** Initially generated by IntelliJ from a .form file. */
    private void setupUi() {
        myContentPanel = new JPanel();
        myContentPanel.setLayout(new GridLayoutManager(5, 2, new Insets(0, 0, 0, 0), -1, -1));
        myContentPanel.setPreferredSize(new Dimension(800, 400));
        myResourceTypeComboBox = new JComboBox();
        myContentPanel.add(myResourceTypeComboBox,
                new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
                        GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0,
                        false));
        final JBLabel jBLabel1 = new JBLabel();
        jBLabel1.setText("Resource type:");
        jBLabel1.setDisplayedMnemonic('R');
        jBLabel1.setDisplayedMnemonicIndex(0);
        myContentPanel.add(jBLabel1,
                new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0,
                        false));
        myDeviceConfiguratorWrapper = new JPanel();
        myDeviceConfiguratorWrapper.setLayout(new BorderLayout(0, 0));
        myContentPanel.add(myDeviceConfiguratorWrapper,
                new GridConstraints(3, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null,
                        null, 0, false));
        final JLabel label1 = new JLabel();
        label1.setText("Directory name:");
        label1.setDisplayedMnemonic('D');
        label1.setDisplayedMnemonicIndex(0);
        myContentPanel.add(label1,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0,
                        false));
        myDirectoryNameTextField = new JTextField();
        myDirectoryNameTextField.setEnabled(true);
        myContentPanel.add(myDirectoryNameTextField,
                new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
                        GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
                        new Dimension(150, -1), null, 0, false));
        myErrorLabel = new JBLabel();
        myContentPanel.add(myErrorLabel,
                new GridConstraints(4, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0,
                        false));
        myResDirLabel = new JBLabel();
        myResDirLabel.setText("Base directory:");
        myResDirLabel.setDisplayedMnemonic('B');
        myResDirLabel.setDisplayedMnemonicIndex(0);
        myContentPanel.add(myResDirLabel,
                new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0,
                        false));
        myResDirCombo = new ComboboxWithBrowseButton();
        myContentPanel.add(myResDirCombo,
                new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
                        GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0,
                        false));
        jBLabel1.setLabelFor(myResourceTypeComboBox);
        label1.setLabelFor(myDirectoryNameTextField);
        myResDirLabel.setLabelFor(myResourceTypeComboBox);
    }
}