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
.openapi
.wm
.impl
;
18 import com
.intellij
.ide
.AppLifecycleListener
;
19 import com
.intellij
.ide
.DataManager
;
20 import com
.intellij
.ide
.impl
.ProjectUtil
;
21 import com
.intellij
.ide
.ui
.UISettings
;
22 import com
.intellij
.openapi
.MnemonicHelper
;
23 import com
.intellij
.openapi
.actionSystem
.ActionManager
;
24 import com
.intellij
.openapi
.actionSystem
.DataProvider
;
25 import com
.intellij
.openapi
.actionSystem
.PlatformDataKeys
;
26 import com
.intellij
.openapi
.application
.Application
;
27 import com
.intellij
.openapi
.application
.ApplicationInfo
;
28 import com
.intellij
.openapi
.application
.ApplicationManager
;
29 import com
.intellij
.openapi
.application
.ModalityState
;
30 import com
.intellij
.openapi
.application
.ex
.ApplicationInfoEx
;
31 import com
.intellij
.openapi
.application
.ex
.ApplicationManagerEx
;
32 import com
.intellij
.openapi
.keymap
.KeymapManager
;
33 import com
.intellij
.openapi
.project
.DumbAwareRunnable
;
34 import com
.intellij
.openapi
.project
.Project
;
35 import com
.intellij
.openapi
.project
.ProjectManager
;
36 import com
.intellij
.openapi
.wm
.IdeFrame
;
37 import com
.intellij
.openapi
.wm
.ex
.LayoutFocusTraversalPolicyExt
;
38 import com
.intellij
.openapi
.wm
.ex
.StatusBarEx
;
39 import com
.intellij
.ui
.AppUIUtil
;
40 import com
.intellij
.ui
.BalloonLayout
;
41 import com
.intellij
.ui
.FocusTrackback
;
42 import com
.intellij
.util
.ui
.UIUtil
;
43 import org
.jetbrains
.annotations
.NotNull
;
44 import org
.jetbrains
.annotations
.Nullable
;
48 import java
.awt
.event
.WindowAdapter
;
49 import java
.awt
.event
.WindowEvent
;
53 * @author Anton Katilin
54 * @author Vladimir Kondratyev
57 // Made non-final for Fabrique
58 public class IdeFrameImpl
extends JFrame
implements IdeFrame
, DataProvider
{
59 private String myTitle
;
61 private String myFileTitle
;
62 private File myCurrentFile
;
64 private Project myProject
;
65 private final LayoutFocusTraversalPolicyExt myLayoutFocusTraversalPolicy
;
67 private IdeRootPane myRootPane
;
68 private BalloonLayout myBalloonLayout
;
70 public IdeFrameImpl(ApplicationInfoEx applicationInfoEx
, ActionManager actionManager
, UISettings uiSettings
, DataManager dataManager
,
71 KeymapManager keymapManager
, final Application application
, final String
[] commandLineArgs
) {
72 super(applicationInfoEx
.getFullApplicationName());
73 myRootPane
= new IdeRootPane(actionManager
, uiSettings
, dataManager
, keymapManager
, application
, commandLineArgs
);
74 setRootPane(myRootPane
);
76 AppUIUtil
.updateFrameIcon(this);
77 final Dimension screenSize
= Toolkit
.getDefaultToolkit().getScreenSize();
78 setBounds(10, 10, screenSize
.width
- 20, screenSize
.height
- 40);
80 myLayoutFocusTraversalPolicy
= new LayoutFocusTraversalPolicyExt();
81 setFocusTraversalPolicy(myLayoutFocusTraversalPolicy
);
84 new MnemonicHelper().register(this);
86 myBalloonLayout
= new BalloonLayout(myRootPane
.getLayeredPane(), new Insets(8, 8, 8, 8));
94 * THIS IS AN "ABSOLUTELY-GURU METHOD".
95 * NOBODY SHOULD ADD OTHER USAGES OF IT :)
96 * ONLY ANTON AND VOVA ARE PERMITTED TO USE THIS METHOD!!!
100 * !!!!! CAUTION !!!!!
102 public final void setDefaultFocusableComponent(final JComponent component
) {
103 myLayoutFocusTraversalPolicy
.setOverridenDefaultComponent(component
);
107 * This is overriden to get rid of strange Alloy LaF customization of frames. For unknown reason it sets the maxBounds rectangle
108 * and it does it plain wrong. Setting bounds to <code>null</code> means default value should be taken from the underlying OS.
110 public synchronized void setMaximizedBounds(Rectangle bounds
) {
111 super.setMaximizedBounds(null);
114 private void setupCloseAction() {
115 setDefaultCloseOperation(WindowConstants
.DO_NOTHING_ON_CLOSE
);
117 new WindowAdapter() {
118 public void windowClosing(final WindowEvent e
) {
119 final Application app
= ApplicationManager
.getApplication();
120 app
.invokeLater(new DumbAwareRunnable() {
122 if (app
.isDisposed()) {
123 ApplicationManagerEx
.getApplicationEx().exit();
127 final Project
[] openProjects
= ProjectManager
.getInstance().getOpenProjects();
128 if (openProjects
.length
> 1) {
129 if (myProject
!= null && myProject
.isOpen()) {
130 ProjectUtil
.closeProject(myProject
);
132 app
.getMessageBus().syncPublisher(AppLifecycleListener
.TOPIC
).projectFrameClosed();
135 ApplicationManagerEx
.getApplicationEx().exit();
138 }, ModalityState
.NON_MODAL
);
144 public StatusBarEx
getStatusBar() {
145 return ((IdeRootPane
)getRootPane()).getStatusBar();
148 public void updateToolbar() {
149 ((IdeRootPane
)getRootPane()).updateToolbar();
152 public void updateMenuBar(){
153 ((IdeRootPane
)getRootPane()).updateMainMenuActions();
156 public void setTitle(final String title
) {
161 private void setFrameTitle(final String text
) {
162 super.setTitle(text
);
165 public void setFileTitle(final String fileTitle
) {
166 setFileTitle(fileTitle
, null);
169 public void setFileTitle(@Nullable final String fileTitle
, @Nullable File file
) {
170 myFileTitle
= fileTitle
;
171 myCurrentFile
= file
;
175 private void updateTitle() {
176 final StringBuilder sb
= new StringBuilder();
177 if (myTitle
!= null && myTitle
.length() > 0) {
181 if (myFileTitle
!= null && myFileTitle
.length() > 0) {
182 sb
.append(myFileTitle
);
186 getRootPane().putClientProperty("Window.documentFile", myCurrentFile
);
188 sb
.append(((ApplicationInfoEx
)ApplicationInfo
.getInstance()).getFullApplicationName());
189 setFrameTitle(sb
.toString());
192 public Object
getData(final String dataId
) {
193 if (PlatformDataKeys
.PROJECT
.is(dataId
)) {
194 if (myProject
!= null) {
195 return myProject
.isInitialized() ? myProject
: null;
201 public void setProject(final Project project
) {
202 getStatusBar().cleanupCustomComponents();
204 if (project
!= null) {
205 if (myRootPane
!= null) {
206 myRootPane
.installNorthComponents(project
);
210 if (myRootPane
!= null) { //already disposed
211 myRootPane
.deinstallNorthComponents();
215 if (project
== null) {
216 FocusTrackback
.release(this);
220 public Project
getProject() {
224 public void dispose() {
225 if (myRootPane
!= null) {
232 public void paint(Graphics g
) {
233 UIUtil
.applyRenderingHints(g
);
237 public Rectangle
suggestChildFrameBounds() {
238 //todo [kirillk] a dummy implementation
239 final Rectangle b
= getBounds();
248 public static Component
findNearestModalComponent(@NotNull Component c
) {
249 Component eachParent
= c
;
250 while (eachParent
!= null) {
251 if (eachParent
instanceof IdeFrameImpl
) return eachParent
;
252 if (eachParent
instanceof JDialog
) {
253 if (((JDialog
)eachParent
).isModal()) return eachParent
;
255 eachParent
= eachParent
.getParent();
261 public final BalloonLayout
getBalloonLayout() {
262 return myBalloonLayout
;