View Javadoc
1   /*
2    * Metis: Java Data Framework
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.metis.ui;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
21  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
22  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
23  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerEntry;
24  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerErrorList;
25  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerExceptionWrapper;
26  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerManager;
27  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerStandardEntry;
28  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
29  import io.github.tonywasher.joceanus.tethys.api.button.TethysUIButton;
30  import io.github.tonywasher.joceanus.tethys.api.control.TethysUILabel;
31  import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
32  import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBoxPaneManager;
33  
34  /**
35   * Error panel.
36   */
37  public class MetisErrorPanel
38          implements OceanusEventProvider<MetisUIEvent>, TethysUIComponent {
39      /**
40       * Text for Clear Button.
41       */
42      private static final String NLS_CLEAR = MetisUIResource.ERROR_BUTTON_CLEAR.getValue();
43  
44      /**
45       * Text for Box title.
46       */
47      private static final String NLS_TITLE = MetisUIResource.ERROR_TITLE.getValue();
48  
49      /**
50       * The Event Manager.
51       */
52      private final OceanusEventManager<MetisUIEvent> theEventManager;
53  
54      /**
55       * The Panel.
56       */
57      private final TethysUIBoxPaneManager thePanel;
58  
59      /**
60       * The error field.
61       */
62      private final TethysUILabel theErrorField;
63  
64      /**
65       * The clear button.
66       */
67      private final TethysUIButton theClearButton;
68  
69      /**
70       * The viewer entry for the error.
71       */
72      private final MetisViewerEntry theViewerError;
73  
74      /**
75       * The error itself.
76       */
77      private final MetisViewerErrorList theErrors;
78  
79      /**
80       * Constructor.
81       *
82       * @param pFactory   the GUI factory
83       * @param pViewerMgr the Viewer manager
84       * @param pParent    the parent viewer entry
85       */
86      public MetisErrorPanel(final TethysUIFactory<?> pFactory,
87                             final MetisViewerManager pViewerMgr,
88                             final MetisViewerEntry pParent) {
89          /* Create the error viewer entry for this view */
90          theViewerError = pViewerMgr.newEntry(pParent, MetisViewerStandardEntry.ERROR.toString());
91          theViewerError.setVisible(false);
92  
93          /* Create the event manager */
94          theEventManager = new OceanusEventManager<>();
95  
96          /* Create the error list */
97          theErrors = new MetisViewerErrorList();
98          theViewerError.setObject(theErrors);
99  
100         /* Create the error field */
101         theErrorField = pFactory.controlFactory().newLabel();
102         theErrorField.setErrorText();
103 
104         /* Create the clear button */
105         theClearButton = pFactory.buttonFactory().newButton();
106         theClearButton.setTextOnly();
107         theClearButton.setText(NLS_CLEAR);
108 
109         /* Add the listener for item changes */
110         theClearButton.getEventRegistrar().addEventListener(e -> clearErrors());
111 
112         /* Create the error panel */
113         thePanel = pFactory.paneFactory().newHBoxPane();
114         thePanel.setBorderTitle(NLS_TITLE);
115 
116         /* Define the layout */
117         thePanel.addNode(theClearButton);
118         thePanel.addNode(theErrorField);
119 
120         /* Set the Error panel to be red and invisible */
121         thePanel.setVisible(false);
122     }
123 
124     @Override
125     public OceanusEventRegistrar<MetisUIEvent> getEventRegistrar() {
126         return theEventManager.getEventRegistrar();
127     }
128 
129     @Override
130     public TethysUIComponent getUnderlying() {
131         return thePanel;
132     }
133 
134     @Override
135     public void setEnabled(final boolean bEnabled) {
136         /* Pass on to important elements */
137         theClearButton.setEnabled(bEnabled);
138     }
139 
140     /**
141      * Do we have an error?
142      *
143      * @return true/false
144      */
145     public boolean hasError() {
146         return !theErrors.isEmpty();
147     }
148 
149     /**
150      * Set error indication for window.
151      *
152      * @param pException the exception
153      */
154     public void addError(final OceanusException pException) {
155         /* If we do not currently have an error */
156         if (!hasError()) {
157             /* Show the viewer entry */
158             theViewerError.setVisible(true);
159         }
160 
161         /* Record the error */
162         theErrors.add(new MetisViewerExceptionWrapper(pException));
163 
164         /* Set the error text and display the panel */
165         setErrorText(pException.getMessage());
166 
167         /* Notify listeners */
168         theEventManager.fireEvent(MetisUIEvent.VISIBILITY);
169     }
170 
171     /**
172      * Show validation error.
173      *
174      * @param pError the error message
175      */
176     public void showValidateError(final String pError) {
177         if (pError != null) {
178             setErrorText(pError);
179         } else {
180             thePanel.setVisible(false);
181         }
182     }
183 
184     /**
185      * Set error text for window.
186      *
187      * @param pText the text
188      */
189     private void setErrorText(final String pText) {
190         /* Set the string for the error field */
191         theErrorField.setText(pText);
192 
193         /* Make the panel visible */
194         thePanel.setVisible(true);
195     }
196 
197     /**
198      * Set error list.
199      *
200      * @param pExceptions the error list
201      */
202     public void setErrors(final MetisViewerErrorList pExceptions) {
203         /* If we currently have an error */
204         if (hasError()) {
205             /* Clear the error */
206             theErrors.clear();
207             theViewerError.setVisible(false);
208         }
209 
210         /* If we have some exceptions */
211         if (!pExceptions.isEmpty()) {
212             /* Show the debug */
213             theViewerError.setVisible(true);
214 
215             /* Add the new errors */
216             theErrors.addList(pExceptions);
217 
218             /* Set the error text and display the panel */
219             setErrorText(pExceptions.getUnderlyingList().get(0).getMessage());
220         }
221 
222         /* Notify listeners */
223         theEventManager.fireEvent(MetisUIEvent.VISIBILITY);
224     }
225 
226     /**
227      * Clear error indication for this window.
228      */
229     private void clearErrors() {
230         /* If we currently have an error */
231         if (hasError()) {
232             /* Clear the error */
233             theErrors.clear();
234             theViewerError.setVisible(false);
235         }
236 
237         /* Make the panel invisible */
238         setVisible(false);
239 
240         /* Notify listeners */
241         theEventManager.fireEvent(MetisUIEvent.VISIBILITY);
242     }
243 }