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()) {