com.intellij.uiDesigner.clientProperties.ConfigureClientPropertiesDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.uiDesigner.clientProperties.ConfigureClientPropertiesDialog.java

Source

/*
 * Copyright 2000-2009 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.uiDesigner.clientProperties;

import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.ActionToolbarPosition;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.uiDesigner.UIDesignerBundle;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.util.*;

/**
 * @author yole
 */
public class ConfigureClientPropertiesDialog extends DialogWrapper {
    private JTree myClassTree;
    private JTable myPropertiesTable;
    private Class mySelectedClass;
    private ClientPropertiesManager.ClientProperty[] mySelectedProperties = new ClientPropertiesManager.ClientProperty[0];
    private final MyTableModel myTableModel = new MyTableModel();
    private final Project myProject;
    private final ClientPropertiesManager myManager;
    private Splitter mySplitter;
    final private PropertiesComponent myPropertiesComponent = PropertiesComponent.getInstance();
    final private static String SPLITTER_PROPORTION_PROPERTY = "ConfigureClientPropertiesDialog.splitterProportion";

    public ConfigureClientPropertiesDialog(final Project project) {
        super(project, true);
        myProject = project;
        setTitle(UIDesignerBundle.message("client.properties.title"));
        myManager = ClientPropertiesManager.getInstance(project).clone();
        init();
    }

    public void save() {
        ClientPropertiesManager.getInstance(myProject).saveFrom(myManager);
    }

    @Override
    public void dispose() {
        myPropertiesComponent.setValue(SPLITTER_PROPORTION_PROPERTY, String.valueOf(mySplitter.getProportion()));
        super.dispose();
    }

    private void updateSelectedProperties() {
        mySelectedProperties = myManager.getConfiguredProperties(mySelectedClass);
        myTableModel.fireTableDataChanged();
    }

