replaced <code></code> with more concise {@code}
[idea/community.git] / platform / platform-impl / src / com / intellij / util / IJSwingUtilities.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.util;
17
18 import com.intellij.ide.ui.UISettings;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.wm.ex.WindowManagerEx;
21 import com.intellij.ui.EditorTextField;
22 import com.intellij.util.ui.JBSwingUtilities;
23 import com.intellij.util.ui.UIUtil;
24 import org.jetbrains.annotations.NotNull;
25 import org.jetbrains.annotations.Nullable;
26
27 import javax.swing.*;
28 import javax.swing.event.HyperlinkEvent;
29 import java.awt.*;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32
33 public class IJSwingUtilities extends JBSwingUtilities {
34
35   /**
36    * @return true if javax.swing.SwingUtilities.findFocusOwner(component) != null
37    */
38   public static boolean hasFocus(Component component) {
39     Component focusOwner = findFocusOwner(component);
40     return focusOwner != null;
41   }
42
43   private static Component findFocusOwner(Component c) {
44     Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
45
46     // verify focusOwner is a descendant of c
47     for (Component temp = focusOwner; temp != null; temp = (temp instanceof Window) ? null : temp.getParent())
48     {
49       if (temp == c) {
50         return focusOwner;
51       }
52     }
53
54     return null;
55   }
56
57   /**
58    * @return true if window ancestor of component was most recent focused window and most recent focused component
59    * in that window was descended from component
60    */
61   public static boolean hasFocus2(Component component) {
62     WindowManagerEx windowManager = WindowManagerEx.getInstanceEx();
63     Window activeWindow=null;
64     if (windowManager != null) {
65       activeWindow = windowManager.getMostRecentFocusedWindow();
66     }
67     if(activeWindow==null){
68       return false;
69     }
70     Component focusedComponent = windowManager.getFocusedComponent(activeWindow);
71     if (focusedComponent == null) {
72       return false;
73     }
74
75     return SwingUtilities.isDescendingFrom(focusedComponent, component);
76   }
77
78   /**
79    * This method is copied from {@code SwingUtilities}.
80    * Returns index of the first occurrence of {@code mnemonic}
81    * within string {@code text}. Matching algorithm is not
82    * case-sensitive.
83    *
84    * @param text The text to search through, may be null
85    * @param mnemonic The mnemonic to find the character for.
86    * @return index into the string if exists, otherwise -1
87    */
88   public static int findDisplayedMnemonicIndex(String text, int mnemonic) {
89     if (text == null || mnemonic == '\0') {
90       return -1;
91     }
92
93     char uc = Character.toUpperCase((char)mnemonic);
94     char lc = Character.toLowerCase((char)mnemonic);
95
96     int uci = text.indexOf(uc);
97     int lci = text.indexOf(lc);
98
99     if (uci == -1) {
100       return lci;
101     } else if(lci == -1) {
102       return uci;
103     } else {
104       return (lci < uci) ? lci : uci;
105     }
106   }
107
108   public static void adjustComponentsOnMac(@Nullable JComponent component) {
109     adjustComponentsOnMac(null, component);
110   }
111
112
113   public static void adjustComponentsOnMac(@Nullable JLabel label, @Nullable JComponent component) {
114     if (component == null) return;
115     if (!UIUtil.isUnderAquaLookAndFeel()) return;
116
117     if (component instanceof JComboBox) {
118       UIUtil.addInsets(component, new Insets(0,-2,0,0));
119       if (label != null) {
120         UIUtil.addInsets(label, new Insets(0,2,0,0));
121       }
122     }
123     if (component instanceof JCheckBox) {
124       UIUtil.addInsets(component, new Insets(0,-5,0,0));
125     }
126     if (component instanceof JTextField || component instanceof EditorTextField) {
127       if (label != null) {
128         UIUtil.addInsets(label, new Insets(0,3,0,0));
129       }
130     }
131   }
132
133   public static HyperlinkEvent createHyperlinkEvent(@Nullable String href, @NotNull Object source) {
134     URL url = null;
135     try {
136       url = new URL(href);
137     }
138     catch (MalformedURLException ignored) {
139     }
140     return new HyperlinkEvent(source, HyperlinkEvent.EventType.ACTIVATED, url, href);
141   }
142
143   /**
144    * A copy of javax.swing.SwingUtilities#updateComponentTreeUI that invokes children updateUI() first
145
146    * @param c component
147    * @see javax.swing.SwingUtilities#updateComponentTreeUI
148    */
149   public static void updateComponentTreeUI(@Nullable Component c) {
150     if (c == null) return;
151     for (Component component : UIUtil.uiTraverser(c).postOrderDfsTraversal()) {
152       if (component instanceof JComponent) ((JComponent)component).updateUI();
153     }
154     c.invalidate();
155     c.validate();
156     c.repaint();
157   }
158
159   public static void moveMousePointerOn(Component component) {
160     if (component != null && component.isShowing()) {
161       UISettings settings = ApplicationManager.getApplication() == null ? null : UISettings.getInstance();
162       if (settings != null && settings.getMoveMouseOnDefaultButton()) {
163         Point point = component.getLocationOnScreen();
164         int dx = component.getWidth() / 2;
165         int dy = component.getHeight() / 2;
166         try {
167           new Robot().mouseMove(point.x + dx, point.y + dy);
168         }
169         catch (AWTException ignored) {
170           // robot is not available
171         }
172       }
173     }
174   }
175 }