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
26 package javafx.scene;
27
28 import com.sun.javafx.pgstub.StubToolkit;
29 import com.sun.javafx.sg.prism.NGGroup;
30 import com.sun.javafx.tk.Toolkit;
31 import java.util.concurrent.atomic.AtomicBoolean;
32 import javafx.scene.shape.Rectangle;
33 import javafx.stage.Stage;
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.Test;
37
38 import static org.junit.Assert.*;
39
40 public class ParentTest {
41 private StubToolkit toolkit;
42 private Stage stage;
43
44 @Before
45 public void setUp() {
46 toolkit = (StubToolkit) Toolkit.getToolkit();
47 stage = new Stage();
48 }
49
50 @After
51 public void tearDown() {
127 groupD.setId("d");
128 Group group = new Group(rectA, rectB, rectC, groupD, rectE, rectF);
129
130 assertNull(group.lookup("#4444"));
131 }
132
133 @Test
134 public void testRemoveChild() {
135 Rectangle rect1 = new Rectangle();
136 Rectangle rect2 = new Rectangle();
137 Rectangle rect3 = new Rectangle();
138 Rectangle rect4 = new Rectangle();
139 Rectangle rect5 = new Rectangle();
140 Rectangle rect6 = new Rectangle();
141
142 Group g = new Group();
143 Scene s = new Scene(g);
144 stage.setScene(s);
145 stage.show();
146
147 g.getChildren().addAll(rect1, rect2, rect3, rect4, rect5, rect6);
148 toolkit.fireTestPulse();
149
150 // try removing node from the end of the observableArrayList
151 g.getChildren().remove(rect6);
152 toolkit.fireTestPulse();
153 final NGGroup peer = g.impl_getPeer();
154 assertEquals(5, g.getChildren().size());
155 assertEquals(5, peer.getChildren().size());
156
157 // try removing node from the beginning of the observableArrayList
158 g.getChildren().remove(rect1);
159 toolkit.fireTestPulse();
160 assertEquals(4, g.getChildren().size());
161 assertEquals(4, peer.getChildren().size());
162
163 // try removing node from the middle of the observableArrayList
164 g.getChildren().remove(rect3);
165 toolkit.fireTestPulse();
166 assertEquals(3, g.getChildren().size());
167 assertEquals(3, peer.getChildren().size());
168 }
169
170 @Test
171 public void testSetChild() {
172 Rectangle rect1 = new Rectangle();
173 Rectangle rect2 = new Rectangle();
174 Rectangle rect3 = new Rectangle();
175
176 Group g = new Group();
177 Scene s = new Scene(g);
178 stage.setScene(s);
179 stage.show();
180
181 g.getChildren().addAll(rect1, rect2);
182 toolkit.fireTestPulse();
183
184 // try setting node at given index
185 g.getChildren().set(1, rect3);
186 toolkit.fireTestPulse();
187 assertEquals(2, g.getChildren().size());
188 assertEquals(2, ((NGGroup)g.impl_getPeer()).getChildren().size());
189 }
190
191 @Test
192 public void testSetSameChild() {
193 Rectangle rect1 = new Rectangle();
194 Rectangle rect2 = new Rectangle();
195
196 Group g = new Group();
197 Scene s = new Scene(g);
198 stage.setScene(s);
199 stage.show();
200
201 g.getChildren().addAll(rect1, rect2);
202 toolkit.fireTestPulse();
203
204 // try setting the same node at given index
205 g.getChildren().set(1, rect2);
206
207 toolkit.fireTestPulse();
208 assertEquals(2, g.getChildren().size());
209 assertEquals(2, ((NGGroup)g.impl_getPeer()).getChildren().size());
210 }
211
212 @Test
213 public void testRemoveAddSameChild() {
214 Rectangle rect1 = new Rectangle();
215 Rectangle rect2 = new Rectangle();
216 Rectangle rect3 = new Rectangle();
217 Rectangle rect4 = new Rectangle();
218 Rectangle rect5 = new Rectangle();
219 Rectangle rect6 = new Rectangle();
220
221 Group g = new Group();
222 Scene s = new Scene(g);
223 stage.setScene(s);
224 stage.show();
225
226 g.getChildren().addAll(rect1, rect2, rect3, rect4, rect5, rect6);
227 toolkit.fireTestPulse();
228
229 // try removing node from the end of the observableArrayList
230 // and add it afterwords
231 g.getChildren().remove(rect6);
232 g.getChildren().add(rect6);
233 toolkit.fireTestPulse();
234 assertEquals(6, g.getChildren().size());
235 assertEquals(6, ((NGGroup)g.impl_getPeer()).getChildren().size());
236 }
237
238 @Test
239 public void testRemoveAddDiferentChild() {
240 Rectangle rect1 = new Rectangle();
241 Rectangle rect2 = new Rectangle();
242 Rectangle rect3 = new Rectangle();
243 Rectangle rect4 = new Rectangle();
244 Rectangle rect5 = new Rectangle();
245 Rectangle rect6 = new Rectangle();
246
247 Group g = new Group();
248 Scene s = new Scene(g);
249 stage.setScene(s);
250 stage.show();
251
252 g.getChildren().addAll(rect1, rect2, rect3, rect4, rect5);
253 toolkit.fireTestPulse();
254
255 // try removing node from the end of the observableArrayList
256 // and add a different one
257 g.getChildren().remove(rect5);
258 g.getChildren().add(rect6);
259 toolkit.fireTestPulse();
260 assertEquals(5, g.getChildren().size());
261 assertEquals(5, ((NGGroup)g.impl_getPeer()).getChildren().size());
262 }
263
264 @Test
265 public void testGetChildrenUnmodifiable() {
266 Rectangle rect1 = new Rectangle();
267 Rectangle rect2 = new Rectangle();
268 Rectangle rect3 = new Rectangle();
269
270 Group g = new Group();
271 g.getChildren().addAll(rect1,rect2,rect3);
272
273 assertEquals(3, g.getChildrenUnmodifiable().size());
274 assertSame(rect1, g.getChildrenUnmodifiable().get(0));
275 assertSame(rect2, g.getChildrenUnmodifiable().get(1));
276 assertSame(rect3, g.getChildrenUnmodifiable().get(2));
277 }
278
279 @Test
280 public void testGetChildrenUnmodifiableCantBeModified() {
281 Rectangle rect1 = new Rectangle();
282 Rectangle rect2 = new Rectangle();
283 Rectangle rect3 = new Rectangle();
284
285 Group g = new Group();
286 g.getChildren().addAll(rect1,rect2,rect3);
287
288 try {
289 g.getChildrenUnmodifiable().add(new Rectangle());
290 fail("UnsupportedOperationException should have been thrown.");
291 } catch (UnsupportedOperationException uoe) {
292 // expected
293 }
294 }
295
296 @Test
297 public void testRequestLayoutWithoutParent() {
298 Group g = new Group();
299 g.layout();
300 // this shouldn't fail even when the group doesn't have a parent
301 g.requestLayout();
302 }
303
304 @Test
305 public void testRequestLayoutWithoutScene() {
306 Group g = new Group();
307 g.setManaged(false);
308 g.layout();
309 // this shouldn't fail even when the scene is not set
310 g.requestLayout();
311 }
312
313 @Test
314 public void testRequestLayoutClearsCache() {
315 Group g = new Group();
316 Rectangle r = new Rectangle(100,200);
317 g.getChildren().add(r);
318
319 g.requestLayout();
320 assertEquals(100, g.prefWidth(-1), 1e-100);
321 assertEquals(200, g.prefHeight(-1), 1e-100);
322
323 r.setWidth(150);
324 r.setHeight(250);
325 g.requestLayout();
326
327 assertEquals(150, g.prefWidth(-1), 1e-100);
328 assertEquals(250, g.prefHeight(-1), 1e-100);
329 }
330
331 @Test
332 public void testPrefWidthIncludesChildLayoutX() {
333 Rectangle r = new Rectangle(10,10,100,100);
334 r.setLayoutX(10);
335 MockParent p = new MockParent(r);
336
337 assertEquals(120, p.prefWidth(-1), 0);
339
340 @Test
341 public void testPrefHeightIncludesChildLayoutY() {
342 Rectangle r = new Rectangle(10,10,100,100);
343 r.setLayoutY(10);
344 MockParent p = new MockParent(r);
345
346 assertEquals(120, p.prefHeight(-1), 0);
347 }
348
349 @Test
350 public void testDuplicates() {
351 Group g = new Group();
352
353 Rectangle r1 = new Rectangle();
354 Rectangle r2 = new Rectangle();
355 Rectangle r3 = new Rectangle();
356 Rectangle r4 = new Rectangle();
357
358 try {
359 g.getChildren().addAll(r1, r2, r3, r4);
360 g.getChildren().add(r2);
361 fail();
362 } catch (IllegalArgumentException e) {
363
364 }
365 }
366
367 @Test(expected=NullPointerException.class)
368 public void testAddingNullChild() {
369 Group g = new Group();
370 g.getChildren().add(null);
371 }
372
373 @Test(expected=NullPointerException.class)
374 public void testNullCheckIsDoneBeforeTestForDuplicates() {
375 Group g = new Group();
376 g.getChildren().addAll(null, new Rectangle(), null);
377 }
378
379 @Test(expected=IllegalArgumentException.class)
380 public void testAddingClipNodeTwice() {
381 Group g = new Group();
382
383 Node clipParent = new Rectangle();
384 Node clipNode = new Rectangle();
385
386 clipParent.setClip(clipNode);
387 try {
388 // try to add node which is already set as a clip
389 g.getChildren().add(clipNode);
390 fail();
391 } catch (IllegalArgumentException e) {
392 }
393
394 // try again
395 g.getChildren().add(clipNode);
396 }
397
398 @Test
399 public void testAddingFixedClipNode() {
400 Group g = new Group();
401
402 Node clipParent = new Rectangle();
403 Node clipNode = new Rectangle();
404
405 clipParent.setClip(clipNode);
406 try {
407 // try to add node which is already set as a clip
408 g.getChildren().add(clipNode);
409 fail();
410 } catch (IllegalArgumentException e) {
411 }
412
413 // fix the problem and add again
414 clipParent.setClip(null);
415 g.getChildren().add(clipNode);
416 }
417
418 @Test(expected=IllegalArgumentException.class)
419 public void testFalsePermutation() {
420 Group g = new Group();
421
422 Rectangle r1 = new Rectangle();
423 Rectangle r2 = new Rectangle();
424 Rectangle r3 = new Rectangle();
425 Rectangle r4 = new Rectangle();
426
427 g.getChildren().addAll(r1, r2, r3, r4);
428 g.getChildren().setAll(r1, r2, r2, r4);
429 }
430
431 @Test
432 public void testFalseDuplicates() {
433 Group g = new Group();
434
435 Rectangle r1 = new Rectangle();
436 Rectangle r2 = new Rectangle();
437 Rectangle r3 = new Rectangle();
438 Rectangle r4 = new Rectangle();
439
440 g.getChildren().addAll(r1, r2);
441 try {
442 g.getChildren().addAll(r3, r4, r2);
443 fail();
444 } catch (IllegalArgumentException e) {
445 }
446 try {
447 g.getChildren().add(r3);
448 } catch (IllegalArgumentException e) {
449 fail();
450 }
451
452 }
453
454 @Test
455 public void nodeCanBeAddedDuringLayout() {
456 final Rectangle rect = new Rectangle(100, 100);
457 final Group g = new Group(rect);
458
459 Group root = new Group() {
460 @Override protected void layoutChildren() {
461 getChildren().setAll(g);
462 }
463 };
464
465 Scene scene = new Scene(root);
466
467 stage.setScene(scene);
468 stage.show();
469
470 // there are assertions tested down the stack (see RT-21746)
471 }
472
473 private static class LGroup extends Group {
474
475 private boolean layoutCalled;
476
477 @Override
478 public void requestLayout() {
479 super.requestLayout();
480 layoutCalled = true;
481 }
482
483 public void assertAndClear(boolean b) {
484 assertEquals(b, layoutCalled);
485 layoutCalled = false;
486 }
487
488 public void clear() {
489 layoutCalled = false;
490 }
491
492 }
493
494 @Test
495 public void requestLayoutAlwaysCalledUpToTheLayoutRoot() {
496 final Group root = new Group();
497 final LGroup lroot = new LGroup();
498 lroot.setManaged(false);
499 root.getChildren().add(lroot);
500 final LGroup sub = new LGroup();
501 lroot.getChildren().add(sub);
502
503 lroot.clear();
504 sub.clear();
505 root.layout();
506
507 lroot.assertAndClear(false);
508 sub.assertAndClear(false);
509
510 sub.requestLayout();
511
512 lroot.assertAndClear(true);
513 sub.assertAndClear(true);
514
515 sub.requestLayout();
516 lroot.assertAndClear(true);
517 sub.assertAndClear(true);
518 }
519
520 @Test
521 public void unmanagedParentTest() {
547 outerGroup.getChildren().add(intermediate);
548
549 innerGroup.assertAndClear(false);
550 intermediate.assertAndClear(true);
551 outerGroup.assertAndClear(true);
552
553 innerGroup.requestLayout();
554 intermediate.getChildren().add(innerGroup);
555
556 innerGroup.assertAndClear(true);
557 intermediate.assertAndClear(true);
558 outerGroup.assertAndClear(false);
559
560 }
561
562 @Test
563 public void requestLayoutTriggersPulse() {
564 final Group root = new Group();
565 final LGroup lroot = new LGroup();
566 lroot.setManaged(false);
567 root.getChildren().add(lroot);
568 final LGroup sub = new LGroup();
569 lroot.getChildren().add(sub);
570
571 toolkit.clearPulseRequested();
572 sub.requestLayout();
573 Scene scene = new Scene(root);
574 assertTrue(toolkit.isPulseRequested());
575 toolkit.clearPulseRequested();
576 root.layout();
577
578 sub.requestLayout();
579
580 assertTrue(toolkit.isPulseRequested());
581 }
582
583 @Test
584 public void requestLayoutNotPropagatingDuringLayout() {
585 final LGroup lroot = new LGroup();
586 lroot.setManaged(false);
587 final LGroup sub = new LGroup() {
588
589 @Override
590 protected void layoutChildren() {
591 super.layoutChildren();
592 requestLayout();
593 }
594
595 };
596 lroot.getChildren().add(sub);
597 lroot.clear();
598 sub.clear();
599
600 sub.requestLayout();
601 lroot.assertAndClear(true);
602 sub.assertAndClear(true);
603
604 lroot.layout();
605
606 lroot.assertAndClear(false);
607 sub.assertAndClear(true);
608 }
609
610 @Test
611 public void testChildrenPermutationInvalidatesManagedChildrenAndLayout() {
612 LGroup root = new LGroup();
613 Rectangle r1 = new Rectangle();
614 Rectangle r2 = new Rectangle();
615
616 root.getChildren().addAll(r1, r2);
617
618 root.clear();
619
620 root.getManagedChildren().equals(root.getChildren());
621
622 root.getChildren().setAll(r2, r1);
623
624 root.getManagedChildren().equals(root.getChildren());
625 root.assertAndClear(true);
626
627 r2.toFront();
628
629 root.getManagedChildren().equals(root.getChildren());
630 root.assertAndClear(true);
631 }
632
633 @Test
634 public void newChildInvalidatesLayoutWhenLayoutBoundsAreValidatedImmediately() {
635 Group root = new Group();
636 final AtomicBoolean layoutCalled = new AtomicBoolean();
637 final AtomicBoolean testReady = new AtomicBoolean();
638 LGroup sub = new LGroup() {
639
640 @Override
641 protected void layoutChildren() {
642 if (testReady.get()) {
643 assertAndClear(true);
644 layoutCalled.set(true);
645 }
646 }
647
648 };
649 root.getChildren().add(sub);
650 root.getLayoutBounds(); // validate
651 sub.getBoundsInParent(); // validate
652
653 root.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> {
654 // ChangeListener will immediately validate the bounds
655 });
656 sub.clear();
657
658 testReady.set(true);
659 sub.getChildren().add(new Rectangle());
660 assertTrue(layoutCalled.get());
661 }
662
663 @Test
664 public void sceneListenerCanAddChild() {
665 final Group root = new Group();
666 final Scene scene = new Scene(root, 600, 450);
667
668 final Group child = new Group(new Group(), new Group(), new Group());
669
670 child.getChildren().get(1).sceneProperty().addListener(o -> child.getChildren().add(2, new Group()));
671
672 root.getChildren().add(child);
673
674 assertSame(scene, child.getChildren().get(3).getScene());
675 }
676
677 public static class MockParent extends Parent {
678 public MockParent(Node... children) {
679 getChildren().addAll(children);
680 }
681 }
682 }
|
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
26 package test.javafx.scene;
27
28 import test.com.sun.javafx.pgstub.StubToolkit;
29 import com.sun.javafx.sg.prism.NGGroup;
30 import com.sun.javafx.tk.Toolkit;
31 import java.util.concurrent.atomic.AtomicBoolean;
32 import javafx.scene.Group;
33 import javafx.scene.GroupShim;
34 import javafx.scene.Node;
35 import javafx.scene.Parent;
36 import javafx.scene.ParentShim;
37 import javafx.scene.Scene;
38 import javafx.scene.shape.Rectangle;
39 import javafx.stage.Stage;
40 import org.junit.After;
41 import org.junit.Before;
42 import org.junit.Test;
43
44 import static org.junit.Assert.*;
45
46 public class ParentTest {
47 private StubToolkit toolkit;
48 private Stage stage;
49
50 @Before
51 public void setUp() {
52 toolkit = (StubToolkit) Toolkit.getToolkit();
53 stage = new Stage();
54 }
55
56 @After
57 public void tearDown() {
133 groupD.setId("d");
134 Group group = new Group(rectA, rectB, rectC, groupD, rectE, rectF);
135
136 assertNull(group.lookup("#4444"));
137 }
138
139 @Test
140 public void testRemoveChild() {
141 Rectangle rect1 = new Rectangle();
142 Rectangle rect2 = new Rectangle();
143 Rectangle rect3 = new Rectangle();
144 Rectangle rect4 = new Rectangle();
145 Rectangle rect5 = new Rectangle();
146 Rectangle rect6 = new Rectangle();
147
148 Group g = new Group();
149 Scene s = new Scene(g);
150 stage.setScene(s);
151 stage.show();
152
153 ParentShim.getChildren(g).addAll(rect1, rect2, rect3, rect4, rect5, rect6);
154 toolkit.fireTestPulse();
155
156 // try removing node from the end of the observableArrayList
157 ParentShim.getChildren(g).remove(rect6);
158 toolkit.fireTestPulse();
159 final NGGroup peer = g.impl_getPeer();
160 assertEquals(5, ParentShim.getChildren(g).size());
161 assertEquals(5, peer.getChildren().size());
162
163 // try removing node from the beginning of the observableArrayList
164 ParentShim.getChildren(g).remove(rect1);
165 toolkit.fireTestPulse();
166 assertEquals(4, ParentShim.getChildren(g).size());
167 assertEquals(4, peer.getChildren().size());
168
169 // try removing node from the middle of the observableArrayList
170 ParentShim.getChildren(g).remove(rect3);
171 toolkit.fireTestPulse();
172 assertEquals(3, ParentShim.getChildren(g).size());
173 assertEquals(3, peer.getChildren().size());
174 }
175
176 @Test
177 public void testSetChild() {
178 Rectangle rect1 = new Rectangle();
179 Rectangle rect2 = new Rectangle();
180 Rectangle rect3 = new Rectangle();
181
182 Group g = new Group();
183 Scene s = new Scene(g);
184 stage.setScene(s);
185 stage.show();
186
187 ParentShim.getChildren(g).addAll(rect1, rect2);
188 toolkit.fireTestPulse();
189
190 // try setting node at given index
191 ParentShim.getChildren(g).set(1, rect3);
192 toolkit.fireTestPulse();
193 assertEquals(2, ParentShim.getChildren(g).size());
194 assertEquals(2, ((NGGroup)g.impl_getPeer()).getChildren().size());
195 }
196
197 @Test
198 public void testSetSameChild() {
199 Rectangle rect1 = new Rectangle();
200 Rectangle rect2 = new Rectangle();
201
202 Group g = new Group();
203 Scene s = new Scene(g);
204 stage.setScene(s);
205 stage.show();
206
207 ParentShim.getChildren(g).addAll(rect1, rect2);
208 toolkit.fireTestPulse();
209
210 // try setting the same node at given index
211 ParentShim.getChildren(g).set(1, rect2);
212
213 toolkit.fireTestPulse();
214 assertEquals(2, ParentShim.getChildren(g).size());
215 assertEquals(2, ((NGGroup)g.impl_getPeer()).getChildren().size());
216 }
217
218 @Test
219 public void testRemoveAddSameChild() {
220 Rectangle rect1 = new Rectangle();
221 Rectangle rect2 = new Rectangle();
222 Rectangle rect3 = new Rectangle();
223 Rectangle rect4 = new Rectangle();
224 Rectangle rect5 = new Rectangle();
225 Rectangle rect6 = new Rectangle();
226
227 Group g = new Group();
228 Scene s = new Scene(g);
229 stage.setScene(s);
230 stage.show();
231
232 ParentShim.getChildren(g).addAll(rect1, rect2, rect3, rect4, rect5, rect6);
233 toolkit.fireTestPulse();
234
235 // try removing node from the end of the observableArrayList
236 // and add it afterwords
237 ParentShim.getChildren(g).remove(rect6);
238 ParentShim.getChildren(g).add(rect6);
239 toolkit.fireTestPulse();
240 assertEquals(6, ParentShim.getChildren(g).size());
241 assertEquals(6, ((NGGroup)g.impl_getPeer()).getChildren().size());
242 }
243
244 @Test
245 public void testRemoveAddDiferentChild() {
246 Rectangle rect1 = new Rectangle();
247 Rectangle rect2 = new Rectangle();
248 Rectangle rect3 = new Rectangle();
249 Rectangle rect4 = new Rectangle();
250 Rectangle rect5 = new Rectangle();
251 Rectangle rect6 = new Rectangle();
252
253 Group g = new Group();
254 Scene s = new Scene(g);
255 stage.setScene(s);
256 stage.show();
257
258 ParentShim.getChildren(g).addAll(rect1, rect2, rect3, rect4, rect5);
259 toolkit.fireTestPulse();
260
261 // try removing node from the end of the observableArrayList
262 // and add a different one
263 ParentShim.getChildren(g).remove(rect5);
264 ParentShim.getChildren(g).add(rect6);
265 toolkit.fireTestPulse();
266 assertEquals(5, ParentShim.getChildren(g).size());
267 assertEquals(5, ((NGGroup)g.impl_getPeer()).getChildren().size());
268 }
269
270 @Test
271 public void testGetChildrenUnmodifiable() {
272 Rectangle rect1 = new Rectangle();
273 Rectangle rect2 = new Rectangle();
274 Rectangle rect3 = new Rectangle();
275
276 Group g = new Group();
277 ParentShim.getChildren(g).addAll(rect1,rect2,rect3);
278
279 assertEquals(3, g.getChildrenUnmodifiable().size());
280 assertSame(rect1, g.getChildrenUnmodifiable().get(0));
281 assertSame(rect2, g.getChildrenUnmodifiable().get(1));
282 assertSame(rect3, g.getChildrenUnmodifiable().get(2));
283 }
284
285 @Test
286 public void testGetChildrenUnmodifiableCantBeModified() {
287 Rectangle rect1 = new Rectangle();
288 Rectangle rect2 = new Rectangle();
289 Rectangle rect3 = new Rectangle();
290
291 Group g = new Group();
292 ParentShim.getChildren(g).addAll(rect1,rect2,rect3);
293
294 try {
295 g.getChildrenUnmodifiable().add(new Rectangle());
296 fail("UnsupportedOperationException should have been thrown.");
297 } catch (UnsupportedOperationException uoe) {
298 // expected
299 }
300 }
301
302 @Test
303 public void testRequestLayoutWithoutParent() {
304 Group g = new Group();
305 g.layout();
306 // this shouldn't fail even when the group doesn't have a parent
307 g.requestLayout();
308 }
309
310 @Test
311 public void testRequestLayoutWithoutScene() {
312 Group g = new Group();
313 g.setManaged(false);
314 g.layout();
315 // this shouldn't fail even when the scene is not set
316 g.requestLayout();
317 }
318
319 @Test
320 public void testRequestLayoutClearsCache() {
321 Group g = new Group();
322 Rectangle r = new Rectangle(100,200);
323 ParentShim.getChildren(g).add(r);
324
325 g.requestLayout();
326 assertEquals(100, g.prefWidth(-1), 1e-100);
327 assertEquals(200, g.prefHeight(-1), 1e-100);
328
329 r.setWidth(150);
330 r.setHeight(250);
331 g.requestLayout();
332
333 assertEquals(150, g.prefWidth(-1), 1e-100);
334 assertEquals(250, g.prefHeight(-1), 1e-100);
335 }
336
337 @Test
338 public void testPrefWidthIncludesChildLayoutX() {
339 Rectangle r = new Rectangle(10,10,100,100);
340 r.setLayoutX(10);
341 MockParent p = new MockParent(r);
342
343 assertEquals(120, p.prefWidth(-1), 0);
345
346 @Test
347 public void testPrefHeightIncludesChildLayoutY() {
348 Rectangle r = new Rectangle(10,10,100,100);
349 r.setLayoutY(10);
350 MockParent p = new MockParent(r);
351
352 assertEquals(120, p.prefHeight(-1), 0);
353 }
354
355 @Test
356 public void testDuplicates() {
357 Group g = new Group();
358
359 Rectangle r1 = new Rectangle();
360 Rectangle r2 = new Rectangle();
361 Rectangle r3 = new Rectangle();
362 Rectangle r4 = new Rectangle();
363
364 try {
365 ParentShim.getChildren(g).addAll(r1, r2, r3, r4);
366 ParentShim.getChildren(g).add(r2);
367 fail();
368 } catch (IllegalArgumentException e) {
369
370 }
371 }
372
373 @Test(expected=NullPointerException.class)
374 public void testAddingNullChild() {
375 Group g = new Group();
376 ParentShim.getChildren(g).add(null);
377 }
378
379 @Test(expected=NullPointerException.class)
380 public void testNullCheckIsDoneBeforeTestForDuplicates() {
381 Group g = new Group();
382 ParentShim.getChildren(g).addAll(null, new Rectangle(), null);
383 }
384
385 @Test(expected=IllegalArgumentException.class)
386 public void testAddingClipNodeTwice() {
387 Group g = new Group();
388
389 Node clipParent = new Rectangle();
390 Node clipNode = new Rectangle();
391
392 clipParent.setClip(clipNode);
393 try {
394 // try to add node which is already set as a clip
395 ParentShim.getChildren(g).add(clipNode);
396 fail();
397 } catch (IllegalArgumentException e) {
398 }
399
400 // try again
401 ParentShim.getChildren(g).add(clipNode);
402 }
403
404 @Test
405 public void testAddingFixedClipNode() {
406 Group g = new Group();
407
408 Node clipParent = new Rectangle();
409 Node clipNode = new Rectangle();
410
411 clipParent.setClip(clipNode);
412 try {
413 // try to add node which is already set as a clip
414 ParentShim.getChildren(g).add(clipNode);
415 fail();
416 } catch (IllegalArgumentException e) {
417 }
418
419 // fix the problem and add again
420 clipParent.setClip(null);
421 ParentShim.getChildren(g).add(clipNode);
422 }
423
424 @Test(expected=IllegalArgumentException.class)
425 public void testFalsePermutation() {
426 Group g = new Group();
427
428 Rectangle r1 = new Rectangle();
429 Rectangle r2 = new Rectangle();
430 Rectangle r3 = new Rectangle();
431 Rectangle r4 = new Rectangle();
432
433 ParentShim.getChildren(g).addAll(r1, r2, r3, r4);
434 ParentShim.getChildren(g).setAll(r1, r2, r2, r4);
435 }
436
437 @Test
438 public void testFalseDuplicates() {
439 Group g = new Group();
440
441 Rectangle r1 = new Rectangle();
442 Rectangle r2 = new Rectangle();
443 Rectangle r3 = new Rectangle();
444 Rectangle r4 = new Rectangle();
445
446 ParentShim.getChildren(g).addAll(r1, r2);
447 try {
448 ParentShim.getChildren(g).addAll(r3, r4, r2);
449 fail();
450 } catch (IllegalArgumentException e) {
451 }
452 try {
453 ParentShim.getChildren(g).add(r3);
454 } catch (IllegalArgumentException e) {
455 fail();
456 }
457
458 }
459
460 @Test
461 public void nodeCanBeAddedDuringLayout() {
462 final Rectangle rect = new Rectangle(100, 100);
463 final Group g = new Group(rect);
464
465 Group root = new Group() {
466 @Override protected void layoutChildren() {
467 ParentShim.getChildren(this).setAll(g);
468 }
469 };
470
471 Scene scene = new Scene(root);
472
473 stage.setScene(scene);
474 stage.show();
475
476 // there are assertions tested down the stack (see RT-21746)
477 }
478
479 private static class LGroup extends Group {
480
481 private boolean layoutCalled;
482
483 @Override
484 public void requestLayout() {
485 super.requestLayout();
486 layoutCalled = true;
487 }
488
489 public void assertAndClear(boolean b) {
490 assertEquals(b, layoutCalled);
491 layoutCalled = false;
492 }
493
494 public void clear() {
495 layoutCalled = false;
496 }
497
498 }
499
500 @Test
501 public void requestLayoutAlwaysCalledUpToTheLayoutRoot() {
502 final Group root = new Group();
503 final LGroup lroot = new LGroup();
504 lroot.setManaged(false);
505 ParentShim.getChildren(root).add(lroot);
506 final LGroup sub = new LGroup();
507 ParentShim.getChildren(lroot).add(sub);
508
509 lroot.clear();
510 sub.clear();
511 root.layout();
512
513 lroot.assertAndClear(false);
514 sub.assertAndClear(false);
515
516 sub.requestLayout();
517
518 lroot.assertAndClear(true);
519 sub.assertAndClear(true);
520
521 sub.requestLayout();
522 lroot.assertAndClear(true);
523 sub.assertAndClear(true);
524 }
525
526 @Test
527 public void unmanagedParentTest() {
553 outerGroup.getChildren().add(intermediate);
554
555 innerGroup.assertAndClear(false);
556 intermediate.assertAndClear(true);
557 outerGroup.assertAndClear(true);
558
559 innerGroup.requestLayout();
560 intermediate.getChildren().add(innerGroup);
561
562 innerGroup.assertAndClear(true);
563 intermediate.assertAndClear(true);
564 outerGroup.assertAndClear(false);
565
566 }
567
568 @Test
569 public void requestLayoutTriggersPulse() {
570 final Group root = new Group();
571 final LGroup lroot = new LGroup();
572 lroot.setManaged(false);
573 ParentShim.getChildren(root).add(lroot);
574 final LGroup sub = new LGroup();
575 ParentShim.getChildren(lroot).add(sub);
576
577 toolkit.clearPulseRequested();
578 sub.requestLayout();
579 Scene scene = new Scene(root);
580 assertTrue(toolkit.isPulseRequested());
581 toolkit.clearPulseRequested();
582 root.layout();
583
584 sub.requestLayout();
585
586 assertTrue(toolkit.isPulseRequested());
587 }
588
589 @Test
590 public void requestLayoutNotPropagatingDuringLayout() {
591 final LGroup lroot = new LGroup();
592 lroot.setManaged(false);
593 final LGroup sub = new LGroup() {
594
595 @Override
596 protected void layoutChildren() {
597 GroupShim.layoutChildren((Group)getParent());
598 requestLayout();
599 }
600
601 };
602 ParentShim.getChildren(lroot).add(sub);
603 lroot.clear();
604 sub.clear();
605
606 sub.requestLayout();
607 lroot.assertAndClear(true);
608 sub.assertAndClear(true);
609
610 lroot.layout();
611
612 lroot.assertAndClear(false);
613 sub.assertAndClear(true);
614 }
615
616 @Test
617 public void testChildrenPermutationInvalidatesManagedChildrenAndLayout() {
618 LGroup root = new LGroup();
619 Rectangle r1 = new Rectangle();
620 Rectangle r2 = new Rectangle();
621
622 ParentShim.getChildren(root).addAll(r1, r2);
623
624 root.clear();
625
626 ParentShim.getManagedChildren(root).equals(ParentShim.getChildren(root));
627
628 ParentShim.getChildren(root).setAll(r2, r1);
629
630 ParentShim.getManagedChildren(root).equals(ParentShim.getChildren(root));
631 root.assertAndClear(true);
632
633 r2.toFront();
634
635 ParentShim.getManagedChildren(root).equals(ParentShim.getChildren(root));
636 root.assertAndClear(true);
637 }
638
639 @Test
640 public void newChildInvalidatesLayoutWhenLayoutBoundsAreValidatedImmediately() {
641 Group root = new Group();
642 final AtomicBoolean layoutCalled = new AtomicBoolean();
643 final AtomicBoolean testReady = new AtomicBoolean();
644 LGroup sub = new LGroup() {
645
646 @Override
647 protected void layoutChildren() {
648 if (testReady.get()) {
649 assertAndClear(true);
650 layoutCalled.set(true);
651 }
652 }
653
654 };
655 ParentShim.getChildren(root).add(sub);
656 root.getLayoutBounds(); // validate
657 sub.getBoundsInParent(); // validate
658
659 root.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> {
660 // ChangeListener will immediately validate the bounds
661 });
662 sub.clear();
663
664 testReady.set(true);
665 ParentShim.getChildren(sub).add(new Rectangle());
666 assertTrue(layoutCalled.get());
667 }
668
669 @Test
670 public void sceneListenerCanAddChild() {
671 final Group root = new Group();
672 final Scene scene = new Scene(root, 600, 450);
673
674 final Group child = new Group(new Group(), new Group(), new Group());
675
676 ParentShim.getChildren(child).get(1).sceneProperty().addListener(o -> ParentShim.getChildren(child).add(2, new Group()));
677
678 ParentShim.getChildren(root).add(child);
679
680 assertSame(scene, ParentShim.getChildren(child).get(3).getScene());
681 }
682
683 public static class MockParent extends Parent {
684 public MockParent(Node... children) {
685 ParentShim.getChildren(this).addAll(children);
686 }
687 }
688 }
|