Skip to content

Commit 381b3bc

Browse files
committed
Merge branch 'develop' into feature/sonar_issue_cleanup
# Conflicts: # src/main/java/de/doubleslash/keeptime/DefaultExceptionHandler.java # src/main/java/de/doubleslash/keeptime/Main.java # src/main/java/de/doubleslash/keeptime/common/ColorHelper.java # src/main/java/de/doubleslash/keeptime/common/ConfigParser.java # src/main/java/de/doubleslash/keeptime/common/DateFormatter.java # src/main/java/de/doubleslash/keeptime/controller/Controller.java # src/main/java/de/doubleslash/keeptime/model/Model.java # src/main/java/de/doubleslash/keeptime/view/ReportController.java # src/main/java/de/doubleslash/keeptime/view/SettingsController.java # src/main/java/de/doubleslash/keeptime/view/ViewController.java # src/main/java/de/doubleslash/keeptime/view/time/Interval.java # src/main/java/de/doubleslash/keeptime/viewpopup/GlobalScreenListener.java # src/main/java/de/doubleslash/keeptime/viewpopup/ViewControllerPopup.java # src/main/resources/settings.fxml Has to be tested - lots of conflicts
2 parents 1b0b4b2 + 00a0a3c commit 381b3bc

18 files changed

+474
-344
lines changed

