1f35f82874dc89c3046f1b56fa28f393f7ab1dd6
[idea/community.git] / java / idea-ui / src / com / intellij / facet / impl / ui / FacetEditorImpl.java
1 /*
2  * Copyright 2000-2017 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.facet.impl.ui;
17
18 import com.intellij.facet.Facet;
19 import com.intellij.facet.FacetConfiguration;
20 import com.intellij.facet.ui.*;
21 import com.intellij.openapi.Disposable;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.options.Configurable;
24 import com.intellij.openapi.options.UnnamedConfigurable;
25 import com.intellij.openapi.options.UnnamedConfigurableGroup;
26 import com.intellij.openapi.roots.ProjectModelExternalSource;
27 import com.intellij.openapi.roots.ui.configuration.ModificationOfImportedModelWarningComponent;
28 import com.intellij.openapi.util.Disposer;
29 import com.intellij.openapi.wm.IdeFocusManager;
30 import com.intellij.ui.TabbedPaneWrapper;
31 import com.intellij.util.ui.JBUI;
32 import com.intellij.util.ui.UIUtil;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35
36 import javax.swing.*;
37 import javax.swing.event.ChangeEvent;
38 import javax.swing.event.ChangeListener;
39 import java.awt.*;
40 import java.util.HashSet;
41 import java.util.Set;
42
43 public class FacetEditorImpl extends UnnamedConfigurableGroup implements UnnamedConfigurable, FacetEditor {
44   private final FacetEditorTab[] myEditorTabs;
45   private final FacetErrorPanel myErrorPanel;
46   private JComponent myComponent;
47   private @Nullable TabbedPaneWrapper myTabbedPane;
48   private final FacetEditorContext myContext;
49   private final Set<FacetEditorTab> myVisitedTabs = new HashSet<>();
50   private int mySelectedTabIndex = 0;
51   private final Disposable myDisposable = Disposer.newDisposable();
52
53   public FacetEditorImpl(final FacetEditorContext context, final FacetConfiguration configuration) {
54     myContext = context;
55     myErrorPanel = new FacetErrorPanel();
56     myEditorTabs = configuration.createEditorTabs(context, myErrorPanel.getValidatorsManager());
57     for (Configurable configurable : myEditorTabs) {
58       add(configurable);
59     }
60   }
61
62   @Override
63   public void reset() {
64     super.reset();
65     myErrorPanel.getValidatorsManager().validate();
66   }
67
68   public JComponent getComponent() {
69     if (myComponent == null) {
70       myComponent = createComponent();
71     }
72     return myComponent;
73   }
74
75   @Override
76   public JComponent createComponent() {
77     final JComponent editorComponent;
78     if (myEditorTabs.length > 1) {
79       final TabbedPaneWrapper tabbedPane = new TabbedPaneWrapper(myDisposable);
80       for (FacetEditorTab editorTab : myEditorTabs) {
81         JComponent c = editorTab.createComponent();
82         UIUtil.addInsets(c, UIUtil.PANEL_SMALL_INSETS);
83         tabbedPane.addTab(editorTab.getDisplayName(), c);
84       }
85       tabbedPane.addChangeListener(new ChangeListener() {
86         @Override
87         public void stateChanged(@NotNull ChangeEvent e) {
88           myEditorTabs[mySelectedTabIndex].onTabLeaving();
89           mySelectedTabIndex = tabbedPane.getSelectedIndex();
90           onTabSelected(myEditorTabs[mySelectedTabIndex]);
91         }
92       });
93       editorComponent = tabbedPane.getComponent();
94       myTabbedPane = tabbedPane;
95     }
96     else if (myEditorTabs.length == 1) {
97       editorComponent = myEditorTabs[0].createComponent();
98       UIUtil.addInsets(editorComponent, JBUI.insets(0, 5, 0, 0));
99     }
100     else {
101       editorComponent = new JPanel();
102     }
103     ProjectModelExternalSource externalSource = myContext.getFacet().getExternalSource();
104     if (externalSource != null) {
105       myErrorPanel.getValidatorsManager().registerValidator(new FacetEditorValidator() {
106         @NotNull
107         @Override
108         public ValidationResult check() {
109           if (isModified()) {
110             String text = ModificationOfImportedModelWarningComponent.getWarningText("Facet '" + myContext.getFacetName() + "'", externalSource);
111             return new ValidationResult(text);
112           }
113           return ValidationResult.OK;
114         }
115       }, editorComponent);
116     }
117
118
119     final JComponent errorComponent = myErrorPanel.getComponent();
120     UIUtil.addInsets(errorComponent, JBUI.insets(0, 5, 5, 0));
121
122     final JPanel panel = new JPanel(new BorderLayout());
123     panel.add(BorderLayout.CENTER, editorComponent);
124     panel.add(BorderLayout.SOUTH, errorComponent);
125     return panel;
126   }
127
128   private void onTabSelected(final FacetEditorTab selectedTab) {
129     selectedTab.onTabEntering();
130     if (myVisitedTabs.add(selectedTab)) {
131       final JComponent preferredFocusedComponent = selectedTab.getPreferredFocusedComponent();
132       if (preferredFocusedComponent != null) {
133         ApplicationManager.getApplication().invokeLater(() -> {
134           if (preferredFocusedComponent.isShowing()) {
135             IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus(preferredFocusedComponent, true));
136           }
137         });
138       }
139     }
140   }
141
142   @Override
143   public void disposeUIResources() {
144     Disposer.dispose(myDisposable);
145     myErrorPanel.disposeUIResources();
146     super.disposeUIResources();
147   }
148
149   @Nullable
150   public String getHelpTopic() {
151     return 0 <= mySelectedTabIndex && mySelectedTabIndex < myEditorTabs.length ? myEditorTabs[mySelectedTabIndex].getHelpTopic() : null;
152   }
153
154   public void onFacetAdded(@NotNull Facet facet) {
155     for (FacetEditorTab editorTab : myEditorTabs) {
156       editorTab.onFacetInitialized(facet);
157     }
158   }
159
160   public void setSelectedTabName(final String tabName) {
161     getComponent();
162     final TabbedPaneWrapper tabbedPane = myTabbedPane;
163     if (tabbedPane == null) return;
164     for (int i = 0; i < tabbedPane.getTabCount(); i++) {
165       if (tabName.equals(tabbedPane.getTitleAt(i))) {
166         tabbedPane.setSelectedIndex(i);
167         return;
168       }
169     }
170   }
171
172   public FacetEditorContext getContext() {
173     return myContext;
174   }
175
176   public void onFacetSelected() {
177     if (mySelectedTabIndex < myEditorTabs.length) {
178       onTabSelected(myEditorTabs[mySelectedTabIndex]);
179     }
180   }
181
182   @Override
183   public FacetEditorTab[] getEditorTabs() {
184     return myEditorTabs;
185   }
186
187   @Override
188   public <T extends FacetEditorTab> T getEditorTab(@NotNull final Class<T> aClass) {
189     for (FacetEditorTab editorTab : myEditorTabs) {
190       if (aClass.isInstance(editorTab)) {
191         return aClass.cast(editorTab);
192       }
193     }
194     return null;
195   }
196 }