1 /*
2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation. Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package org.netbeans.jemmy.util;
26 
27 import java.awt.Component;
28 import java.awt.Container;
29 import java.awt.Dialog;
30 
31 import javax.swing.JInternalFrame;
32 import javax.swing.JScrollPane;
33 import javax.swing.JTabbedPane;
34 
35 import org.netbeans.jemmy.JemmyException;
36 import org.netbeans.jemmy.JemmyInputException;
37 import org.netbeans.jemmy.JemmyProperties;
38 import org.netbeans.jemmy.TimeoutExpiredException;
39 import org.netbeans.jemmy.operators.ComponentOperator;
40 import org.netbeans.jemmy.operators.JDialogOperator;
41 import org.netbeans.jemmy.operators.JInternalFrameOperator;
42 import org.netbeans.jemmy.operators.JScrollPaneOperator;
43 import org.netbeans.jemmy.operators.JTabbedPaneOperator;
44 import org.netbeans.jemmy.operators.Operator;
45 import org.netbeans.jemmy.operators.WindowOperator;
46 import org.netbeans.jemmy.operators.Operator.ComponentVisualizer;
47 
48 /**
49  *
50  * Used as component visualizer by default.
51  *
52  * @see
53  * org.netbeans.jemmy.operators.Operator#setVisualizer(Operator.ComponentVisualizer)
54  * @see org.netbeans.jemmy.operators.Operator.ComponentVisualizer
55  *
56  * @author Alexandre Iline (alexandre.iline@oracle.com)
57  *
58  */
59 public class DefaultVisualizer implements ComponentVisualizer, Cloneable {
60 
61     private boolean window = true;
62     private boolean internalFrame = true;
63     private boolean scroll = false;
64     private boolean switchTab = false;
65     private boolean modal = false;
66 
DefaultVisualizer()67     public DefaultVisualizer() {
68     }
69 
70     /**
71      * Forces vizualizer to check that component is on the top modal dialog or
72      * no modal dialog displayed.
73      *
74      * @param yesOrNo If true, JemmyInputException will be throught if component
75      * is not on the top modal dialog and a modal dialog is dislayed.
76      */
checkForModal(boolean yesOrNo)77     public void checkForModal(boolean yesOrNo) {
78         modal = yesOrNo;
79     }
80 
81     /**
82      * Informs that a window contained component should be activated.
83      *
84      * @param yesOrNo true if windows need to be activated.
85      */
activateWindow(boolean yesOrNo)86     public void activateWindow(boolean yesOrNo) {
87         window = yesOrNo;
88     }
89 
90     /**
91      * Informs that an internal frame contained component should be activated.
92      *
93      * @param yesOrNo true if internal frames need to be activated.
94      */
activateInternalFrame(boolean yesOrNo)95     public void activateInternalFrame(boolean yesOrNo) {
96         internalFrame = yesOrNo;
97     }
98 
99     /**
100      * Informs that scrolling should be made.
101      *
102      * @param yesOrNo true if scroll panes need to be scrolled.
103      */
scroll(boolean yesOrNo)104     public void scroll(boolean yesOrNo) {
105         scroll = yesOrNo;
106     }
107 
108     /**
109      * Informs that tab switching should be made.
110      *
111      * @param yesOrNo true if tabbed panes need to be switched.
112      */
switchTab(boolean yesOrNo)113     public void switchTab(boolean yesOrNo) {
114         switchTab = yesOrNo;
115     }
116 
117     /**
118      * Returns true if window is active.
119      *
120      * @param winOper an operator representing the window.
121      * @return true is window is active.
122      */
isWindowActive(WindowOperator winOper)123     protected boolean isWindowActive(WindowOperator winOper) {
124         return winOper.isFocused() && winOper.isActive();
125     }
126 
127     /**
128      * Performs an atomic window-activization precedure. A window is sopposed to
129      * be prepared for the activization (i.e. put "to front").
130      *
131      * @param winOper an operator representing the window.
132      */
makeWindowActive(WindowOperator winOper)133     protected void makeWindowActive(WindowOperator winOper) {
134         winOper.activate();
135     }
136 
137     /**
138      * Activates a window. Uses makeWindowActive if necessary.
139      *
140      * @param winOper an operator representing the window.
141      * @see #makeWindowActive
142      */
activate(WindowOperator winOper)143     protected void activate(WindowOperator winOper) {
144         boolean active = isWindowActive(winOper);
145         winOper.toFront();
146         if (!active) {
147             makeWindowActive(winOper);
148         }
149     }
150 
151     /**
152      * Inits an internal frame.
153      *
154      * @param intOper an operator representing the frame.
155      */
initInternalFrame(JInternalFrameOperator intOper)156     protected void initInternalFrame(JInternalFrameOperator intOper) {
157         if (!intOper.isSelected()) {
158             intOper.activate();
159         }
160     }
161 
162     /**
163      * Scrolls JScrollPane to make the component visible.
164      *
165      * @param scrollOper an operator representing a scroll pane.
166      * @param target a component - target to be made visible.
167      */
scroll(JScrollPaneOperator scrollOper, Component target)168     protected void scroll(JScrollPaneOperator scrollOper, Component target) {
169         if (!scrollOper.checkInside(target)) {
170             scrollOper.scrollToComponent(target);
171         }
172     }
173 
174     /**
175      * Switches tabs to make the component visible.
176      *
177      * @param tabOper an operator representing a tabbed pane.
178      * @param target a component - target to be made visible.
179      */
switchTab(JTabbedPaneOperator tabOper, Component target)180     protected void switchTab(JTabbedPaneOperator tabOper, Component target) {
181         int tabInd = 0;
182         for (int j = 0; j < tabOper.getTabCount(); j++) {
183             if (target == tabOper.getComponentAt(j)) {
184                 tabInd = j;
185                 break;
186             }
187         }
188         if (tabOper.getSelectedIndex() != tabInd) {
189             tabOper.selectPage(tabInd);
190         }
191     }
192 
193     /**
194      * Prepares the component for user input.
195      *
196      * @param compOper an operator representing the component.
197      * @throws JemmyInputException
198      * @see #checkForModal(boolean)
199      */
200     @Override
makeVisible(ComponentOperator compOper)201     public void makeVisible(ComponentOperator compOper) {
202         try {
203             if (modal) {
204                 Dialog modalDialog = JDialogOperator.getTopModalDialog();
205                 if (modalDialog != null
206                         && compOper.getWindow() != modalDialog) {
207                     throw (new JemmyInputException("Component is not on top modal dialog.",
208                             compOper.getSource()));
209                 }
210             }
211             WindowOperator winOper = new WindowOperator(compOper.getWindow());
212             if (window) {
213                 winOper.copyEnvironment(compOper);
214                 winOper.setVisualizer(new EmptyVisualizer());
215                 activate(winOper);
216             }
217             if (internalFrame && compOper instanceof JInternalFrameOperator) {
218                 initInternalFrame((JInternalFrameOperator) compOper);
219             }
220             Container[] conts = compOper.getContainers();
221             for (int i = conts.length - 1; i >= 0; i--) {
222                 if (internalFrame && conts[i] instanceof JInternalFrame) {
223                     JInternalFrameOperator intOper = new JInternalFrameOperator((JInternalFrame) conts[i]);
224                     intOper.copyEnvironment(compOper);
225                     intOper.setVisualizer(new EmptyVisualizer());
226                     initInternalFrame(intOper);
227                 } else if (scroll && conts[i] instanceof JScrollPane) {
228                     JScrollPaneOperator scrollOper = new JScrollPaneOperator((JScrollPane) conts[i]);
229                     scrollOper.copyEnvironment(compOper);
230                     scrollOper.setVisualizer(new EmptyVisualizer());
231                     scroll(scrollOper, compOper.getSource());
232                 } else if (switchTab && conts[i] instanceof JTabbedPane) {
233                     JTabbedPaneOperator tabOper = new JTabbedPaneOperator((JTabbedPane) conts[i]);
234                     tabOper.copyEnvironment(compOper);
235                     tabOper.setVisualizer(new EmptyVisualizer());
236                     switchTab(tabOper, i == 0 ? compOper.getSource() : conts[i - 1]);
237                 }
238             }
239         } catch (TimeoutExpiredException e) {
240             JemmyProperties.getProperties().getOutput().printStackTrace(e);
241         }
242     }
243 
244     /**
245      * Creates an exact copy of this visualizer.
246      *
247      * @return new instance.
248      */
cloneThis()249     public DefaultVisualizer cloneThis() {
250         try {
251             return (DefaultVisualizer) super.clone();
252         } catch (CloneNotSupportedException e) {
253             //that's impossible
254             throw (new JemmyException("Even impossible happens :)", e));
255         }
256     }
257 
258 }
259