    @Nullable
    protected JComponent createCenterPanel() {
        myClassTree = new Tree();
        myClassTree.setRootVisible(false);
        myClassTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent e) {
                final TreePath leadSelectionPath = e.getNewLeadSelectionPath();
                if (leadSelectionPath == null)
                    return;
                final DefaultMutableTreeNode node = (DefaultMutableTreeNode) leadSelectionPath
                        .getLastPathComponent();
                mySelectedClass = (Class) node.getUserObject();
                updateSelectedProperties();
            }
        });

        myClassTree.setCellRenderer(new ColoredTreeCellRenderer() {
            public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded,
                    boolean leaf, int row, boolean hasFocus) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                if (node.getUserObject() instanceof Class) {
                    Class cls = (Class) node.getUserObject();
                    if (cls != null) {
                        append(cls.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
                    }
                }
            }
        });
        fillClassTree();

        myPropertiesTable = new JBTable();
        myPropertiesTable.setModel(myTableModel);

        mySplitter = new Splitter(false,
                Float.valueOf(myPropertiesComponent.getValue(SPLITTER_PROPORTION_PROPERTY, "0.5f")));
        mySplitter.setFirstComponent(
                ToolbarDecorator.createDecorator(myClassTree).setAddAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        ClassNameInputDialog dlg = new ClassNameInputDialog(myProject, mySplitter);
                        dlg.show();
                        if (dlg.getExitCode() == OK_EXIT_CODE) {
                            String className = dlg.getClassName();
                            if (className.length() == 0)
                                return;
                            final Class aClass;
                            try {
                                aClass = Class.forName(className);
                            } catch (ClassNotFoundException ex) {
                                Messages.showErrorDialog(mySplitter,
                                        UIDesignerBundle.message("client.properties.class.not.found", className),
                                        UIDesignerBundle.message("client.properties.title"));
                                return;
                            }
                            if (!JComponent.class.isAssignableFrom(aClass)) {
                                Messages.showErrorDialog(
                                        mySplitter, UIDesignerBundle
                                                .message("client.properties.class.not.component", className),
                                        UIDesignerBundle.message("client.properties.title"));
                                return;
                            }
                            myManager.addClientPropertyClass(className);
                            fillClassTree();
                        }
                    }
                }).setRemoveAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        if (mySelectedClass != null) {
                            myManager.removeClientPropertyClass(mySelectedClass);
                            fillClassTree();
                        }
                    }
                }).setToolbarPosition(SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.RIGHT)
                        .createPanel());

        mySplitter.setSecondComponent(ToolbarDecorator.createDecorator(myPropertiesTable).disableUpDownActions()
                .setAddAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        AddClientPropertyDialog dlg = new AddClientPropertyDialog(myProject);
                        dlg.show();
                        if (dlg.getExitCode() == OK_EXIT_CODE) {
                            ClientPropertiesManager.ClientProperty[] props = myManager
                                    .getClientProperties(mySelectedClass);
                            for (ClientPropertiesManager.ClientProperty prop : props) {
                                if (prop.getName().equalsIgnoreCase(dlg.getEnteredProperty().getName())) {
                                    Messages.showErrorDialog(mySplitter,
                                            UIDesignerBundle.message("client.properties.already.defined",
                                                    prop.getName()),
                                            UIDesignerBundle.message("client.properties.title"));
                                    return;
                                }
                            }
                            myManager.addConfiguredProperty(mySelectedClass, dlg.getEnteredProperty());
                            updateSelectedProperties();
                        }
                    }
                }).setRemoveAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        int row = myPropertiesTable.getSelectedRow();
                        if (row >= 0 && row < mySelectedProperties.length) {
                            myManager.removeConfiguredProperty(mySelectedClass,
                                    mySelectedProperties[row].getName());
                            updateSelectedProperties();
                            if (mySelectedProperties.length > 0) {
                                if (row >= mySelectedProperties.length)
                                    row--;
                                myPropertiesTable.getSelectionModel().setSelectionInterval(row, row);
                            }
                        }
                    }
                }).createPanel());

        return mySplitter;
    }

    private void fillClassTree() {
        List<Class> configuredClasses = myManager.getConfiguredClasses();
        Collections.sort(configuredClasses, new Comparator<Class>() {
            public int compare(final Class o1, final Class o2) {
                return getInheritanceLevel(o1) - getInheritanceLevel(o2);
            }

            private int getInheritanceLevel(Class aClass) {
                int level = 0;
                while (aClass.getSuperclass() != null) {
                    level++;
                    aClass = aClass.getSuperclass();
                }
                return level;
            }
        });

        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
        DefaultTreeModel treeModel = new DefaultTreeModel(root);
        Map<Class, DefaultMutableTreeNode> classToNodeMap = new HashMap<Class, DefaultMutableTreeNode>();
        for (Class cls : configuredClasses) {
            DefaultMutableTreeNode parentNode = root;
            Class superClass = cls.getSuperclass();
            while (superClass != null) {
                if (classToNodeMap.containsKey(superClass)) {
                    parentNode = classToNodeMap.get(superClass);
                    break;
                }
                superClass = superClass.getSuperclass();
            }
            DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(cls);
            classToNodeMap.put(cls, childNode);
            parentNode.add(childNode);
        }
        myClassTree.setModel(treeModel);
        myClassTree.expandRow(0);
        myClassTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        myClassTree.getSelectionModel().setSelectionPath(new TreePath(new Object[] { root, root.getFirstChild() }));
    }

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

    private class MyTableModel extends AbstractTableModel {
        public int getRowCount() {
            return mySelectedProperties.length;
        }

        public int getColumnCount() {
            return 2;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 0:
                return mySelectedProperties[rowIndex].getName();
            default:
                return mySelectedProperties[rowIndex].getValueClass();
            }
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return UIDesignerBundle.message("client.properties.name");
            default:
                return UIDesignerBundle.message("client.properties.class");
            }
        }
    }
}