3232import javafx .beans .property .SimpleLongProperty ;
3333import javafx .beans .property .SimpleObjectProperty ;
3434import javafx .collections .ListChangeListener ;
35+ import javafx .collections .ListChangeListener .Change ;
3536import javafx .collections .ObservableList ;
3637import javafx .embed .swing .SwingFXUtils ;
3738import javafx .fxml .FXML ;
@@ -172,29 +173,20 @@ public void changeProject(final Project newProject, final long minusSeconds) {
172173 @ FXML
173174 private void initialize () throws IOException {
174175
175- bigTimeLabel .setText (TIME_ZERO );
176- bigTimeLabel .setFont (new Font (ARIAL , 60 ));
177- allTimeLabel .setText (TIME_ZERO );
178- todayAllSeconds .setText (TIME_ZERO );
176+ setUpTime ();
179177
180- textArea .setWrapText (true );
181- textArea .setEditable (false );
182- textArea .editableProperty ().bind (mouseHoveringProperty );
183-
184- textArea .textProperty ().addListener ((a , b , c ) -> {
185- controller .setComment (textArea .getText ());
186- });
178+ setUpTextArea ();
187179
188180 // reposition window if projects are hidden (as anchor is top left)
189181 mouseHoveringProperty .addListener ((a , b , c ) -> {
190182 setProjectWindowVisibleByMouseHover (c );
191183 });
192184
193- minimizeButton .setOnAction (( ae ) -> {
185+ minimizeButton .setOnAction (ae -> {
194186 mainStage .setIconified (true );
195187 });
196188 minimizeButton .textFillProperty ().bind (fontColorProperty );
197- closeButton .setOnAction (( ae ) -> {
189+ closeButton .setOnAction (ae -> {
198190 mainStage .close ();
199191 });
200192 closeButton .textFillProperty ().bind (fontColorProperty );
@@ -203,41 +195,20 @@ private void initialize() throws IOException {
203195 addNewProjectButton .setOnAction ((ae ) -> {
204196 LOG .info ("Add new project clicked" );
205197 // TODO somewhat duplicate dialog of create and edit
206- final Dialog <Project > dialog = new Dialog <>();
207- dialog .setTitle ("Create new project" );
208- dialog .setHeaderText ("Create a new project" );
198+ final Dialog <Project > dialog = setUpDialogProject ("Create new project" , "Create a new project" );
209199
210- dialog .getDialogPane ().getButtonTypes ().addAll (ButtonType .OK , ButtonType .CANCEL );
211-
212- final GridPane grid = new GridPane ();
213- grid .setHgap (10 );
214- grid .setVgap (10 );
215- grid .setPadding (new Insets (20 , 150 , 10 , 10 ));
200+ final GridPane grid = setUpAddNewProjectGridPane ("" , Color .WHITE , true );
216201
217- grid .add (new Label ("Name:" ), 0 , 0 );
218- final TextField projectNameTextField = new TextField ();
219- projectNameTextField .setPromptText ("Projectname" );
220- grid .add (projectNameTextField , 1 , 0 );
221-
222- grid .add (new Label ("Color:" ), 0 , 1 );
223- final ColorPicker colorPicker = new ColorPicker ();
224- grid .add (colorPicker , 1 , 1 );
225-
226- grid .add (new Label ("IsWork:" ), 0 , 2 );
227- final CheckBox isWorkCheckBox = new CheckBox ();
228- grid .add (isWorkCheckBox , 1 , 2 );
229-
230- grid .add (new Label ("SortIndex:" ), 0 , 3 );
231- final Spinner <Integer > indexSpinner = new Spinner <>();
232- final int availableProjectAmount = model .availableProjects .size ();
233- indexSpinner
234- .setValueFactory (new IntegerSpinnerValueFactory (0 , availableProjectAmount , availableProjectAmount ));
235- grid .add (indexSpinner , 1 , 3 );
236202 // TODO disable OK button if no name is set
237203 dialog .getDialogPane ().setContent (grid );
238204
239205 dialog .setResultConverter (dialogButton -> {
240206 if (dialogButton == ButtonType .OK ) {
207+ final ObservableList <Node > nodes = grid .getChildren ();
208+ final TextField projectNameTextField = (TextField ) nodes .get (1 );
209+ final ColorPicker colorPicker = (ColorPicker ) nodes .get (3 );
210+ final CheckBox isWorkCheckBox = (CheckBox ) nodes .get (5 );
211+ final Spinner <Integer > indexSpinner = (Spinner <Integer >) nodes .get (7 );
241212 return new Project (projectNameTextField .getText (), colorPicker .getValue (), isWorkCheckBox .isSelected (),
242213 indexSpinner .getValue ()); // temporary (misused) transfer object for project
243214 }
@@ -261,34 +232,18 @@ private void initialize() throws IOException {
261232 return new Light .Distant (45 , 45 , color );
262233 }, fontColorProperty ));
263234
264- settingsButton .setOnAction ((ae ) -> {
265- LOG .info ("Settings clicked" );
266- this .mainStage .setAlwaysOnTop (false );
267- settingsController .update ();
268- settingsStage .show ();
235+ settingsButton .setOnAction (ae -> {
236+ settingsClicked ();
269237 });
270238 settingsButton .setEffect (lighting );
271239
272240 calendarButton .setOnAction ((ae ) -> {
273- LOG .info ("Calendar clicked" );
274- this .mainStage .setAlwaysOnTop (false );
275- reportController .update ();
276- reportStage .show ();
241+ calendarClicked ();
277242 });
278243 calendarButton .setEffect (lighting );
279244
280245 final Runnable updateMainBackgroundColor = () -> {
281- Color color = model .defaultBackgroundColor .get ();
282- double opacity = 0 ;
283- if (mouseHoveringProperty .get ()) {
284- color = model .hoverBackgroundColor .get ();
285- opacity = .3 ;
286- }
287- String style = changeStyleAttribute (pane .getStyle (), "fx-background-color" ,
288- RGBA + ColorHelper .colorToCssRgba (color ) + ")" );
289- style = changeStyleAttribute (style , "fx-border-color" ,
290- RGBA + ColorHelper .colorToCssRgb (color ) + ", " + opacity + ")" );
291- pane .setStyle (style );
246+ runUpdateMainBackgroundColor ();
292247 };
293248
294249 mouseHoveringProperty .addListener ((a , b , c ) -> {
@@ -352,25 +307,7 @@ private void initialize() throws IOException {
352307 });
353308
354309 model .availableProjects .addListener ((ListChangeListener <Project >) lis -> {
355- while (lis .next ()) {
356- if (lis .wasAdded ()) {
357- final List <? extends Project > addedSubList = lis .getAddedSubList ();
358- for (final Project project : addedSubList ) {
359- final Node node = addProjectToProjectList (project );
360- projectSelectionNodeMap .put (project , node );
361- }
362- } else if (lis .wasRemoved ()) {
363- final List <? extends Project > removedSubList = lis .getRemoved ();
364- for (final Project project : removedSubList ) {
365- // change to idle if removed project was active
366- if (project == model .activeWorkItem .get ().getProject ()) {
367- changeProject (model .idleProject , 0 );
368- }
369- final Node remove = projectSelectionNodeMap .remove (project );
370- availableProjectVbox .getChildren ().remove (remove );
371- }
372- }
373- }
310+ setUpAvailableProjectsListener (lis );
374311 });
375312
376313 model .defaultBackgroundColor .addListener ((a , b , c ) -> {
@@ -410,39 +347,110 @@ private void initialize() throws IOException {
410347
411348 // update ui each second
412349 Interval .registerCallBack (() -> {
413- final LocalDateTime now = LocalDateTime .now ();
414- model .activeWorkItem .get ().setEndTime (now ); // TODO not good to change model
415-
416- final long currentWorkSeconds = Duration
417- .between (model .activeWorkItem .get ().getStartTime (), model .activeWorkItem .get ().getEndTime ())
418- .getSeconds ();
419- activeWorkSecondsProperty .set (currentWorkSeconds );
420- final long todayWorkingSeconds = controller .calcTodaysWorkSeconds ();
421- final long todaySeconds = controller .calcTodaysSeconds ();
422-
423- // update all ui labels
424- // TODO do it with bindings (maybe create a viewmodel for this)
425- // bigTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentWorkSeconds));
426- allTimeLabel .setText (DateFormatter .secondsToHHMMSS (todayWorkingSeconds ));
427- todayAllSeconds .setText (DateFormatter .secondsToHHMMSS (todaySeconds ));
428-
429- for (final Project p : elapsedProjectTimeLabelMap .keySet ()) {
430- final Label label = elapsedProjectTimeLabelMap .get (p );
431-
432- final long seconds = model .pastWorkItems .stream ().filter ((work ) -> work .getProject ().getId () == p .getId ())
433- .mapToLong (work -> {
434- return Duration .between (work .getStartTime (), work .getEndTime ()).getSeconds ();
435- }).sum ();
436- label .setText (DateFormatter .secondsToHHMMSS (seconds ));
437- label .setFont (new Font (ARIAL , 12 ));
438- }
350+ final long currentWorkSeconds = doIntervalRegisterCallBack ();
439351
440352 updateProjectColorTimeline ();
441353 updateTaskbarIcon (currentWorkSeconds );
442354 });
443355
444356 }
445357
358+ private void settingsClicked () {
359+ LOG .info ("Settings clicked" );
360+ this .mainStage .setAlwaysOnTop (false );
361+ settingsController .update ();
362+ settingsStage .show ();
363+ }
364+
365+ private void calendarClicked () {
366+ LOG .info ("Calendar clicked" );
367+ this .mainStage .setAlwaysOnTop (false );
368+ reportController .update ();
369+ reportStage .show ();
370+ }
371+
372+ private void runUpdateMainBackgroundColor () {
373+ Color color = model .defaultBackgroundColor .get ();
374+ double opacity = 0 ;
375+ if (mouseHoveringProperty .get ()) {
376+ color = model .hoverBackgroundColor .get ();
377+ opacity = .3 ;
378+ }
379+ String style = changeStyleAttribute (pane .getStyle (), "fx-background-color" ,
380+ RGBA + ColorHelper .colorToCssRgba (color ) + ")" );
381+ style = changeStyleAttribute (style , "fx-border-color" ,
382+ RGBA + ColorHelper .colorToCssRgb (color ) + ", " + opacity + ")" );
383+ pane .setStyle (style );
384+ }
385+
386+ private void setUpAvailableProjectsListener (final Change <? extends Project > lis ) {
387+ while (lis .next ()) {
388+ if (lis .wasAdded ()) {
389+ final List <? extends Project > addedSubList = lis .getAddedSubList ();
390+ for (final Project project : addedSubList ) {
391+ final Node node = addProjectToProjectList (project );
392+ projectSelectionNodeMap .put (project , node );
393+ }
394+ } else if (lis .wasRemoved ()) {
395+ final List <? extends Project > removedSubList = lis .getRemoved ();
396+ for (final Project project : removedSubList ) {
397+ // change to idle if removed project was active
398+ if (project == model .activeWorkItem .get ().getProject ()) {
399+ changeProject (model .idleProject , 0 );
400+ }
401+ final Node remove = projectSelectionNodeMap .remove (project );
402+ availableProjectVbox .getChildren ().remove (remove );
403+ }
404+ }
405+ }
406+ }
407+
408+ private long doIntervalRegisterCallBack () {
409+ final LocalDateTime now = LocalDateTime .now ();
410+ model .activeWorkItem .get ().setEndTime (now ); // TODO not good to change model
411+
412+ final long currentWorkSeconds = Duration
413+ .between (model .activeWorkItem .get ().getStartTime (), model .activeWorkItem .get ().getEndTime ()).getSeconds ();
414+ activeWorkSecondsProperty .set (currentWorkSeconds );
415+ final long todayWorkingSeconds = controller .calcTodaysWorkSeconds ();
416+ final long todaySeconds = controller .calcTodaysSeconds ();
417+
418+ // update all ui labels
419+ // TODO do it with bindings (maybe create a viewmodel for this)
420+ // bigTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentWorkSeconds));
421+ allTimeLabel .setText (DateFormatter .secondsToHHMMSS (todayWorkingSeconds ));
422+ todayAllSeconds .setText (DateFormatter .secondsToHHMMSS (todaySeconds ));
423+
424+ for (final Project p : elapsedProjectTimeLabelMap .keySet ()) {
425+ final Label label = elapsedProjectTimeLabelMap .get (p );
426+
427+ final long seconds = model .pastWorkItems .stream ().filter ((work ) -> work .getProject ().getId () == p .getId ())
428+ .mapToLong (work -> {
429+ return Duration .between (work .getStartTime (), work .getEndTime ()).getSeconds ();
430+ }).sum ();
431+ label .setText (DateFormatter .secondsToHHMMSS (seconds ));
432+ label .setFont (new Font (ARIAL , 12 ));
433+ }
434+ return currentWorkSeconds ;
435+ }
436+
437+ private void setUpTime () {
438+ bigTimeLabel .setText (TIME_ZERO );
439+ bigTimeLabel .setFont (new Font (ARIAL , 60 ));
440+ allTimeLabel .setText (TIME_ZERO );
441+ todayAllSeconds .setText (TIME_ZERO );
442+ }
443+
444+ private void setUpTextArea () {
445+ textArea .setWrapText (true );
446+ textArea .setEditable (false );
447+ textArea .editableProperty ().bind (mouseHoveringProperty );
448+
449+ textArea .textProperty ().addListener ((a , b , c ) -> {
450+ controller .setComment (textArea .getText ());
451+ });
452+ }
453+
446454 private void setProjectWindowVisibleByMouseHover (final Boolean c ) {
447455 // TODO fix the not so nice jumping..
448456 projectsVBox .setManaged (c );
@@ -664,7 +672,7 @@ private Node addProjectToProjectList(final Project p) {
664672 editMenuItem .setOnAction (e -> {
665673 // TODO refactor to use "add project" controls
666674 LOG .info ("Edit project" );
667- final Dialog <ButtonType > dialog = setUpEditProjectDialog ( p );
675+ final Dialog <ButtonType > dialog = setUpDialogButtonType ( "Edit project" , "Edit project '" + p . getName () + "'" );
668676 final GridPane grid = setUpEditProjectGridPane (p );
669677
670678 // TODO disable OK button if no name is set
@@ -734,43 +742,65 @@ private void editProject(final ObservableList<Node> nodes, final Project p) {
734742 indexSpinner .getValue ());
735743 }
736744
737- private Label setUpProjectNameLabel (final Label projectNameLabel , final double dimFactor , final Project p ) {
738- return projectNameLabel ;
745+ private Dialog <ButtonType > setUpDialogButtonType (final String title , final String headerText ) {
746+ final Dialog <ButtonType > dialog = new Dialog <>();
747+ dialog .setTitle (title );
748+ dialog .setHeaderText (headerText );
749+ dialog .getDialogPane ().getButtonTypes ().addAll (ButtonType .OK , ButtonType .CANCEL );
750+ return dialog ;
739751 }
740752
741- private Dialog <ButtonType > setUpEditProjectDialog (final Project p ) {
742- final Dialog <ButtonType > dialog = new Dialog <>();
743- dialog .setTitle ("Edit project" );
744- dialog .setHeaderText ("Edit project '" + p . getName () + "'" );
753+ private Dialog <Project > setUpDialogProject (final String title , final String headerText ) {
754+ final Dialog <Project > dialog = new Dialog <>();
755+ dialog .setTitle (title );
756+ dialog .setHeaderText (headerText );
745757 dialog .getDialogPane ().getButtonTypes ().addAll (ButtonType .OK , ButtonType .CANCEL );
746758 return dialog ;
747759 }
748760
749761 private GridPane setUpEditProjectGridPane (final Project p ) {
750- final GridPane grid = new GridPane ();
762+ final GridPane grid = setUpGridPane (p .getName (), p .getColor (), p .isWork ());
763+
764+ final Spinner <Integer > indexSpinner = new Spinner <>();
765+ final int availableProjectAmount = model .availableProjects .size ();
766+ indexSpinner .setValueFactory (new IntegerSpinnerValueFactory (0 , availableProjectAmount - 1 , p .getIndex ()));
767+ grid .add (indexSpinner , 1 , 3 );
768+
769+ return grid ;
770+ }
771+
772+ private GridPane setUpAddNewProjectGridPane (final String projectName , final Color projectColor ,
773+ final boolean isWork ) {
774+ final GridPane grid = setUpGridPane (projectName , projectColor , isWork );
775+
776+ final Spinner <Integer > indexSpinner = new Spinner <>();
777+ final int availableProjectAmount = model .availableProjects .size ();
778+ indexSpinner .setValueFactory (new IntegerSpinnerValueFactory (0 , availableProjectAmount , availableProjectAmount ));
779+ grid .add (indexSpinner , 1 , 3 );
780+
781+ return grid ;
782+ }
751783
784+ private GridPane setUpGridPane (final String projectName , final Color projectColor , final boolean isWork ) {
785+ final GridPane grid = new GridPane ();
752786 grid .setHgap (10 );
753787 grid .setVgap (10 );
754788 grid .setPadding (new Insets (20 , 150 , 10 , 10 ));
755789
756790 grid .add (new Label ("Name:" ), 0 , 0 );
757- final TextField projectNameTextField = new TextField (p . getName () );
791+ final TextField projectNameTextField = new TextField (projectName );
758792 grid .add (projectNameTextField , 1 , 0 );
759793
760794 grid .add (new Label ("Color:" ), 0 , 1 );
761- final ColorPicker colorPicker = new ColorPicker (p . getColor () );
795+ final ColorPicker colorPicker = new ColorPicker (projectColor );
762796 grid .add (colorPicker , 1 , 1 );
763797
764798 grid .add (new Label ("IsWork:" ), 0 , 2 );
765799 final CheckBox isWorkCheckBox = new CheckBox ();
766- isWorkCheckBox .setSelected (p . isWork () );
800+ isWorkCheckBox .setSelected (isWork );
767801 grid .add (isWorkCheckBox , 1 , 2 );
768802
769803 grid .add (new Label ("SortIndex:" ), 0 , 3 );
770- final Spinner <Integer > indexSpinner = new Spinner <>();
771- final int availableProjectAmount = model .availableProjects .size ();
772- indexSpinner .setValueFactory (new IntegerSpinnerValueFactory (0 , availableProjectAmount - 1 , p .getIndex ()));
773- grid .add (indexSpinner , 1 , 3 );
774804
775805 return grid ;
776806 }
0 commit comments