1 /*
2  * Copyright (c) 2016 Vivid Solutions.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
8  * and the Eclipse Distribution License is available at
9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12 package org.locationtech.jtstest.testrunner;
13 
14 import java.awt.Component;
15 import java.awt.Container;
16 import java.awt.Dimension;
17 import java.awt.Toolkit;
18 import java.beans.PropertyVetoException;
19 import java.io.File;
20 
21 import javax.swing.JComponent;
22 import javax.swing.JDesktopPane;
23 import javax.swing.JFileChooser;
24 import javax.swing.JInternalFrame;
25 import javax.swing.JList;
26 import javax.swing.JTable;
27 import javax.swing.SwingUtilities;
28 import javax.swing.text.JTextComponent;
29 
30 import org.locationtech.jtstest.util.StringUtil;
31 
32 
33 /**
34  * Useful GUI utilities
35  *
36  * @version 1.7
37  */
38 public class GuiUtil {
39 
40     /**
41      * Centers the first component on the second
42      */
center(Component componentToMove, Component componentToCenterOn)43     public static void center(Component componentToMove, Component componentToCenterOn) {
44         Dimension componentToCenterOnSize = componentToCenterOn.getSize();
45         componentToMove.setLocation(
46             componentToCenterOn.getX()
47                 + ((componentToCenterOnSize.width - componentToMove.getWidth()) / 2),
48             componentToCenterOn.getY()
49                 + ((componentToCenterOnSize.height - componentToMove.getHeight()) / 2));
50     }
51 
52     /**
53      * Centers the component on the screen
54      */
centerOnScreen(Component componentToMove)55     public static void centerOnScreen(Component componentToMove) {
56         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
57         componentToMove.setLocation(
58             (screenSize.width - componentToMove.getWidth()) / 2,
59             (screenSize.height - componentToMove.getHeight()) / 2);
60     }
61 
62     /**
63      * Centers the component on its window
64      */
centerOnWindow(Component componentToMove)65     public static void centerOnWindow(Component componentToMove) {
66         center(componentToMove, SwingUtilities.windowForComponent(componentToMove));
67     }
68 
69     //Save the contents of the cell that the user is in the middle of editing
70     //From Question of the Week No. 23
71     //http://developer.java.sun.com/developer/qow/archive/23/
commitChanges(JTable table)72     public static void commitChanges(JTable table) {
73         if (table.isEditing()) {
74             String text = ((JTextComponent) table.getEditorComponent()).getText();
75             table.setValueAt(text, table.getEditingRow(), table.getEditingColumn());
76             table.getCellEditor().cancelCellEditing();
77         }
78     }
79 
80     /**
81      * Workaround for bug: can't re-show internal frames. See bug parade 4138031.
82      */
show(JInternalFrame internalFrame, JDesktopPane desktopPane)83     public static void show(JInternalFrame internalFrame, JDesktopPane desktopPane)
84         throws PropertyVetoException {
85         if (!desktopPane.isAncestorOf(internalFrame))
86             desktopPane.add(internalFrame);
87         internalFrame.setClosed(false);
88         internalFrame.setVisible(true);
89         internalFrame.toFront();
90     }
91 
92     /**
93      * Workaround for Swing bug: JFileChooser does not support multi-file selection
94      * See Sun bug database 4218431.
95      * http://manning.spindoczine.com/sbe/files/uts2/Chapter14html/Chapter14.htm)
96      */
getSelectedFiles(JFileChooser chooser)97     public static File[] getSelectedFiles(JFileChooser chooser) {
98         // Although JFileChooser won't give us this information,
99         // we need it...
100         Container c1 = (Container) chooser.getComponent(3);
101         JList list = null;
102         while (c1 != null) {
103             Container c = (Container) c1.getComponent(0);
104             if (c instanceof JList) {
105                 list = (JList) c;
106                 break;
107             }
108             c1 = c;
109         }
110         Object[] entries = list.getSelectedValues();
111         File[] files = new File[entries.length];
112         for (int k = 0; k < entries.length; k++) {
113             if (entries[k] instanceof File)
114                 files[k] = (File) entries[k];
115         }
116         return files;
117     }
118 
119     /**
120      * Changes the tooltip text of each component in the Container to be
121      * multiline HTML. Modifies all descendants (children, grandchildren, etc.).
122      */
formatTooltips(Container container)123     public static void formatTooltips(Container container) {
124         for (int i = 0; i < container.getComponentCount(); i++) {
125             Component component = container.getComponent(i);
126             if (component instanceof JComponent)
127                 formatTooltip((JComponent) component);
128             if (component instanceof Container)
129                 formatTooltips((Container) component);
130         }
131     }
132 
133     /**
134      * Changes the tooltip text of the JComponent to be multiline HTML.
135      */
formatTooltip(JComponent jcomponent)136     public static void formatTooltip(JComponent jcomponent) {
137         String tip = jcomponent.getToolTipText();
138         if (tip == null || tip.length() == 0)
139             return;
140         if (tip.toLowerCase().indexOf("<html>") > -1)
141             return;
142         tip = StringUtil.wrap(tip, 50);
143         tip = StringUtil.replaceAll(tip, "\n", "<p>");
144         tip = "<html>" + tip + "</html>";
145         jcomponent.setToolTipText(tip);
146     }
147 
148     /**
149      * Runs r in the event dispatch thread, which may be the current thread.
150      * Waits for r to finish before returning.
151      */
invokeAndWait(Runnable r)152     public static void invokeAndWait(Runnable r)
153         throws InterruptedException, java.lang.reflect.InvocationTargetException {
154         if (SwingUtilities.isEventDispatchThread()) {
155             r.run();
156         } else {
157             SwingUtilities.invokeAndWait(r);
158         }
159     }
160 }
161