001/*
002 * ============================================================================
003 * Copyright © 2002-2024 by Thomas Thrien.
004 * All Rights Reserved.
005 * ============================================================================
006 * Licensed to the public under the agreements of the GNU Lesser General Public
007 * License, version 3.0 (the "License"). You may obtain a copy of the License at
008 *
009 *      http://www.gnu.org/licenses/lgpl.html
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 * License for the specific language governing permissions and limitations
015 * under the License.
016 */
017
018package org.tquadrat.foundation.fx.control.tester;
019
020import static java.lang.System.err;
021import static java.lang.System.out;
022import static javafx.scene.layout.Region.USE_COMPUTED_SIZE;
023import static org.apiguardian.api.API.Status.EXPERIMENTAL;
024import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument;
025import static org.tquadrat.foundation.lang.Objects.requireNotBlankArgument;
026import static org.tquadrat.foundation.util.UniqueIdUtils.timebasedUUID;
027
028import org.apiguardian.api.API;
029import org.tquadrat.foundation.annotation.ClassVersion;
030import org.tquadrat.foundation.annotation.ProgramClass;
031import org.tquadrat.foundation.fx.control.ErrorDisplay;
032import javafx.application.Application;
033import javafx.event.ActionEvent;
034import javafx.event.EventHandler;
035import javafx.geometry.Insets;
036import javafx.scene.Scene;
037import javafx.scene.control.Button;
038import javafx.scene.control.Tooltip;
039import javafx.scene.layout.HBox;
040import javafx.stage.Stage;
041
042/**
043 *  Test bed for the custom control
044 *  {@link ErrorDisplay}.
045 *
046 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
047 *  @version $Id: ErrorDisplayTester.java 1113 2024-03-12 02:01:14Z tquadrat $
048 *  @since 0.4.3
049 *
050 *  @UMLGraph.link
051 */
052@SuppressWarnings( "UseOfSystemOutOrSystemErr" )
053@ClassVersion( sourceVersion = "$Id: ErrorDisplayTester.java 1113 2024-03-12 02:01:14Z tquadrat $" )
054@API( status = EXPERIMENTAL, since = "0.4.3" )
055@ProgramClass
056public final class ErrorDisplayTester extends Application
057{
058        /*---------------*\
059    ====** Inner Classes **====================================================
060        \*---------------*/
061
062        /*-----------*\
063    ====** Constants **========================================================
064        \*-----------*/
065    /**
066     *  The contents for the message.
067     */
068    public static final String [] contents = { "one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine ", "ten " };
069
070        /*------------*\
071    ====** Attributes **=======================================================
072        \*------------*/
073    /**
074     *  The error display.
075     */
076    private ErrorDisplay m_ErrorDisplay;
077
078    /**
079     *  Counter.
080     */
081    private int m_Counter = 0;
082
083    /**
084     *  The message.
085     */
086    @SuppressWarnings( "StringBufferField" )
087    private final StringBuilder m_Buffer = new StringBuilder( "zero " );
088
089        /*------------------------*\
090    ====** Static Initialisations **===========================================
091        \*------------------------*/
092    /**
093     *  The flag that tracks the assertion on/off status for this package.
094     */
095    private static boolean m_AssertionOn;
096
097    static
098    {
099        //---* Determine the assertion status *--------------------------------
100        m_AssertionOn = false;
101        //noinspection AssertWithSideEffects,PointlessBooleanExpression,NestedAssignment
102        assert (m_AssertionOn = true) == true : "Assertion is switched off";
103    }
104
105        /*--------------*\
106    ====** Constructors **=====================================================
107        \*--------------*/
108    /**
109     *  Creates a new instance of {@code ErrorDisplayTester}.
110     */
111    public ErrorDisplayTester() { /* Just exists */ }
112
113        /*---------*\
114    ====** Methods **==========================================================
115        \*---------*/
116    /**
117     *  Creates a button and configures it.
118     *
119     *  @param  text    The button text.
120     *  @param  eventHandler    The event handler for the new button.
121     *  @return The new button.
122     */
123    @SuppressWarnings( "SameParameterValue" )
124    private final Button createButton( final String text, final EventHandler<ActionEvent> eventHandler )
125    {
126        final var retValue = new Button( requireNotBlankArgument( text, "text" ) );
127        retValue.setOnAction( requireNonNullArgument( eventHandler, "eventHandler" ) );
128
129        final var buttonWidth = 100.0;
130        final var buttonHeight = 30.0;
131        final var spacing = 7.5;
132
133        retValue.setMaxHeight( buttonHeight );
134        retValue.setMinHeight( buttonHeight );
135        retValue.setPrefHeight( buttonHeight );
136        retValue.setMaxWidth( buttonWidth );
137        retValue.setMinWidth( buttonWidth );
138        retValue.setPrefWidth( buttonWidth );
139        retValue.setPadding( new Insets( spacing ) );
140
141        //---* Done *----------------------------------------------------------
142        return retValue;
143    }   //  createButton()
144
145    /**
146     *  The program entry point.
147     *
148     *  @param  args    The command line arguments.
149     */
150    public static final void main( final String... args )
151    {
152        out.printf( "Assertion is %s%n".formatted( m_AssertionOn ? "ON" : "OFF" ) );
153
154        try
155        {
156            launch( args );
157        }
158        catch( final Throwable t )
159        {
160            t.printStackTrace( err );
161        }
162    }   //  main()
163
164    /**
165     *  Responds to the AddMessage button.
166     *
167     *  @param  event   The action event.
168     */
169    private final void onAddMessage( final ActionEvent event )
170    {
171        final var id = timebasedUUID().toString();
172        final var pos = m_Counter++ % contents.length;
173        m_Buffer.append( contents [pos] );
174        final var message = m_Buffer.toString();
175        m_ErrorDisplay.addMessage( id, message );
176    }   //  onAddMessage()
177
178    /**
179     *  {@inheritDoc}
180     */
181    @SuppressWarnings( "ProhibitedExceptionDeclared" )
182    @Override
183    public void start( final Stage primaryStage ) throws Exception
184    {
185        //---* Compose the scene *---------------------------------------------
186        final var spacing = 7.5;
187        final var root = new HBox();
188        root.setSpacing( spacing );
189        root.setPadding( new Insets( spacing ) );
190
191        m_ErrorDisplay = new ErrorDisplay();
192        root.getChildren().add( createButton( "Add Message", this::onAddMessage ) );
193        root.getChildren().add( m_ErrorDisplay );
194        //noinspection MagicNumber
195        m_ErrorDisplay.setMinSize( 500.0, 300.0 );
196        m_ErrorDisplay.setPrefSize( USE_COMPUTED_SIZE, USE_COMPUTED_SIZE );
197        m_ErrorDisplay.setMaxSize( Double.MAX_VALUE, Double.MAX_VALUE );
198        m_ErrorDisplay.addMessage( m_Buffer.toString() );
199        m_ErrorDisplay.setTooltip( new Tooltip( "The error display" ) );
200
201        final var scene = new Scene( root, -1, -1 );
202        primaryStage.setScene( scene );
203        primaryStage.centerOnScreen();
204        primaryStage.setOnCloseRequest( $ -> out.println( "Done!" ) );
205
206        //---* Show the stage *--------------------------------------------
207        primaryStage.show();
208    }   //  start()
209}
210//  class ErrorDisplayTester
211
212/*
213 *  End of File
214 */