Added support for profiles

This commit is contained in:
Robert Vokac 2024-03-03 13:19:59 +00:00
parent bd0bc03e38
commit b7ef2119f3
No known key found for this signature in database
GPG Key ID: 693D30BEE3329055
10 changed files with 180 additions and 42 deletions

4
.gitignore vendored
View File

@ -13,6 +13,8 @@ proxy.txt
out.txt
pocasi.txt
test.txt
timecalc.conf
timecalc*.conf
focus.txt
dist/*
time-calc-current-profile.txt
time-calc-profiles.txt

View File

@ -141,13 +141,13 @@ Smileys can be colored or white-black (can be set in configuration)
* I - disable almost everything
* E - enable or disable battery waves
* B - hide or show buttons
* 0,1,2,3,4,5,6,7,8 or 9 - activates a profile
* F - show numbers for profiles
## Command button
## Todos
* Custom main window title
* Profiles
* Split to Maven modules
* Junit, Mockito, etc.
* Checkstyle

View File

@ -141,6 +141,8 @@ public class TimeCalcConfiguration {
= new BooleanProperty(TimeCalcProperty.WALKING_HUMAN_VISIBLE.getKey());
public final StringProperty mainWindowCustomTitleProperty
= new StringProperty(TimeCalcProperty.MAIN_WINDOW_CUSTOM_TITLE.getKey());
public final StringProperty profileNameProperty
= new StringProperty(TimeCalcProperty.PROFILE_NAME.getKey());
private final Map<TimeCalcProperty, Property> mapOfProperties = new HashMap<>();
private List<Property> allProperties = new ArrayList<>();
@ -190,7 +192,9 @@ public class TimeCalcConfiguration {
squareVisibleProperty,
circleVisibleProperty,
walkingHumanVisibleProperty,
mainWindowCustomTitleProperty,}) {
mainWindowCustomTitleProperty,
profileNameProperty,
}) {
allProperties.add(p);
}
allProperties.stream().forEach(p -> mapOfProperties.put(TimeCalcProperty.forKey(p.getName()), p));
@ -219,7 +223,7 @@ public class TimeCalcConfiguration {
}
Properties properties = new Properties();
this.allProperties.stream().forEach(p -> properties.put(p.getName(), p.getValue()));
this.timeCalcProperties.save(properties);
this.timeCalcProperties.save(properties, this.profileNameProperty.getValue());
}

View File

@ -1,5 +1,7 @@
package org.nanoboot.utils.timecalc.app;
import java.io.IOException;
/**
* @author Robert Vokac
* @since 21.02.2024
@ -9,4 +11,8 @@ public class TimeCalcException extends RuntimeException {
public TimeCalcException(String msg) {
super(msg);
}
public TimeCalcException(Exception e) {
super(e);
}
}

View File

@ -2,11 +2,17 @@ package org.nanoboot.utils.timecalc.app;
import org.nanoboot.utils.timecalc.entity.Visibility;
import org.nanoboot.utils.timecalc.swing.common.MainWindow;
import org.nanoboot.utils.timecalc.swing.common.Toaster;
import org.nanoboot.utils.timecalc.utils.common.Jokes;
import org.nanoboot.utils.timecalc.utils.common.Utils;
import javax.swing.JOptionPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
/**
* @author Robert Vokac
@ -17,7 +23,7 @@ public class TimeCalcKeyAdapter extends KeyAdapter {
private final TimeCalcConfiguration timeCalcConfiguration;
private final TimeCalcApp timeCalcApp;
private final MainWindow window;
private final File timeCalcProfilesTxtFile = new File("time-calc-profiles.txt");
public TimeCalcKeyAdapter(
TimeCalcConfiguration timeCalcConfiguration,
TimeCalcApp timeCalcApp,
@ -157,6 +163,77 @@ public class TimeCalcKeyAdapter extends KeyAdapter {
MainWindow.hideShowCheckBox.setSelected(!MainWindow.hideShowCheckBox.isSelected());
}
boolean numberKeyWasPressed = e.getKeyCode() == KeyEvent.VK_0 ||
e.getKeyCode() == KeyEvent.VK_1 ||
e.getKeyCode() == KeyEvent.VK_2 ||
e.getKeyCode() == KeyEvent.VK_3 ||
e.getKeyCode() == KeyEvent.VK_4 ||
e.getKeyCode() == KeyEvent.VK_5 ||
e.getKeyCode() == KeyEvent.VK_6 ||
e.getKeyCode() == KeyEvent.VK_7 ||
e.getKeyCode() == KeyEvent.VK_8 ||
e.getKeyCode() == KeyEvent.VK_9;
if(numberKeyWasPressed &&!timeCalcProfilesTxtFile.exists()) {
JOptionPane.showMessageDialog(null, "Warning: There is no profile assigned to Key with number, you pressed.", "Warning", JOptionPane.WARNING_MESSAGE);
}
if (numberKeyWasPressed && timeCalcProfilesTxtFile.exists()) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(timeCalcProfilesTxtFile));
} catch (IOException ioException) {
ioException.printStackTrace();
}
int profileNumber = 0;
Toaster toaster = new Toaster();
toaster.setDisplayTime(5000);
switch(e.getKeyCode()) {
case KeyEvent.VK_0: profileNumber = 0;break;
case KeyEvent.VK_1: profileNumber = 1;break;
case KeyEvent.VK_2: profileNumber = 2;break;
case KeyEvent.VK_3: profileNumber = 3;break;
case KeyEvent.VK_4: profileNumber = 4;break;
case KeyEvent.VK_5: profileNumber = 5;break;
case KeyEvent.VK_6: profileNumber = 6;break;
case KeyEvent.VK_7: profileNumber = 7;break;
case KeyEvent.VK_8: profileNumber = 8;break;
case KeyEvent.VK_9: profileNumber = 9;break;
}
String key = String.valueOf(profileNumber);
if(properties.containsKey(key)) {
String profileName = (String) properties.get(key);
if(profileName.equals( timeCalcConfiguration.profileNameProperty)) {
toaster.showToaster("Profile \"" + profileName + "\" is already active. Nothing to do");
} else {
toaster.showToaster("Info: Changing profile to: " + ((
profileName.isEmpty() ? "{Default profile}" :
profileName)));
TimeCalcProperties.getInstance().loadProfile(profileName);
timeCalcConfiguration.loadFromTimeCalcProperties(
TimeCalcProperties.getInstance());
}
} else {
JOptionPane.showMessageDialog(null, "Warning: There is no profile assigned to Key " + profileNumber, "Warning", JOptionPane.WARNING_MESSAGE);
}
}
if (e.getKeyCode() == KeyEvent.VK_F) {
Toaster toaster = new Toaster();
if(timeCalcProfilesTxtFile.exists()) {
toaster.setDisplayTime(15000);
try {
toaster.showToaster(Utils.readTextFromFile(timeCalcProfilesTxtFile));
} catch (IOException ioException) {
ioException.printStackTrace();
toaster.showToaster("Error: " + ioException.getMessage());
}
} else {
toaster.setDisplayTime(15000);
toaster.showToaster("Warning: There are no numbers assigned to profiles. Update file: " + timeCalcProfilesTxtFile.getAbsolutePath() + ".");
}
}
window.repaint();
}

View File

@ -18,17 +18,33 @@ import java.util.Properties;
*/
public class TimeCalcProperties {
public static final File FILE = new File("timecalc.conf");
public static final File FILE_WITHOUT_ANY_PROFILE = new File("timecalc.conf");
private static TimeCalcProperties INSTANCE;
private static final File timeCalcCurrentProfileTxtFile = new File("time-calc-current-profile.txt");
private final Properties properties = new Properties();
private final Map<String, String> defaultProperties = new HashMap<>();
private TimeCalcProperties() {
System.out.println("Loading configuration - start");
String profileName = "";
try {
this.properties.load(new FileInputStream("timecalc.conf"));
profileName = timeCalcCurrentProfileTxtFile.exists() ? Utils.readTextFromFile(
timeCalcCurrentProfileTxtFile) : "";
} catch (IOException e) {
System.err.println(e);
e.printStackTrace();
throw new TimeCalcException(e);
}
File file = getFile(profileName);
if(file.exists()) {
try {
this.properties.load(new FileInputStream(file));
} catch (IOException e) {
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("Loading configuration - end");
System.out.println("Loading default configuration - start");
try {
String defaultConfiguration = Utils.readTextFromTextResourceInJar(
"timecalc-default.conf");
@ -38,14 +54,17 @@ public class TimeCalcProperties {
.filter(l -> l.contains("="))
.forEach(l -> {
String[] array = l.split("=");
defaultProperties.put(array[0], array[1]);
defaultProperties.put(array[0], array.length > 1 ? array[1] : "");
});
} catch (IOException e) {
e.printStackTrace();
throw new TimeCalcException(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
System.out.println("Loading default configuration - end");
}
public static TimeCalcProperties getInstance() {
@ -111,7 +130,7 @@ public class TimeCalcProperties {
properties.replace(key, value.name());
}
public void save(Properties properties) {
public void save(Properties properties, String profileName) {
properties.entrySet().stream().forEach(e
-> {
if (this.properties.containsKey(e.getKey())) {
@ -123,12 +142,31 @@ public class TimeCalcProperties {
}
}
);
File file = getFile(profileName);
try {
this.properties.store(new FileOutputStream(FILE), null);
System.out.println("Saving to " + FILE + " was successful");
this.properties.store(new FileOutputStream(file), null);
System.out.println("Saving to " + file + " was successful");
} catch (IOException e) {
e.printStackTrace();
System.out.println("Saving to " + FILE + " failed: " + e.getMessage());
System.out.println(
"Saving to " + file + " failed: " + e.getMessage());
}
Utils.writeTextToFile(timeCalcCurrentProfileTxtFile, profileName);
}
private File getFile(String profileName) {
return profileName == null || profileName.isEmpty() ?
FILE_WITHOUT_ANY_PROFILE :
new File("timecalc." + profileName + ".conf");
}
public void loadProfile(String profileName) {
try {
this.properties.load( new FileInputStream(getFile(profileName)));
} catch (IOException e) {
System.err.println(e);
}
}
}

View File

@ -62,7 +62,8 @@ public enum TimeCalcProperty {
SQUARE_VISIBLE("square.visible", "Square"),
CIRCLE_VISIBLE("circle.visible", "Circle"),
WALKING_HUMAN_VISIBLE("walking-human.visible", "Walking Human"),
MAIN_WINDOW_CUSTOM_TITLE("main-window.custom-title", "Main Window : Custom Title");
MAIN_WINDOW_CUSTOM_TITLE("main-window.custom-title", "Main Window : Custom Title"),
PROFILE_NAME("profile.name", "Profile : Name");
@Getter
private final String key;

View File

@ -137,6 +137,8 @@ public class ConfigWindow extends TWindow {
= new JCheckBox(TimeCalcProperty.WALKING_HUMAN_VISIBLE.getKey());
private JTextField mainWindowCustomTitleProperty
= new JTextField();
private JTextField profileNameProperty
= new JTextField();
private final JPanel panelInsideScrollPane;
public ConfigWindow(TimeCalcConfiguration timeCalcConfiguration) {
@ -272,7 +274,8 @@ public class ConfigWindow extends TWindow {
squareVisibleProperty,
circleVisibleProperty,
walkingHumanVisibleProperty,
mainWindowCustomTitleProperty));
mainWindowCustomTitleProperty,
profileNameProperty));
//
propertiesList.stream().forEach(p -> {
p.setAlignmentX(LEFT_ALIGNMENT);
@ -288,6 +291,10 @@ public class ConfigWindow extends TWindow {
addToNextRow(new JLabel(TimeCalcProperty.MAIN_WINDOW_CUSTOM_TITLE.getDescription()));
p.putClientProperty(CLIENT_PROPERTY_KEY, TimeCalcProperty.MAIN_WINDOW_CUSTOM_TITLE.getKey());
}
if (p == profileNameProperty) {
addToNextRow(new JLabel(TimeCalcProperty.PROFILE_NAME.getDescription()));
p.putClientProperty(CLIENT_PROPERTY_KEY, TimeCalcProperty.PROFILE_NAME.getKey());
}
if (p instanceof JComboBox) {
JComboBox jComboBox = ((JComboBox) p);
jComboBox.setMaximumSize(new Dimension(150, 25));

View File

@ -13,13 +13,13 @@ _Time Calc is written in Java programming language and uses the Swing framework.
### Start of application
When "Time Calc" is started", user is asked for:
- start time ... like 7:30
- overtime ... like 0:45 ... overtime is optional and the default value is 0:00
- start time ... like 7:30
- overtime ... like 0:45 ... overtime is optional and the default value is 0:00
### Restart of application
You can restart the app, if you press the **"Restart"** button.
- Then you are asked again for start time and overtime.
- Then you are asked again for start time and overtime.
### End of application
@ -33,7 +33,7 @@ If these files are present, something special happens.
### starttime.txt
This file contains the default start time - used during the previous run of the app.
This file contains the default start time - used during the previous run of the app.
If file starttime.txt does not exist, then the default start time is 7:00.
### overtime.txt
@ -48,30 +48,30 @@ If file test.txt exists, then user is not asked for start time and overtime. Ins
### 3 Visibility modes
* STRONGLY_COLORED - many colors
* WEAKLY_COLORED - darkened colors
* GRAY - gray colors
* NONE - widgets are hidden
* STRONGLY_COLORED - many colors
* WEAKLY_COLORED - darkened colors
* GRAY - gray colors
* NONE - widgets are hidden
### Widgets
*
*
#### Analog Clock
* hour hand
* minute hand (can be disabled in configuration)
* second hand (can be disabled in configuration)
* millisecond hand (can be disabled in configuration)
* shows current year, month, day of month and day of week, if analog clock is hovered by mouse cursor and Visibility is STRONGLY_COLORED
* shows yellow highlighted remaining time until end of today working hours, if analog clock is hovered by mouse cursor and Visibility is STRONGLY_COLORED
* hands can be long or shorter (can be set in configuration)
* hour hand
* minute hand (can be disabled in configuration)
* second hand (can be disabled in configuration)
* millisecond hand (can be disabled in configuration)
* shows current year, month, day of month and day of week, if analog clock is hovered by mouse cursor and Visibility is STRONGLY_COLORED
* shows yellow highlighted remaining time until end of today working hours, if analog clock is hovered by mouse cursor and Visibility is STRONGLY_COLORED
* hands can be long or shorter (can be set in configuration)
#### Progress Square
* Show graphically day progress
* Show graphically day progress
#### Progress Circle
* Show graphically day progress
* Show graphically day progress
#### Hour Battery
@ -141,18 +141,19 @@ Smileys can be colored or white-black (can be set in configuration)
* I - disable almost everything
* E - enable or disable battery waves
* B - hide or show buttons
* 0,1,2,3,4,5,6,7,8 or 9 - activates a profile
* F - show numbers for profiles
## Command button
## Todos
* Config window
* Split to Maven modules
* Junit, Mockito, etc.
* Checkstyle
* Sonarlint
* Sonarqube
* Add SQLite support and store times of arrivals and departures and time of activities
* Split to Maven modules
* Junit, Mockito, etc.
* Checkstyle
* Sonarlint
* Sonarqube
* Add SQLite support and store times of arrivals and departures and time of activities
## For Developers

View File

@ -44,6 +44,8 @@ smileys.colored=true
square.visible=true
circle.visible=true
walking-human.visible=true
main-window.custom-title=---
profile.name=
#TODO:
logs.detailed=false