mock filetype manager if no application allows running lexer suites.
[fedora-idea.git] / platform-api / src / com / intellij / ui / GuiUtils.java
blob199106b2dc8f2709e0dcc1ac83f503405f7cd1c2
1 /*
2 * Copyright 2000-2007 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.ui;
18 import com.intellij.openapi.application.Application;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.fileChooser.FileChooser;
21 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
22 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
23 import com.intellij.openapi.ui.FixedSizeButton;
24 import com.intellij.openapi.ui.Splitter;
25 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
26 import com.intellij.openapi.util.io.FileUtil;
27 import com.intellij.openapi.util.text.StringUtil;
28 import com.intellij.openapi.vfs.VfsUtil;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.util.ArrayUtil;
31 import com.intellij.util.Consumer;
32 import com.intellij.util.ui.UIUtil;
33 import org.jetbrains.annotations.NonNls;
34 import org.jetbrains.annotations.NotNull;
36 import javax.swing.*;
37 import javax.swing.border.Border;
38 import javax.swing.border.TitledBorder;
39 import javax.swing.table.TableCellRenderer;
40 import javax.swing.table.TableColumnModel;
41 import java.awt.*;
42 import java.awt.event.ActionEvent;
43 import java.awt.event.ActionListener;
44 import java.lang.reflect.InvocationTargetException;
45 import java.net.MalformedURLException;
47 public class GuiUtils {
49 private static final Insets paddingFromDialogBoundaries = new Insets(7, 5, 7, 5);
50 private static final Insets paddingInsideDialog = new Insets(5, 5, 5, 5);
52 public static final int lengthForFileField = 25;
54 public static JPanel constructFieldWithBrowseButton(JComponent aComponent, ActionListener aActionListener) {
55 return constructFieldWithBrowseButton(aComponent, aActionListener, 0);
58 public static JPanel constructFieldWithBrowseButton(TextFieldWithHistory aComponent, ActionListener aActionListener) {
59 return constructFieldWithBrowseButton(aComponent, aActionListener, 0);
62 private static JPanel constructFieldWithBrowseButton(final JComponent aComponent, final ActionListener aActionListener, int delta) {
63 JPanel result = new JPanel(new GridBagLayout());
64 result.add(aComponent, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,0));
65 FixedSizeButton browseButton = new FixedSizeButton(aComponent.getPreferredSize().height - delta);//ignore border in case of browse button
66 TextFieldWithBrowseButton.MyDoClickAction.addTo(browseButton, aComponent);
67 result.add(browseButton, new GridBagConstraints(1, 0, 1, 1, 0, 1, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0));
68 browseButton.addActionListener(aActionListener);
70 return result;
73 public static JPanel constructDirectoryBrowserField(final JTextField aTextField, final String aSearchedObjectName) {
74 return constructFieldWithBrowseButton(aTextField, new ActionListener() {
75 public void actionPerformed(ActionEvent e) {
76 FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getDirectoryChooserDescriptor(aSearchedObjectName);
77 VirtualFile[] files = FileChooser.chooseFiles(aTextField, descriptor);
78 if (files.length != 0) {
79 aTextField.setText(FileUtil.toSystemDependentName(files[0].getPath()));
80 aTextField.postActionEvent();
83 });
86 public static JPanel constructFileURLBrowserField(final TextFieldWithHistory aFieldWithHistory,
87 final String aSearchedObjectName) {
88 return constructFieldWithBrowseButton(aFieldWithHistory, new ActionListener() {
89 public void actionPerformed(ActionEvent e) {
90 FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getFileChooserDescriptor(aSearchedObjectName);
91 VirtualFile[] files = FileChooser.chooseFiles(aFieldWithHistory, descriptor);
92 if (files.length != 0) {
93 try {
94 aFieldWithHistory.setText(VfsUtil.virtualToIoFile(files[0]).toURL().toString());
96 catch (MalformedURLException e1) {
97 aFieldWithHistory.setText("");
104 public static JComponent constructLabeledComponent(String aLabelText, JComponent aComponent, int aAxis) {
105 JPanel result = new JPanel();
106 BoxLayout boxLayout = new BoxLayout(result, aAxis);
107 result.setLayout(boxLayout);
109 result.add(new JLabel(aLabelText));
110 result.add(aComponent);
112 return result;
115 public static JPanel makeDialogPanel(JPanel aPanel) {
116 JPanel emptyBordered = makePaddedPanel(aPanel, paddingFromDialogBoundaries);
117 return wrapWithBorder(emptyBordered, IdeBorderFactory.createBorder());
120 public static JPanel makeTitledPanel(JComponent aComponent, String aTitle) {
121 JPanel result = makePaddedPanel(aComponent, false, true, false, true);
122 return wrapWithBorder(result, IdeBorderFactory.createTitledBorder(aTitle));
126 private static JPanel wrapWithBorder(JComponent aPanel, Border aBorder) {
127 JPanel wrapper = new JPanel(new BorderLayout());
128 wrapper.add(aPanel, BorderLayout.CENTER);
129 wrapper.setBorder(aBorder);
130 return wrapper;
134 public static BorderLayout createBorderLayout() {
135 return new BorderLayout(paddingInsideDialog.left, paddingInsideDialog.top);
138 public static GridLayout createGridLayout(int aRows, int aColumns) {
139 return new GridLayout(aRows, aColumns, paddingInsideDialog.left, paddingInsideDialog.top);
142 public static Component createVerticalStrut() {
143 return Box.createRigidArea(new Dimension(0, paddingInsideDialog.top));
146 public static Component createHorisontalStrut() {
147 return Box.createRigidArea(new Dimension(paddingInsideDialog.left, 0));
150 private static JPanel makePaddedPanel(JComponent aComponent, Insets aInsets) {
151 return wrapWithBorder(aComponent, BorderFactory.createEmptyBorder(
152 aInsets.top,
153 aInsets.left,
154 aInsets.bottom,
155 aInsets.right
159 private static JPanel makePaddedPanel(JComponent aComponent,
160 boolean aTop,
161 boolean aLeft,
162 boolean aBottom,
163 boolean aRight) {
164 return wrapWithBorder(aComponent, BorderFactory.createEmptyBorder(
165 aTop ? paddingInsideDialog.top : 0,
166 aLeft ? paddingInsideDialog.left : 0,
167 aBottom ? paddingInsideDialog.bottom : 0,
168 aRight ? paddingInsideDialog.right : 0));
171 public static void setAdditionalIcon(JRadioButton button, Icon icon) {
172 final Icon defaultIcon = UIUtil.getRadioButtonIcon();
173 LayeredIcon deficon = new LayeredIcon(2);
174 deficon.setIcon(defaultIcon, 0);
175 deficon.setIcon(icon, 1, defaultIcon.getIconWidth() + 5, 0);
176 button.setIcon(deficon);
178 LayeredIcon pressed = new LayeredIcon(2);
179 pressed.setIcon(defaultIcon, 0);
180 pressed.setIcon(icon, 1, defaultIcon.getIconWidth() + 5, 0);
181 button.setPressedIcon(pressed);
183 LayeredIcon selected = new LayeredIcon(2);
184 selected.setIcon(defaultIcon, 0);
185 selected.setIcon(icon, 1, defaultIcon.getIconWidth() + 5, 0);
186 button.setSelectedIcon(selected);
189 public static String getTextWithoutMnemonicEscaping(String text) {
190 return text.replaceAll("&", "");
193 public static char getDisplayedMnemonic(String text) {
194 final int i = getDisplayedMnemonicIndex(text);
195 return i == -1 ? (char)-1 : text.charAt(i + 1);
198 public static int getDisplayedMnemonicIndex(String text) {
199 return text.indexOf("&");
202 public static void packParentDialog(Component component) {
203 while (component != null) {
204 if (component instanceof JDialog) {
205 component.setVisible(true);
206 break;
208 component = component.getParent();
212 public static void replaceJSplitPaneWithIDEASplitter(JComponent root) {
213 final Container parent = root.getParent();
214 if (root instanceof JSplitPane) {
215 // we can painlessly replace only splitter which is the only child in container
216 if (parent.getComponents().length != 1 && !(parent instanceof Splitter)) {
217 return;
219 final JSplitPane pane = (JSplitPane)root;
220 final Component component1 = pane.getTopComponent();
221 final Component component2 = pane.getBottomComponent();
222 final int orientation = pane.getOrientation();
223 final Splitter splitter = new Splitter(orientation == JSplitPane.VERTICAL_SPLIT);
224 splitter.setFirstComponent((JComponent) component1);
225 splitter.setSecondComponent((JComponent) component2);
226 splitter.setShowDividerControls(pane.isOneTouchExpandable());
227 splitter.setHonorComponentsMinimumSize(true);
229 if (pane.getDividerLocation() > 0) {
230 // let the component chance to resize itself
231 SwingUtilities.invokeLater(new Runnable() {
232 public void run() {
233 double proportion;
234 if (pane.getOrientation() == JSplitPane.VERTICAL_SPLIT) {
235 proportion = pane.getDividerLocation() / (double)(parent.getHeight() - pane.getDividerSize());
237 else {
238 proportion = pane.getDividerLocation() / (double)(parent.getWidth() - pane.getDividerSize());
240 if (proportion > 0 && proportion < 1) {
241 splitter.setProportion((float)proportion);
247 if (parent instanceof Splitter) {
248 final Splitter psplitter = (Splitter) parent;
249 if (psplitter.getFirstComponent() == root)
250 psplitter.setFirstComponent(splitter);
251 else
252 psplitter.setSecondComponent(splitter);
254 else {
255 parent.remove(0);
256 parent.setLayout(new BorderLayout());
257 parent.add(splitter, BorderLayout.CENTER);
259 replaceJSplitPaneWithIDEASplitter((JComponent) component1);
260 replaceJSplitPaneWithIDEASplitter((JComponent) component2);
262 else {
263 final Component[] components = root.getComponents();
264 for (Component component : components) {
265 if (component instanceof JComponent) {
266 replaceJSplitPaneWithIDEASplitter((JComponent)component);
272 public static void iterateChildren(Component container, Consumer<Component> consumer, JComponent... excludeComponents) {
273 if (excludeComponents != null && ArrayUtil.find(excludeComponents, container) != -1) return;
274 consumer.consume(container);
275 if (container instanceof Container) {
276 final Component[] components = ((Container)container).getComponents();
277 for (Component child : components) {
278 iterateChildren(child, consumer, excludeComponents);
283 public static void iterateChildren(Consumer<Component> consumer, Component... components) {
284 for (final Component component : components) {
285 iterateChildren(component, consumer);
289 public static void enableChildren(final boolean enabled, Component... components) {
290 for (final Component component : components) {
291 enableChildren(component, enabled);
295 public static void showComponents(final boolean visible, Component... components) {
296 for (final Component component : components) {
297 component.setVisible(visible);
301 public static void enableChildren(Component container, final boolean enabled, JComponent... excludeComponents) {
302 iterateChildren(container, new Consumer<Component>() {
303 public void consume(final Component t) {
304 enableComponent(t, enabled);
306 }, excludeComponents);
309 private static void enableComponent(Component component, boolean enabled) {
310 if (component.isEnabled() == enabled) return;
311 component.setEnabled(enabled);
312 if (component instanceof JPanel) {
313 final Border border = ((JPanel)component).getBorder();
314 if (border instanceof TitledBorder) {
315 Color color = enabled ? component.getForeground() : UIUtil.getTextInactiveTextColor();
316 ((TitledBorder)border).setTitleColor(color);
319 else if (component instanceof JLabel) {
320 Color color = UIUtil.getTextInactiveTextColor();
321 if (color == null) color = component.getForeground();
322 @NonNls String changeColorString = "<font color=#" + colorToHex(color) +">";
323 final JLabel label = (JLabel)component;
324 @NonNls String text = label.getText();
325 if (text != null && text.startsWith("<html>")) {
326 if (StringUtil.startsWithConcatenationOf(text, "<html>", changeColorString) && enabled) {
327 text = "<html>"+text.substring(("<html>"+changeColorString).length());
329 else if (!StringUtil.startsWithConcatenationOf(text, "<html>", changeColorString) && !enabled) {
330 text = "<html>"+changeColorString+text.substring("<html>".length());
332 label.setText(text);
335 else if (component instanceof JTable) {
336 TableColumnModel columnModel = ((JTable)component).getColumnModel();
337 for (int i=0; i<columnModel.getColumnCount();i++) {
338 TableCellRenderer cellRenderer = columnModel.getColumn(0).getCellRenderer();
339 if (cellRenderer instanceof Component) {
340 enableComponent((Component)cellRenderer, enabled);
346 public static String colorToHex(final Color color) {
347 return to2DigitsHex(color.getRed())
348 +to2DigitsHex(color.getGreen())
349 +to2DigitsHex(color.getBlue());
352 private static String to2DigitsHex(int i) {
353 String s = Integer.toHexString(i);
354 if (s.length() < 2) s = "0" + s;
355 return s;
358 public static void invokeAndWait(@NotNull Runnable runnable) throws InvocationTargetException, InterruptedException {
359 Application application = ApplicationManager.getApplication();
360 assert !application.isDispatchThread() : "Must not be invoked from AWT dispatch thread";
361 if (application.isReadAccessAllowed()) {
362 // make ApplicationImpl catch deadlock situation with readLock held
363 application.invokeAndWait(runnable, application.getDefaultModalityState());
364 return;
366 SwingUtilities.invokeAndWait(runnable);
368 public static void runOrInvokeAndWait(@NotNull Runnable runnable) throws InvocationTargetException, InterruptedException {
369 Application application = ApplicationManager.getApplication();
370 if (application.isDispatchThread()) {
371 runnable.run();
373 else {
374 invokeAndWait(runnable);