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.swing.field;
18  
19  import io.github.tonywasher.joceanus.oceanus.event.OceanusEvent;
20  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
21  import io.github.tonywasher.joceanus.tethys.api.button.TethysUIListButtonManager;
22  import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIListButtonField;
23  import io.github.tonywasher.joceanus.tethys.core.factory.TethysUICoreFactory;
24  import io.github.tonywasher.joceanus.tethys.swing.base.TethysUISwingNode;
25  import io.github.tonywasher.joceanus.tethys.swing.button.TethysUISwingListButtonManager;
26  import io.github.tonywasher.joceanus.tethys.swing.menu.TethysUISwingScrollMenu;
27  
28  import javax.swing.JButton;
29  import javax.swing.JLabel;
30  import javax.swing.SwingConstants;
31  import java.awt.Rectangle;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.function.Supplier;
35  
36  /**
37   * ListButtonField class.
38   *
39   * @param <T> the data type
40   */
41  public class TethysUISwingListButtonField<T extends Comparable<? super T>>
42          extends TethysUISwingDataTextField<List<T>>
43          implements TethysUIListButtonField<T> {
44      /**
45       * The icon manager.
46       */
47      private final TethysUISwingListButtonManager<T> theManager;
48  
49      /**
50       * Are we editing a cell?
51       */
52      private boolean isCellEditing;
53  
54      /**
55       * Constructor.
56       *
57       * @param pFactory the GUI factory
58       */
59      TethysUISwingListButtonField(final TethysUICoreFactory<?> pFactory) {
60          this(pFactory, new JLabel());
61      }
62  
63      /**
64       * Constructor.
65       *
66       * @param pFactory the GUI factory
67       * @param pLabel   the label
68       */
69      private TethysUISwingListButtonField(final TethysUICoreFactory<?> pFactory,
70                                           final JLabel pLabel) {
71          this(pFactory, pFactory.buttonFactory().newListButton(), pLabel);
72      }
73  
74      /**
75       * Constructor.
76       *
77       * @param pFactory the GUI factory
78       * @param pManager the manager
79       * @param pLabel   the label
80       */
81      private TethysUISwingListButtonField(final TethysUICoreFactory<?> pFactory,
82                                           final TethysUIListButtonManager<T> pManager,
83                                           final JLabel pLabel) {
84          /* Initialise underlying class */
85          super(pFactory, TethysUISwingNode.getComponent(pManager), pLabel);
86  
87          /* Store the manager and button */
88          theManager = (TethysUISwingListButtonManager<T>) pManager;
89  
90          /* Set listener on manager */
91          pManager.getEventRegistrar().addEventListener(this::handleEvent);
92          theManager.getMenu().getEventRegistrar().addEventListener(TethysUIEvent.WINDOWCLOSED, e -> haltCellEditing());
93      }
94  
95      @SuppressWarnings("unchecked")
96      @Override
97      public List<T> getCastValue(final Object pValue) {
98          return (List<T>) pValue;
99      }
100 
101     /**
102      * handle List Button event.
103      *
104      * @param pEvent the even
105      */
106     private void handleEvent(final OceanusEvent<TethysUIEvent> pEvent) {
107         switch (pEvent.getEventId()) {
108             case NEWVALUE:
109                 setValue(theManager.getValue());
110                 fireEvent(TethysUIEvent.NEWVALUE, pEvent.getDetails());
111                 break;
112             case EDITFOCUSLOST:
113                 haltCellEditing();
114                 break;
115             default:
116                 break;
117         }
118     }
119 
120     @Override
121     public JButton getEditControl() {
122         return (JButton) super.getEditControl();
123     }
124 
125     @Override
126     public void setValue(final List<T> pValue) {
127         super.setValue(pValue);
128         theManager.setValue(pValue);
129         updateText();
130     }
131 
132     /**
133      * Update the button text.
134      */
135     private void updateText() {
136         getLabel().setText(theManager.getText());
137     }
138 
139     @Override
140     public void startCellEditing(final Rectangle pCell) {
141         isCellEditing = true;
142         theManager.buildMenu();
143         final TethysUISwingScrollMenu<T> myMenu = theManager.getMenu();
144         myMenu.showMenuAtPosition(pCell, SwingConstants.BOTTOM);
145     }
146 
147     /**
148      * haltCellEditing.
149      */
150     private void haltCellEditing() {
151         isCellEditing = false;
152     }
153 
154     @Override
155     public TethysUISwingListButtonField<T> cloneField(final JLabel pLabel) {
156         return new TethysUISwingListButtonField<>(getGuiFactory(), pLabel);
157     }
158 
159     @Override
160     public void setSelectables(final Supplier<Iterator<T>> pSelectables) {
161         theManager.setSelectables(pSelectables);
162     }
163 }
164