3838public final class MainWindowController implements IAudioTimer , TrayIconListener {
3939
4040 @ FXML
41- private GridPane grpControls ;
41+ private Button btnClearSearch ;
42+ @ FXML
43+ private TextField txtSearch ;
44+ @ FXML
45+ private GridPane grpOther ;
46+ @ FXML
47+ private GridPane grpRadioFrequencyStatic ;
48+ @ FXML
49+ private GridPane grpAudiences ;
50+ @ FXML
51+ private GridPane grpOffice ;
52+ @ FXML
53+ private GridPane grpNature ;
4254 @ FXML
4355 private CheckMenuItem mniTimerEnabled ;
4456 @ FXML
@@ -139,7 +151,7 @@ public void setControllers(final SettingsController settingsController, final Up
139151 * @param visible True if the media buttons should be visible, otherwise false
140152 */
141153 public void loadMediaButtonVisibility (final boolean visible ) {
142- getAllSoundPanes (grpControls ).forEach (s -> s .setMediaButton (visible ));
154+ getAllSoundPanes ().forEach (s -> s .setMediaButton (visible ));
143155 }
144156
145157 /**
@@ -201,20 +213,37 @@ private void checkForUpdates(final boolean showNoUpdates, final boolean showErro
201213 }
202214 }
203215
216+ /**
217+ * Get all {@link SoundPane} objects
218+ *
219+ * @return The {@link List} of {@link SoundPane} objects
220+ */
221+ private List <SoundPane > getAllSoundPanes () {
222+ final List <SoundPane > elements = new ArrayList <>();
223+
224+ elements .addAll (getSoundPanes (grpOther ));
225+ elements .addAll (getSoundPanes (grpRadioFrequencyStatic ));
226+ elements .addAll (getSoundPanes (grpAudiences ));
227+ elements .addAll (getSoundPanes (grpOffice ));
228+ elements .addAll (getSoundPanes (grpNature ));
229+
230+ return elements ;
231+ }
232+
204233 /**
205234 * Get all {@link SoundPane} objects from a {@link GridPane} object
206235 *
207236 * @param parent The {@link GridPane} object
208237 * @return The {@link List} of {@link SoundPane} objects inside the given {@link GridPane} object
209238 */
210- private List <SoundPane > getAllSoundPanes (final GridPane parent ) {
239+ private List <SoundPane > getSoundPanes (final GridPane parent ) {
211240 if (parent == null )
212241 throw new NullPointerException ("GridPane cannot be null!" );
213242
214243 final List <SoundPane > elements = new ArrayList <>();
215244 parent .getChildren ().forEach (e -> {
216245 if (e instanceof GridPane p )
217- elements .addAll (getAllSoundPanes (p ));
246+ elements .addAll (getSoundPanes (p ));
218247 if (e instanceof SoundPane s )
219248 elements .add (s );
220249 });
@@ -260,7 +289,7 @@ public void run() {
260289 * Method that is invoked to initialize the FXML object
261290 */
262291 @ FXML
263- private void initialize () {
292+ public void initialize () {
264293 mniTimerEnabled .setOnAction (_ -> {
265294 if (mniTimerEnabled .isSelected ()) {
266295 final Properties properties = settingsController .getProperties ();
@@ -271,13 +300,36 @@ private void initialize() {
271300 cancelTimer ();
272301 }
273302 });
303+
304+ txtSearch .textProperty ().addListener ((_ , _ , newValue ) -> {
305+ if (newValue == null || newValue .isBlank ()) {
306+ Platform .runLater (() -> {
307+ getAllSoundPanes ().forEach (e -> {
308+ e .setVisible (true );
309+ e .setManaged (true );
310+ });
311+ btnClearSearch .setVisible (false );
312+ btnClearSearch .setManaged (false );
313+ });
314+ return ;
315+ }
316+ Platform .runLater (() -> {
317+ getAllSoundPanes ()
318+ .forEach (e -> {
319+ e .setVisible (e .getName ().toLowerCase ().contains (newValue .trim ().toLowerCase ()));
320+ e .setManaged (e .isVisible ());
321+ });
322+ btnClearSearch .setVisible (true );
323+ btnClearSearch .setManaged (true );
324+ });
325+ });
274326 }
275327
276328 /**
277329 * Hide the current stage
278330 */
279331 private void hideShowStage () {
280- final Stage stage = (Stage ) grpControls .getScene ().getWindow ();
332+ final Stage stage = (Stage ) grpNature .getScene ().getWindow ();
281333 if (stage .isShowing ()) {
282334 stage .hide ();
283335 } else {
@@ -320,14 +372,14 @@ private void openSoundPreset(final String path) {
320372 final Path filePath = Path .of (path );
321373 final String actual = Files .readString (filePath );
322374
323- if (actual == null || actual .isEmpty ())
324- throw new IllegalArgumentException ("Sound preset cannot be null or empty!" );
375+ if (actual .isEmpty ())
376+ throw new IllegalArgumentException ("Sound preset cannot be empty!" );
325377
326378 final TypeReference <HashMap <String , Double >> typeRef = new TypeReference <>() {
327379 };
328380
329381 final Map <String , Double > mediaVolumes = objectMapper .readValue (actual , typeRef );
330- final List <SoundPane > soundPanes = getAllSoundPanes (grpControls );
382+ final List <SoundPane > soundPanes = getAllSoundPanes ();
331383
332384 mediaVolumes .forEach ((key , value ) -> soundPanes .stream ().filter (e -> e .getMediaKey ().equals (key )).forEach (e -> e .getSlider ().setValue (value )));
333385 } catch (final IOException ex ) {
@@ -356,7 +408,7 @@ private void saveSoundPresetAction() {
356408 }
357409
358410 final Map <String , Double > mediaVolumes = new HashMap <>();
359- getAllSoundPanes (grpControls ).forEach (e -> mediaVolumes .put (e .getMediaKey (), e .getSlider ().getValue ()));
411+ getAllSoundPanes ().forEach (e -> mediaVolumes .put (e .getMediaKey (), e .getSlider ().getValue ()));
360412
361413 try {
362414 objectMapper .writeValue (new File (filePath ), mediaVolumes );
@@ -376,7 +428,7 @@ private void saveSoundPresetAction() {
376428 private void playPauseAction () {
377429 logger .info ("Play / pause all media" );
378430 try {
379- for (final SoundPane soundPane : getAllSoundPanes (grpControls )) {
431+ for (final SoundPane soundPane : getAllSoundPanes ()) {
380432 soundPane .playPause ();
381433 }
382434 } catch (final MediaPlayerException ex ) {
@@ -391,7 +443,7 @@ private void playPauseAction() {
391443 @ FXML
392444 private void resetAction () {
393445 logger .info ("Resetting all audio sliders" );
394- getAllSoundPanes (grpControls ).forEach (e -> e .getSlider ().setValue (0 ));
446+ getAllSoundPanes ().forEach (e -> e .getSlider ().setValue (0 ));
395447 }
396448
397449 /**
@@ -530,13 +582,21 @@ private void updateAction() {
530582 checkForUpdates (true , true );
531583 }
532584
585+ /**
586+ * Method that is called when the search field should be cleared
587+ */
588+ @ FXML
589+ public void clearSearchAction () {
590+ txtSearch .clear ();
591+ }
592+
533593 /**
534594 * Method that is called when the {@link Timer} object has fired
535595 */
536596 @ Override
537597 public void fired () {
538598 cancelTimer ();
539- getAllSoundPanes (grpControls ).forEach (SoundPane ::pause );
599+ getAllSoundPanes ().forEach (SoundPane ::pause );
540600
541601 if (Boolean .parseBoolean (settingsController .getProperties ().getProperty ("timerComputerShutdown" , "false" ))) {
542602 final String command = switch (platformName .toLowerCase ()) {
@@ -707,7 +767,7 @@ public void setAudioBalance(final double audioBalance) {
707767 throw new IllegalArgumentException ("Balance must be between -1.0 and 1.0!" );
708768
709769 logger .info ("Setting the audio balance to {}" , audioBalance );
710- getAllSoundPanes (grpControls ).forEach (s -> s .setBalance (audioBalance ));
770+ getAllSoundPanes ().forEach (s -> s .setBalance (audioBalance ));
711771 }
712772
713773 /**
0 commit comments