View Javadoc
1   /*
2    * Tethys: GUI Utilities
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.tethys.javafx.pane;
18  
19  import javafx.geometry.Pos;
20  import javafx.scene.Node;
21  import javafx.scene.layout.HBox;
22  import javafx.scene.layout.Pane;
23  import javafx.scene.layout.Priority;
24  import javafx.scene.layout.Region;
25  import javafx.scene.layout.VBox;
26  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
27  import io.github.tonywasher.joceanus.tethys.core.base.TethysUICoreComponent;
28  import io.github.tonywasher.joceanus.tethys.core.factory.TethysUICoreFactory;
29  import io.github.tonywasher.joceanus.tethys.core.pane.TethysUICoreBoxPaneManager;
30  import io.github.tonywasher.joceanus.tethys.javafx.base.TethysUIFXNode;
31  
32  import java.util.Iterator;
33  
34  /**
35   * FX Box Pane Manager.
36   */
37  public class TethysUIFXBoxPaneManager
38          extends TethysUICoreBoxPaneManager {
39      /**
40       * The Node.
41       */
42      private final TethysUIFXNode theNode;
43  
44      /**
45       * The BoxPane.
46       */
47      private final Pane theBoxPane;
48  
49      /**
50       * Is the Box horizontal?
51       */
52      private final boolean isHorizontal;
53  
54      /**
55       * Constructor.
56       *
57       * @param pFactory    the factory
58       * @param pHorizontal horizontal box true/false
59       */
60      TethysUIFXBoxPaneManager(final TethysUICoreFactory<?> pFactory,
61                               final boolean pHorizontal) {
62          super(pFactory);
63          isHorizontal = pHorizontal;
64          if (isHorizontal) {
65              final HBox myBox = new HBox(getGap());
66              myBox.setAlignment(Pos.CENTER);
67              theBoxPane = myBox;
68          } else {
69              final VBox myBox = new VBox(getGap());
70              myBox.setAlignment(Pos.CENTER);
71              theBoxPane = myBox;
72          }
73          theNode = new TethysUIFXNode(theBoxPane);
74      }
75  
76      @Override
77      public TethysUIFXNode getNode() {
78          return theNode;
79      }
80  
81      @Override
82      public void setVisible(final boolean pVisible) {
83          theNode.setManaged(pVisible);
84          theNode.setVisible(pVisible);
85      }
86  
87      @Override
88      public void addNode(final TethysUIComponent pNode) {
89          super.addNode(pNode);
90          theBoxPane.getChildren().add(TethysUIFXNode.getNode(pNode));
91      }
92  
93      @Override
94      public void setChildVisible(final TethysUIComponent pChild,
95                                  final boolean pVisible) {
96          /* Handle nothing to do */
97          final Node myChildNode = TethysUIFXNode.getNode(pChild);
98          final boolean isVisible = myChildNode.isVisible();
99          if (isVisible == pVisible) {
100             return;
101         }
102 
103         /* If the node is not visible */
104         if (pVisible) {
105             /* Count visible prior siblings */
106             final int myId = pChild.getId();
107             int myIndex = 0;
108             final Iterator<TethysUIComponent> myIterator = iterator();
109             while (myIterator.hasNext()) {
110                 final TethysUIComponent myNode = myIterator.next();
111                 final Integer myNodeId = myNode.getId();
112 
113                 /* If we have found the node */
114                 if (myNodeId == myId) {
115                     /* Set visible and add into the list */
116                     myChildNode.setVisible(true);
117                     theBoxPane.getChildren().add(myIndex, myChildNode);
118                     break;
119                 }
120 
121                 /* Increment count if node is visible */
122                 if (TethysUIFXNode.getNode(myNode).isVisible()) {
123                     myIndex++;
124                 }
125             }
126 
127             /* else we must hide the node */
128         } else {
129             /* set invisible and remove from the list */
130             myChildNode.setVisible(false);
131             theBoxPane.getChildren().remove(myChildNode);
132         }
133     }
134 
135     @Override
136     public void setGap(final Integer pGap) {
137         super.setGap(pGap);
138         if (theBoxPane instanceof HBox myBox) {
139             myBox.setSpacing(getGap());
140         } else if (theBoxPane instanceof VBox myBox) {
141             myBox.setSpacing(getGap());
142         }
143     }
144 
145     @Override
146     public void setPreferredWidth(final Integer pWidth) {
147         theBoxPane.setPrefWidth(pWidth);
148     }
149 
150     @Override
151     public void setPreferredHeight(final Integer pHeight) {
152         theBoxPane.setPrefHeight(pHeight);
153     }
154 
155     @Override
156     public void setBorderPadding(final Integer pPadding) {
157         super.setBorderPadding(pPadding);
158         theNode.createWrapperPane(getBorderTitle(), getBorderPadding());
159     }
160 
161     @Override
162     public void setBorderTitle(final String pTitle) {
163         super.setBorderTitle(pTitle);
164         theNode.createWrapperPane(getBorderTitle(), getBorderPadding());
165     }
166 
167     @Override
168     public void addSpacer() {
169         final TethysUIFXSpacer mySpacer = new TethysUIFXSpacer(true);
170         addSpacerNode(mySpacer);
171         theBoxPane.getChildren().add(TethysUIFXNode.getNode(mySpacer));
172     }
173 
174     @Override
175     public void addStrut() {
176         final TethysUIFXSpacer mySpacer = new TethysUIFXSpacer(false);
177         addSpacerNode(mySpacer);
178         theBoxPane.getChildren().add(TethysUIFXNode.getNode(mySpacer));
179     }
180 
181     /**
182      * Spacer node.
183      */
184     private final class TethysUIFXSpacer
185             extends TethysUICoreComponent {
186         /**
187          * The Node.
188          */
189         private final TethysUIFXNode theNode;
190 
191         /**
192          * Region.
193          */
194         private final Region theRegion;
195 
196         /**
197          * Constructor.
198          *
199          * @param pExpand true/false
200          */
201         TethysUIFXSpacer(final boolean pExpand) {
202             theRegion = new Region();
203             theRegion.setPrefWidth(getGap());
204             theRegion.setPrefHeight(getGap());
205             if (pExpand) {
206                 if (isHorizontal) {
207                     HBox.setHgrow(theRegion, Priority.ALWAYS);
208                     theRegion.setMaxWidth(Double.MAX_VALUE);
209                 } else {
210                     VBox.setVgrow(theRegion, Priority.ALWAYS);
211                     theRegion.setMaxHeight(Double.MAX_VALUE);
212                 }
213             }
214             theNode = new TethysUIFXNode(theRegion);
215         }
216 
217         @Override
218         public TethysUIFXNode getNode() {
219             return theNode;
220         }
221 
222         @Override
223         public void setEnabled(final boolean pEnabled) {
224             theRegion.setDisable(!pEnabled);
225         }
226 
227         @Override
228         public void setVisible(final boolean pVisible) {
229             theRegion.setVisible(pVisible);
230         }
231 
232         @Override
233         public void setPreferredWidth(final Integer pWidth) {
234             /* NoOp */
235         }
236 
237         @Override
238         public void setPreferredHeight(final Integer pHeight) {
239             /* NoOp */
240         }
241 
242         @Override
243         public Integer getId() {
244             return -1;
245         }
246     }
247 }