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.
16 package com
.intellij
.uiDesigner
.propertyInspector
;
18 import com
.intellij
.openapi
.project
.Project
;
19 import com
.intellij
.openapi
.ui
.ex
.MultiLineLabel
;
20 import com
.intellij
.openapi
.util
.Comparing
;
21 import com
.intellij
.ui
.ScrollPaneFactory
;
22 import com
.intellij
.uiDesigner
.radComponents
.*;
23 import com
.intellij
.uiDesigner
.UIDesignerBundle
;
24 import com
.intellij
.uiDesigner
.componentTree
.ComponentSelectionListener
;
25 import com
.intellij
.uiDesigner
.componentTree
.ComponentTree
;
26 import com
.intellij
.uiDesigner
.designSurface
.GuiEditor
;
27 import com
.intellij
.uiDesigner
.designSurface
.GridCaptionPanel
;
28 import com
.intellij
.uiDesigner
.quickFixes
.QuickFixManager
;import com
.intellij
.util
.IJSwingUtilities
;
29 import org
.jetbrains
.annotations
.NotNull
;
30 import org
.jetbrains
.annotations
.NonNls
;
32 import javax
.swing
.*;import javax
.swing
.event
.ChangeListener
;import javax
.swing
.event
.ChangeEvent
;
33 import java
.awt
.event
.ActionEvent
;
34 import java
.awt
.event
.ActionListener
;
36 import java
.util
.List
;
39 * @author Anton Katilin
40 * @author Vladimir Kondratyev
42 public final class PropertyInspector
extends JPanel
{
43 private final PropertyInspectorTable myInspectorTable
;
44 private final ComponentTree myComponentTree
;
45 private final QuickFixManager myQuickFixManager
;
46 private GuiEditor myEditor
;
47 private final PropertyInspector
.MyComponentSelectionListener myComponentSelectionListener
;
48 @NonNls private static final String INSPECTOR_CARD
= "inspector";
49 @NonNls private static final String EMPTY_CARD
= "empty";
50 @NonNls private static final String CUSTOM_CARD
= "column";
51 private final JScrollPane myCustomPropertiesScrollPane
= new JScrollPane();
52 private CustomPropertiesPanel myCustomPropertiesPanel
;
53 private final ChangeListener myCustomPropertiesChangeListener
;
54 private RadContainer myPropertiesPanelContainer
;
56 public PropertyInspector(Project project
, @NotNull final ComponentTree componentTree
) {
57 super(new CardLayout());
59 myInspectorTable
= new PropertyInspectorTable(project
, componentTree
);
60 myComponentTree
= componentTree
;
62 // Card with property inspector
63 final JPanel inspectorCard
= new JPanel(new GridBagLayout());
64 final JScrollPane inspectorScrollPane
= ScrollPaneFactory
.createScrollPane(myInspectorTable
);
65 inspectorCard
.add(inspectorScrollPane
,
66 new GridBagConstraints(0, 0, 0, 1, 1, 1, GridBagConstraints
.CENTER
, GridBagConstraints
.BOTH
, new Insets(0, 0, 0, 0), 0, 0)
68 final JCheckBox chkShowExpertProperties
= new JCheckBox(UIDesignerBundle
.message("chk.show.expert.properties"));
70 chkShowExpertProperties
,
71 new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints
.WEST
, GridBagConstraints
.NONE
, new Insets(0, 0, 0, 0), 0, 0)
73 chkShowExpertProperties
.addActionListener(
74 new ActionListener() {
75 public void actionPerformed(final ActionEvent e
) {
76 myInspectorTable
.setShowExpertProperties(chkShowExpertProperties
.isSelected());
80 add(inspectorCard
, INSPECTOR_CARD
);
83 final MultiLineLabel label
= new MultiLineLabel(UIDesignerBundle
.message("label.select.single.component.to.edit.its.properties")){
84 public void updateUI() {
86 setBackground(myInspectorTable
.getBackground());
89 label
.setOpaque(true);
90 label
.setHorizontalAlignment(SwingConstants
.CENTER
);
91 add(label
, EMPTY_CARD
);
92 add(myCustomPropertiesScrollPane
, CUSTOM_CARD
);
94 myComponentSelectionListener
= new MyComponentSelectionListener();
98 myQuickFixManager
= new QuickFixManagerImpl(null, myInspectorTable
, inspectorScrollPane
.getViewport());
100 myCustomPropertiesChangeListener
= new ChangeListener() {
101 public void stateChanged(ChangeEvent e
) {
102 if (myPropertiesPanelContainer
!= null) {
103 myPropertiesPanelContainer
.revalidate();
105 if (myEditor
.ensureEditable()) {
106 myEditor
.refreshAndSave(true);
112 public void setEditor(final GuiEditor editor
) {
113 if (myEditor
!= editor
) {
114 if (myEditor
!= null) {
115 myEditor
.removeComponentSelectionListener(myComponentSelectionListener
);
118 myInspectorTable
.setEditor(myEditor
);
119 myQuickFixManager
.setEditor(myEditor
);
120 if (myEditor
!= null) {
121 myEditor
.addComponentSelectionListener(myComponentSelectionListener
);
124 if (myCustomPropertiesPanel
!= null) {
125 myCustomPropertiesPanel
.removeChangeListener(myCustomPropertiesChangeListener
);
131 public void refreshIntentionHint() {
132 myQuickFixManager
.refreshIntentionHint();
135 public void synchWithTree(final boolean forceSynch
) {
136 final CardLayout cardLayout
= (CardLayout
)getLayout();
137 if (!showSelectedColumnProperties()) {
138 final RadComponent
[] selectedComponents
= myComponentTree
.getSelectedComponents();
139 if(selectedComponents
.length
>= 1){
140 cardLayout
.show(this, INSPECTOR_CARD
);
141 myInspectorTable
.synchWithTree(forceSynch
);
144 List
<RadButtonGroup
> buttonGroups
= myComponentTree
.getSelectedElements(RadButtonGroup
.class);
145 if (buttonGroups
.size() > 0) {
146 showButtonGroupProperties(buttonGroups
.get(0));
149 cardLayout
.show(this, EMPTY_CARD
);
155 private void showButtonGroupProperties(final RadButtonGroup group
) {
156 ButtonGroupPropertiesPanel props
= new ButtonGroupPropertiesPanel(myEditor
.getRootContainer(), group
);
157 myPropertiesPanelContainer
= null;
158 showCustomPropertiesPanel(props
);
161 private boolean showSelectedColumnProperties() {
162 if (myCustomPropertiesPanel
!= null && myPropertiesPanelContainer
!= null &&
163 IJSwingUtilities
.hasFocus(myCustomPropertiesPanel
.getComponent())) {
166 if (myEditor
== null) return false;
167 GridCaptionPanel panel
= myEditor
.getFocusedCaptionPanel();
168 if (panel
== null) return false;
169 RadContainer container
= panel
.getSelectedContainer();
170 if (container
== null) return false;
171 final int[] selection
= panel
.getSelectedCells(null);
172 myPropertiesPanelContainer
= container
;
173 final CustomPropertiesPanel propertiesPanel
= container
.getGridLayoutManager().getRowColumnPropertiesPanel(container
, panel
.isRow(), selection
);
174 if (propertiesPanel
== null) return false;
175 showCustomPropertiesPanel(propertiesPanel
);
179 private void showCustomPropertiesPanel(final CustomPropertiesPanel propertiesPanel
) {
180 if (!Comparing
.equal(propertiesPanel
, myCustomPropertiesPanel
)) {
181 if (myCustomPropertiesPanel
!= null) {
182 myCustomPropertiesPanel
.removeChangeListener(myCustomPropertiesChangeListener
);
184 myCustomPropertiesPanel
= propertiesPanel
;
185 myCustomPropertiesPanel
.addChangeListener(myCustomPropertiesChangeListener
);
186 myCustomPropertiesScrollPane
.getViewport().setView(myCustomPropertiesPanel
.getComponent());
188 final CardLayout cardLayout
= (CardLayout
)getLayout();
189 cardLayout
.show(this, CUSTOM_CARD
);
192 public boolean isEditing(){
193 return myInspectorTable
.isEditing();
196 public void stopEditing(){
197 myInspectorTable
.editingStopped(null);
200 public void requestFocus() {
201 myInspectorTable
.requestFocus();
205 * Synchronizes state with component which is selected in the ComponentTree
207 private final class MyComponentSelectionListener
implements ComponentSelectionListener
{
208 public void selectedComponentChanged(final GuiEditor source
){
209 synchWithTree(false);