src/main/java/de/doubleslash/keeptime/DefaultExceptionHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@
1212
*/
1313
public class DefaultExceptionHandler implements UncaughtExceptionHandler {
1414

15-
private final Logger log = LoggerFactory.getLogger(this.getClass());
15+
private static final Logger LOG = LoggerFactory.getLogger(DefaultExceptionHandler.class);
1616

1717
@Override
1818
public void uncaughtException(final Thread t, final Throwable e) {
19-
log.error("Uncaught exception on thread '{}'.", t, e);
19+
LOG.error("Uncaught exception on thread '{}'.", t, e);
2020
}
2121

2222
/**
2323
* Registers this class as default uncaught exception handler
2424
*/
2525
public void register() {
26-
log.debug("Registering uncaught exception handler");
26+
LOG.debug("Registering uncaught exception handler");
2727
final UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
2828
if (defaultUncaughtExceptionHandler != null) {
29-
log.warn("Uncaught exception handler was already set ('{}'). Overwritting.", defaultUncaughtExceptionHandler);
29+
LOG.warn("Uncaught exception handler was already set ('{}'). Overwritting.", defaultUncaughtExceptionHandler);
3030
}
3131
Thread.setDefaultUncaughtExceptionHandler(this);
3232
}

src/main/java/de/doubleslash/keeptime/Main.java

Lines changed: 120 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package de.doubleslash.keeptime;
22

33
import java.io.IOException;
4+
import java.io.PrintWriter;
5+
import java.io.StringWriter;
46
import java.time.LocalDate;
57
import java.util.List;
68
import java.util.Optional;
@@ -23,18 +25,26 @@
2325
import de.doubleslash.keeptime.viewpopup.GlobalScreenListener;
2426
import de.doubleslash.keeptime.viewpopup.ViewControllerPopup;
2527
import javafx.application.Application;
28+
import javafx.event.EventHandler;
2629
import javafx.fxml.FXMLLoader;
2730
import javafx.scene.Parent;
2831
import javafx.scene.Scene;
32+
import javafx.scene.control.Alert;
33+
import javafx.scene.control.Alert.AlertType;
34+
import javafx.scene.control.Label;
35+
import javafx.scene.control.TextArea;
36+
import javafx.scene.layout.GridPane;
2937
import javafx.scene.layout.Pane;
38+
import javafx.scene.layout.Priority;
3039
import javafx.scene.paint.Color;
3140
import javafx.stage.Stage;
3241
import javafx.stage.StageStyle;
42+
import javafx.stage.WindowEvent;
3343

3444
@SpringBootApplication
3545
public class Main extends Application {
3646

37-
private final Logger log = LoggerFactory.getLogger(this.getClass());
47+
private static final Logger LOG = LoggerFactory.getLogger(Main.class);
3848

3949
public static final String VERSION = "v0.0.2";
4050

@@ -45,9 +55,13 @@ public class Main extends Application {
4555
private Model model;
4656
private Controller controller;
4757

58+
private ViewController viewController;
59+
60+
private GlobalScreenListener globalScreenListener;
61+
4862
@Override
4963
public void init() throws Exception {
50-
log.info("Starting KeepTime {}", VERSION);
64+
LOG.info("Starting KeepTime {}", VERSION);
5165
final DefaultExceptionHandler defaultExceptionHandler = new DefaultExceptionHandler();
5266
defaultExceptionHandler.register();
5367

@@ -58,46 +72,59 @@ public void init() throws Exception {
5872
}
5973

6074
@Override
61-
public void start(final Stage primaryStage) throws Exception {
75+
public void start(final Stage primaryStage) {
76+
LOG.info("Initialising the UI");
77+
try {
78+
initUI(primaryStage);
79+
LOG.info("UI successfully initialised.");
80+
} catch (final Exception e) {
81+
LOG.error("There was an error while initialising the UI", e);
6282

63-
log.debug("Reading configuration");
83+
final Alert alert = new Alert(AlertType.ERROR);
84+
alert.setTitle("Error");
85+
alert.setHeaderText("Could not start application");
86+
alert.setContentText("Please send the error with your logs folder to a developer");
6487

65-
// TODO there should just be one instance of settings in the repo
66-
final List<Settings> settingsList = model.getSettingsRepository().findAll();
67-
final Settings settings;
68-
if (settingsList.isEmpty()) {
69-
settings = new Settings();
70-
settings.setTaskBarColor(Model.TASK_BAR_COLOR.get());
88+
final StringWriter sw = new StringWriter();
89+
final PrintWriter pw = new PrintWriter(sw);
90+
e.printStackTrace(pw);
91+
final String exceptionText = sw.toString();
7192

72-
settings.setDefaultBackgroundColor(Model.DEFAULT_BACKGROUND_COLOR.get());
73-
settings.setDefaultFontColor(Model.DEFAULT_FONT_COLOR.get());
93+
final Label label = new Label("The exception stacktrace was:");
7494

75-
settings.setHoverBackgroundColor(Model.HOVER_BACKGROUND_COLOR.get());
76-
settings.setHoverFontColor(Model.HOVER_FONT_COLOR.get());
77-
settings.setUseHotkey(false);
78-
settings.setDisplayProjectsRight(true);
79-
model.getSettingsRepository().save(settings);
80-
} else {
81-
settings = settingsList.get(0);
95+
final TextArea textArea = new TextArea(exceptionText);
96+
textArea.setEditable(false);
97+
textArea.setWrapText(true);
98+
99+
textArea.setMaxWidth(Double.MAX_VALUE);
100+
textArea.setMaxHeight(Double.MAX_VALUE);
101+
GridPane.setVgrow(textArea, Priority.ALWAYS);
102+
GridPane.setHgrow(textArea, Priority.ALWAYS);
103+
104+
final GridPane expContent = new GridPane();
105+
expContent.setMaxWidth(Double.MAX_VALUE);
106+
expContent.add(label, 0, 0);
107+
expContent.add(textArea, 0, 1);
108+
109+
alert.getDialogPane().setExpandableContent(expContent);
110+
alert.showAndWait();
111+
System.exit(1);
82112
}
113+
}
83114

84-
Model.DEFAULT_BACKGROUND_COLOR.set(settings.getDefaultBackgroundColor());
85-
Model.DEFAULT_FONT_COLOR.set(settings.getDefaultFontColor());
86-
Model.HOVER_BACKGROUND_COLOR.set(settings.getHoverBackgroundColor());
87-
Model.HOVER_FONT_COLOR.set(settings.getHoverFontColor());
88-
Model.TASK_BAR_COLOR.set(settings.getTaskBarColor());
89-
Model.USE_HOTKEY.set(settings.isUseHotkey());
90-
Model.DISPLAY_PROJECTS_RIGHT.set(settings.isDisplayProjectsRight());
115+
private void initUI(final Stage primaryStage) throws Exception {
116+
117+
readSettings();
91118

92119
final List<Work> todaysWorkItems = model.getWorkRepository().findByCreationDate(LocalDate.now());
93-
log.info("Found {} past work items", todaysWorkItems.size());
120+
LOG.info("Found {} past work items", todaysWorkItems.size());
94121
model.getPastWorkItems().addAll(todaysWorkItems);
95122

96123
final List<Project> projects = model.getProjectRepository().findAll();
97124

98-
log.debug("Found '{}' projects", projects.size());
125+
LOG.debug("Found '{}' projects", projects.size());
99126
if (projects.isEmpty()) {
100-
log.info("Adding default project");
127+
LOG.info("Adding default project");
101128
projects.add(Model.DEFAULT_PROJECT);
102129
model.getProjectRepository().save(Model.DEFAULT_PROJECT);
103130
}
@@ -110,37 +137,58 @@ public void start(final Stage primaryStage) throws Exception {
110137
final Optional<Project> findAny = projects.stream().filter(Project::isDefault).findAny();
111138
if (findAny.isPresent()) {
112139
model.setIdleProject(findAny.get());
113-
log.debug("Using project '{}' as default project.", model.getIdleProject());
140+
LOG.debug("Using project '{}' as default project.", model.getIdleProject());
114141
}
115142

116143
primaryStage.setOnHiding(we -> {
117144
popupViewStage.close();
118-
globalScreenListener.register(false); // deregister, as this will keep app running
145+
globalScreenListener.shutdown(); // deregister, as this will keep app running
119146
});
120147

121-
try {
122-
initialiseUI(primaryStage);
123-
} catch (final Exception e) {
124-
log.error(e.getMessage());
125-
}
148+
initialiseUI(primaryStage);
149+
initialisePopupUI(primaryStage);
150+
}
126151

127-
try {
128-
initialisePopupUI(primaryStage);
129-
} catch (final Exception e) {
130-
log.error(e.getMessage());
152+
private void readSettings() {
153+
LOG.debug("Reading configuration");
154+
155+
final List<Settings> settingsList = model.getSettingsRepository().findAll();
156+
final Settings settings;
157+
if (settingsList.isEmpty()) {
158+
settings = new Settings();
159+
settings.setTaskBarColor(Model.TASK_BAR_COLOR.get());
160+
161+
settings.setDefaultBackgroundColor(Model.ORIGINAL_DEFAULT_BACKGROUND_COLOR);
162+
settings.setDefaultFontColor(Model.ORIGINAL_DEFAULT_FONT_COLOR);
163+
164+
settings.setHoverBackgroundColor(Model.ORIGINAL_HOVER_BACKGROUND_COLOR);
165+
settings.setHoverFontColor(Model.ORIGINAL_HOVER_Font_COLOR);
166+
settings.setUseHotkey(false);
167+
settings.setDisplayProjectsRight(false);
168+
settings.setHideProjectsOnMouseExit(true);
169+
model.getSettingsRepository().save(settings);
170+
} else {
171+
settings = settingsList.get(0);
131172
}
132-
}
133173

134-
GlobalScreenListener globalScreenListener;
174+
Model.DEFAULT_BACKGROUND_COLOR.set(settings.getDefaultBackgroundColor());
175+
Model.DEFAULT_FONT_COLOR.set(settings.getDefaultFontColor());
176+
Model.HOVER_BACKGROUND_COLOR.set(settings.getHoverBackgroundColor());
177+
Model.HOVER_FONT_COLOR.set(settings.getHoverFontColor());
178+
Model.TASK_BAR_COLOR.set(settings.getTaskBarColor());
179+
Model.USE_HOTKEY.set(settings.isUseHotkey());
180+
Model.DISPLAY_PROJECTS_RIGHT.set(settings.isDisplayProjectsRight());
181+
Model.HIDE_PROJECTS_ON_MOUSE_EXIT.set(settings.isHideProjectsOnMouseExit());
182+
}
135183

136184
private void initialisePopupUI(final Stage primaryStage) throws IOException {
137-
// TODO register only if it is enabled
185+
LOG.debug("Initialising popup UI.");
186+
138187
globalScreenListener = new GlobalScreenListener();
139-
// TODO stop and close stage when main stage is shutdown
188+
140189
Model.USE_HOTKEY.addListener((a, b, newValue) -> globalScreenListener.register(newValue));
141190
globalScreenListener.register(Model.USE_HOTKEY.get());
142191

143-
// Platform.setImplicitExit(false); // TODO maybe not needed as other view will be available
144192
popupViewStage = new Stage();
145193
popupViewStage.initOwner(primaryStage);
146194
// Load root layout from fxml file.
@@ -159,44 +207,40 @@ private void initialisePopupUI(final Stage primaryStage) throws IOException {
159207
viewControllerPopupController.setStage(popupViewStage);
160208
viewControllerPopupController.setControllerAndModel(controller, model);
161209
globalScreenListener.setViewController(viewControllerPopupController);
162-
163210
}
164211

165-
ViewController viewController;
166-
167-
private void initialiseUI(final Stage primaryStage) {
168-
try {
169-
Pane mainPane;
170-
171-
// Load root layout from fxml file.
172-
final FXMLLoader loader = new FXMLLoader();
173-
loader.setLocation(Resources.getResource(RESOURCE.FXML_VIEW_LAYOUT));
174-
loader.setControllerFactory(springContext::getBean);
175-
mainPane = loader.load();
176-
primaryStage.initStyle(StageStyle.TRANSPARENT);
177-
// Show the scene containing the root layout.
178-
final Scene mainScene = new Scene(mainPane, Color.TRANSPARENT);
212+
private void initialiseUI(final Stage primaryStage) throws IOException {
213+
LOG.debug("Initialising main UI.");
214+
Pane mainPane;
179215

180-
primaryStage.setTitle("KeepTime");
181-
primaryStage.setScene(mainScene);
182-
primaryStage.setAlwaysOnTop(true);
183-
primaryStage.setResizable(false);
184-
185-
primaryStage.setOnCloseRequest(actionEvent -> log.info("On close request"));
186-
187-
viewController = loader.getController();
188-
// Give the controller access to the main app.
189-
viewController.setStage(primaryStage);
216+
// Load root layout from fxml file.
217+
final FXMLLoader loader = new FXMLLoader();
218+
loader.setLocation(Resources.getResource(RESOURCE.FXML_VIEW_LAYOUT));
219+
loader.setControllerFactory(springContext::getBean);
220+
mainPane = loader.load();
221+
primaryStage.initStyle(StageStyle.TRANSPARENT);
222+
// Show the scene containing the root layout.
223+
final Scene mainScene = new Scene(mainPane, Color.TRANSPARENT);
190224

191-
viewController.setController(controller, model);
225+
// Image(Resources.getResource(RESOURCE.ICON_MAIN).toString())); // TODO use an app icon
192226

193-
primaryStage.show();
227+
primaryStage.setTitle("KeepTime");
228+
primaryStage.setScene(mainScene);
229+
primaryStage.setAlwaysOnTop(true);
230+
primaryStage.setResizable(false);
194231

195-
} catch (
232+
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
233+
@Override
234+
public void handle(final WindowEvent event) {
235+
LOG.info("On close request");
236+
}
237+
});
238+
primaryStage.show();
239+
viewController = loader.getController();
240+
// Give the controller access to the main app.
241+
viewController.setStage(primaryStage);
242+
viewController.setController(controller, model);
196243

197-
final Exception e) {
198-
log.error("Error: " + e.toString(), e);
199-
}
200244
}
201245

202246
@Override

src/main/java/de/doubleslash/keeptime/common/ConfigParser.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import javafx.scene.paint.Color;
1818

1919
public class ConfigParser {
20-
private final Logger log = LoggerFactory.getLogger(this.getClass());
20+
private static final Logger LOG = LoggerFactory.getLogger(ConfigParser.class);
2121

2222
private final Controller controller;
2323

@@ -31,13 +31,13 @@ public static boolean hasConfigFile(final String fileName) {
3131
}
3232

3333
public void parseConfig(final File inputFile) {
34-
log.info("Starting import of projects in file '{}'.", inputFile);
34+
LOG.info("Starting import of projects in file '{}'.", inputFile);
3535
try {
3636
final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
3737
final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
3838
final Document doc = dBuilder.parse(inputFile);
3939
doc.getDocumentElement().normalize();
40-
log.debug("Root element '{}'.", doc.getDocumentElement().getNodeName());
40+
LOG.debug("Root element '{}'.", doc.getDocumentElement().getNodeName());
4141
final NodeList nList = doc.getElementsByTagName("project");
4242

4343
// index makes sure to add new projects at the end
@@ -51,7 +51,7 @@ public void parseConfig(final File inputFile) {
5151
final String isWork = eElement.getElementsByTagName("isWork").item(0).getTextContent();
5252
final String color = eElement.getElementsByTagName("color").item(0).getTextContent();
5353

54-
log.debug("Testing if project with name '{}' already exists.", name);
54+
LOG.debug("Testing if project with name '{}' already exists.", name);
5555
boolean exists = false;
5656

5757
for (final Project p : controller.getAvailableProjects()) {
@@ -61,19 +61,19 @@ public void parseConfig(final File inputFile) {
6161
}
6262
}
6363
if (!exists) {
64-
log.info("Adding project '{}'.", name);
64+
LOG.info("Adding project '{}'.", name);
6565
final Color colorTemp = Color.valueOf(color);
6666
controller.addNewProject(name, Boolean.parseBoolean(isWork), colorTemp, index);
6767
index++;
6868
} else {
69-
log.debug("Project '{}' already exists", name);
69+
LOG.debug("Project '{}' already exists", name);
7070
}
7171

7272
}
7373
}
74-
log.info("Import of '{}' finished.", inputFile);
74+
LOG.info("Import of '{}' finished.", inputFile);
7575
} catch (final Exception e) {
76-
log.error("There was an error while importing projects from config.xml", e);
76+
LOG.error("There was an error while importing projects from config.xml", e);
7777
}
7878
}
7979
}

src/main/java/de/doubleslash/keeptime/common/DateFormatter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ public static String secondsToHHMMSS(final long currentWorkSeconds) {
1919

2020
final int sec = (int) (currentWorkSeconds % 3600 % 60);
2121

22-
return (hours > 9 ? hours : "0" + hours) + ":" + (minutes > 9 ? minutes : "0" + minutes) + ":"
23-
+ (sec > 9 ? sec : "0" + sec);
22+
final Object hoursString = hours > 9 ? hours : "0" + hours;
23+
final Object minutesString = minutes > 9 ? minutes : "0" + minutes;
24+
final Object secondsString = sec > 9 ? sec : "0" + sec;
25+
26+
final String timeString = hoursString + ":" + minutesString + ":" + secondsString;
27+
return timeString;
2428
}
2529

2630
public static long getSecondsBewtween(final LocalDateTime startDate, final LocalDateTime endDate) {

src/main/java/de/doubleslash/keeptime/common/Resources.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
public class Resources {
66

7+
private Resources() {
8+
throw new IllegalStateException("Utility class");
9+
}
10+
711
public enum RESOURCE {
812
/** LAYOUTS **/
913
// main

0 commit comments

Comments
 (0)