2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com
.intellij
.uiDesigner
.clientProperties
;
19 import com
.intellij
.openapi
.actionSystem
.*;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.ui
.DialogWrapper
;
22 import com
.intellij
.openapi
.ui
.Messages
;
23 import com
.intellij
.openapi
.util
.DimensionService
;
24 import com
.intellij
.openapi
.util
.IconLoader
;
25 import com
.intellij
.ui
.ColoredTreeCellRenderer
;
26 import com
.intellij
.ui
.SimpleTextAttributes
;
27 import com
.intellij
.uiDesigner
.UIDesignerBundle
;
28 import org
.jetbrains
.annotations
.NonNls
;
29 import org
.jetbrains
.annotations
.Nullable
;
32 import javax
.swing
.event
.TreeSelectionEvent
;
33 import javax
.swing
.event
.TreeSelectionListener
;
34 import javax
.swing
.table
.AbstractTableModel
;
35 import javax
.swing
.tree
.DefaultMutableTreeNode
;
36 import javax
.swing
.tree
.DefaultTreeModel
;
37 import javax
.swing
.tree
.TreePath
;
38 import javax
.swing
.tree
.TreeSelectionModel
;
39 import java
.awt
.BorderLayout
;
45 public class ConfigureClientPropertiesDialog
extends DialogWrapper
{
46 private JPanel myRootPanel
;
47 private JTree myClassTree
;
48 private JTable myPropertiesTable
;
49 private JSplitPane mySplitPane
;
50 private JPanel myClassToolBarPanel
;
51 private JPanel myPropertyToolBarPanel
;
52 private Class mySelectedClass
;
53 private ClientPropertiesManager
.ClientProperty
[] mySelectedProperties
= new ClientPropertiesManager
.ClientProperty
[0];
54 private final MyTableModel myTableModel
= new MyTableModel();
55 private final Project myProject
;
56 private final ClientPropertiesManager myManager
;
58 public ConfigureClientPropertiesDialog(final Project project
) {
62 setTitle(UIDesignerBundle
.message("client.properties.title"));
63 myManager
= ClientPropertiesManager
.getInstance(project
).clone();
65 myClassTree
.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
66 public void valueChanged(TreeSelectionEvent e
) {
67 final TreePath leadSelectionPath
= e
.getNewLeadSelectionPath();
68 if (leadSelectionPath
== null) return;
69 final DefaultMutableTreeNode node
= (DefaultMutableTreeNode
) leadSelectionPath
.getLastPathComponent();
70 mySelectedClass
= (Class
) node
.getUserObject();
71 updateSelectedProperties();
75 myClassTree
.setCellRenderer(new ColoredTreeCellRenderer() {
76 public void customizeCellRenderer(JTree tree
, Object value
, boolean selected
, boolean expanded
, boolean leaf
, int row
, boolean hasFocus
) {
77 DefaultMutableTreeNode node
= (DefaultMutableTreeNode
) value
;
78 if (node
.getUserObject() instanceof Class
) {
79 Class cls
= (Class
) node
.getUserObject();
81 append(cls
.getName(), SimpleTextAttributes
.REGULAR_ATTRIBUTES
);
87 createToolBar(new AddClassAction(), new RemoveClassAction(), myClassToolBarPanel
, myClassTree
);
88 createToolBar(new AddPropertyAction(), new RemovePropertyAction(), myPropertyToolBarPanel
, myPropertiesTable
);
90 myPropertiesTable
.setModel(myTableModel
);
92 final int location
= DimensionService
.getInstance().getExtendedState(getDimensionKey());
94 mySplitPane
.setDividerLocation(location
);
100 private static void createToolBar(final AnAction addAction
,
101 final AnAction removeAction
,
103 final JComponent shortcutHost
) {
104 DefaultActionGroup group
= new DefaultActionGroup();
105 group
.add(addAction
);
106 group
.add(removeAction
);
107 ActionToolbar toolBar
= ActionManager
.getInstance().createActionToolbar(ActionPlaces
.UNKNOWN
, group
, true);
108 panel
.add(toolBar
.getComponent(), BorderLayout
.CENTER
);
109 addAction
.registerCustomShortcutSet(CommonShortcuts
.INSERT
, shortcutHost
);
110 removeAction
.registerCustomShortcutSet(CommonShortcuts
.DELETE
, shortcutHost
);
114 ClientPropertiesManager
.getInstance(myProject
).saveFrom(myManager
);
118 public void dispose() {
119 DimensionService
.getInstance().setExtendedState(getDimensionKey(), mySplitPane
.getDividerLocation());
123 private void fillClassTree() {
124 List
<Class
> configuredClasses
= myManager
.getConfiguredClasses();
125 Collections
.sort(configuredClasses
, new Comparator
<Class
>() {
126 public int compare(final Class o1
, final Class o2
) {
127 return getInheritanceLevel(o1
) - getInheritanceLevel(o2
);
130 private int getInheritanceLevel(Class aClass
) {
132 while(aClass
.getSuperclass() != null) {
134 aClass
= aClass
.getSuperclass();
140 DefaultMutableTreeNode root
= new DefaultMutableTreeNode();
141 DefaultTreeModel treeModel
= new DefaultTreeModel(root
);
142 Map
<Class
, DefaultMutableTreeNode
> classToNodeMap
= new HashMap
<Class
, DefaultMutableTreeNode
>();
143 for(Class cls
: configuredClasses
) {
144 DefaultMutableTreeNode parentNode
= root
;
145 Class superClass
= cls
.getSuperclass();
146 while(superClass
!= null) {
147 if (classToNodeMap
.containsKey(superClass
)) {
148 parentNode
= classToNodeMap
.get(superClass
);
151 superClass
= superClass
.getSuperclass();
153 DefaultMutableTreeNode childNode
= new DefaultMutableTreeNode(cls
);
154 classToNodeMap
.put(cls
, childNode
);
155 parentNode
.add(childNode
);
157 myClassTree
.setModel(treeModel
);
158 myClassTree
.expandRow(0);
159 myClassTree
.getSelectionModel().setSelectionMode(TreeSelectionModel
.SINGLE_TREE_SELECTION
);
160 myClassTree
.getSelectionModel().setSelectionPath(new TreePath(new Object
[] { root
, root
.getFirstChild() }));
163 private void updateSelectedProperties() {
164 mySelectedProperties
= myManager
.getConfiguredProperties(mySelectedClass
);
165 myTableModel
.fireTableDataChanged();
169 protected JComponent
createCenterPanel() {
174 protected String
getDimensionServiceKey() {
175 return "ConfigureClientPropertiesDialog";
178 private class MyTableModel
extends AbstractTableModel
{
179 public int getRowCount() {
180 return mySelectedProperties
.length
;
183 public int getColumnCount() {
187 public Object
getValueAt(int rowIndex
, int columnIndex
) {
188 switch(columnIndex
) {
189 case 0: return mySelectedProperties
[rowIndex
].getName();
190 default: return mySelectedProperties
[rowIndex
].getValueClass();
195 public String
getColumnName(int column
) {
197 case 0: return UIDesignerBundle
.message("client.properties.name");
198 default: return UIDesignerBundle
.message("client.properties.class");
203 private class AddClassAction
extends AnAction
{
204 public AddClassAction() {
205 super(UIDesignerBundle
.message("client.properties.add.class.tooltip"), "", IconLoader
.getIcon("/general/add.png"));
208 public void actionPerformed(AnActionEvent e
) {
209 ClassNameInputDialog dlg
= new ClassNameInputDialog(myProject
, myRootPanel
);
211 if (dlg
.getExitCode() == OK_EXIT_CODE
) {
212 String className
= dlg
.getClassName();
213 if (className
.length() == 0) return;
216 aClass
= Class
.forName(className
);
218 catch(ClassNotFoundException ex
) {
219 Messages
.showErrorDialog(myRootPanel
,
220 UIDesignerBundle
.message("client.properties.class.not.found", className
),
221 UIDesignerBundle
.message("client.properties.title"));
224 if (!JComponent
.class.isAssignableFrom(aClass
)) {
225 Messages
.showErrorDialog(myRootPanel
,
226 UIDesignerBundle
.message("client.properties.class.not.component", className
),
227 UIDesignerBundle
.message("client.properties.title"));
230 myManager
.addClientPropertyClass(className
);
236 private class RemoveClassAction
extends AnAction
{
237 public RemoveClassAction() {
238 super(UIDesignerBundle
.message("client.properties.remove.class.tooltip"), "", IconLoader
.getIcon("/general/remove.png"));
241 public void actionPerformed(AnActionEvent e
) {
242 if (mySelectedClass
!= null) {
243 myManager
.removeClientPropertyClass(mySelectedClass
);
249 private class AddPropertyAction
extends AnAction
{
250 public AddPropertyAction() {
251 super(UIDesignerBundle
.message("client.properties.add.property.tooltip"), "", IconLoader
.getIcon("/general/add.png"));
254 public void actionPerformed(AnActionEvent e
) {
255 AddClientPropertyDialog dlg
= new AddClientPropertyDialog(myProject
);
257 if (dlg
.getExitCode() == OK_EXIT_CODE
) {
258 ClientPropertiesManager
.ClientProperty
[] props
= myManager
.getClientProperties(mySelectedClass
);
259 for(ClientPropertiesManager
.ClientProperty prop
: props
) {
260 if (prop
.getName().equalsIgnoreCase(dlg
.getEnteredProperty().getName())) {
261 Messages
.showErrorDialog(myRootPanel
,
262 UIDesignerBundle
.message("client.properties.already.defined", prop
.getName()),
263 UIDesignerBundle
.message("client.properties.title"));
267 myManager
.addConfiguredProperty(mySelectedClass
, dlg
.getEnteredProperty());
268 updateSelectedProperties();
273 private class RemovePropertyAction
extends AnAction
{
274 public RemovePropertyAction() {
275 super(UIDesignerBundle
.message("client.properties.remove.property.tooltip"), "", IconLoader
.getIcon("/general/remove.png"));
278 public void actionPerformed(AnActionEvent e
) {
279 int row
= myPropertiesTable
.getSelectedRow();
280 if (row
>= 0 && row
< mySelectedProperties
.length
) {
281 myManager
.removeConfiguredProperty(mySelectedClass
, mySelectedProperties
[row
].getName());
282 updateSelectedProperties();
283 if (mySelectedProperties
.length
> 0) {
284 if (row
>= mySelectedProperties
.length
) row
--;
285 myPropertiesTable
.getSelectionModel().setSelectionInterval(row
, row
);
290 public void update(AnActionEvent e
) {
291 e
.getPresentation().setEnabled(myPropertiesTable
.getSelectedRow() >= 0);