modules/controls/src/main/java/javafx/scene/control/skin/AccordionSkin.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -21,27 +21,43 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
-package com.sun.javafx.scene.control.skin;
+package javafx.scene.control.skin;
 
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
 import javafx.beans.value.ChangeListener;
 import javafx.collections.ListChangeListener;
 import javafx.scene.Node;
 import javafx.scene.control.Accordion;
+import javafx.scene.control.Button;
+import javafx.scene.control.Control;
 import javafx.scene.control.Skin;
+import javafx.scene.control.SkinBase;
 import javafx.scene.control.TitledPane;
 import javafx.scene.shape.Rectangle;
 
 import com.sun.javafx.scene.control.behavior.AccordionBehavior;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-public class AccordionSkin extends BehaviorSkinBase<Accordion, AccordionBehavior> {
+/**
+ * Default skin implementation for the {@link Accordion} control.
+ *
+ * @see Accordion
+ * @since 9
+ */
+public class AccordionSkin extends SkinBase<Accordion> {
+
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
 
     private TitledPane firstTitledPane;
     private Rectangle clipRect;
 
     // This is used when we definitely want to force a relayout, regardless of

@@ -52,59 +68,94 @@
     private boolean relayout = false;
 
     // we record the previous height to know if the current height is different
     private double previousHeight = 0;
 
-    public AccordionSkin(final Accordion accordion) {
-        super(accordion, new AccordionBehavior(accordion));
-        accordion.getPanes().addListener((ListChangeListener<TitledPane>) c -> {
+    private TitledPane expandedPane = null;
+    private TitledPane previousPane = null;
+    private Map<TitledPane, ChangeListener<Boolean>>listeners = new HashMap<>();
+
+    private final BehaviorBase<Accordion> behavior;
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a new AccordionSkin instance, installing the necessary child
+     * nodes into the Control {@link Control#getChildren() children} list, as
+     * well as the necessary input mappings for handling key, mouse, etc events.
+     *
+     * @param control The control that this skin should be installed onto.
+     */
+    public AccordionSkin(final Accordion control) {
+        super(control);
+
+        // install default input map for the accordion control
+        behavior = new AccordionBehavior(control);
+//        control.setInputMap(behavior.getInputMap());
+
+        control.getPanes().addListener((ListChangeListener<TitledPane>) c -> {
             if (firstTitledPane != null) {
                 firstTitledPane.getStyleClass().remove("first-titled-pane");
             }
-            if (!accordion.getPanes().isEmpty()) {
-                firstTitledPane = accordion.getPanes().get(0);
+            if (!control.getPanes().isEmpty()) {
+                firstTitledPane = control.getPanes().get(0);
                 firstTitledPane.getStyleClass().add("first-titled-pane");
             }
             // TODO there may be a more efficient way to keep these in sync
-            getChildren().setAll(accordion.getPanes());
+            getChildren().setAll(control.getPanes());
             while (c.next()) {
                 removeTitledPaneListeners(c.getRemoved());
                 initTitledPaneListeners(c.getAddedSubList());
             }
 
             // added to resolve RT-32787
             forceRelayout = true;
         });
 
-        if (!accordion.getPanes().isEmpty()) {
-            firstTitledPane = accordion.getPanes().get(0);
+        if (!control.getPanes().isEmpty()) {
+            firstTitledPane = control.getPanes().get(0);
             firstTitledPane.getStyleClass().add("first-titled-pane");
         }
 
-        clipRect = new Rectangle(accordion.getWidth(), accordion.getHeight());
+        clipRect = new Rectangle(control.getWidth(), control.getHeight());
         getSkinnable().setClip(clipRect);
 
-        initTitledPaneListeners(accordion.getPanes());
-        getChildren().setAll(accordion.getPanes());
+        initTitledPaneListeners(control.getPanes());
+        getChildren().setAll(control.getPanes());
         getSkinnable().requestLayout();
 
-        registerChangeListener(getSkinnable().widthProperty(), "WIDTH");
-        registerChangeListener(getSkinnable().heightProperty(), "HEIGHT");
-    }
-
-    @Override
-    protected void handleControlPropertyChanged(String property) {
-        super.handleControlPropertyChanged(property);
-        if ("WIDTH".equals(property)) {
-            clipRect.setWidth(getSkinnable().getWidth());
-        } else if ("HEIGHT".equals(property)) {
+        registerChangeListener(getSkinnable().widthProperty(), e -> clipRect.setWidth(getSkinnable().getWidth()));
+        registerChangeListener(getSkinnable().heightProperty(), e -> {
             clipRect.setHeight(getSkinnable().getHeight());
             relayout = true;
+        });
         }
-    }
 
 
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override public void dispose() {
+        super.dispose();
+
+        if (behavior != null) {
+            behavior.dispose();
+        }
+    }
+
+    /** {@inheritDoc} */
     @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
         double h = 0;
 
         if (expandedPane != null) {
             h += expandedPane.minHeight(width);

@@ -128,10 +179,11 @@
         }
 
         return h + topInset + bottomInset;
     }
 
+    /** {@inheritDoc} */
     @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
         double h = 0;
 
         if (expandedPane != null) {
             h += expandedPane.prefHeight(width);

@@ -155,10 +207,11 @@
         }
 
         return h + topInset + bottomInset;
     }
 
+    /** {@inheritDoc} */
     @Override protected void layoutChildren(final double x, double y,
             final double w, final double h) {
         final boolean rebuild = forceRelayout || (relayout && previousHeight != h);
         forceRelayout = false;
         previousHeight = h;

@@ -222,13 +275,17 @@
                 y += ph;
             }
         }
     }
 
-    private TitledPane expandedPane = null;
-    private TitledPane previousPane = null;
-    private Map<TitledPane, ChangeListener<Boolean>>listeners = new HashMap<TitledPane, ChangeListener<Boolean>>();
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private implementation                                                  *
+     *                                                                         *
+     **************************************************************************/
 
     private void initTitledPaneListeners(List<? extends TitledPane> list) {
         for (final TitledPane tp: list) {
             tp.setExpanded(tp == getSkinnable().getExpandedPane());
             if (tp.isExpanded()) {