Added new improvements

This commit is contained in:
Robert Vokac 2024-02-03 23:34:12 +00:00
parent 75c25fe5ae
commit ac4d52cf0f
No known key found for this signature in database
GPG Key ID: 693D30BEE3329055
26 changed files with 337 additions and 130 deletions

View File

@ -1,5 +1,47 @@
# Time Calc
# Hint files
## Introduction
focus.txt - request focus for the window
Time Calc is a desktop application used to track the remaining time until the end of some activity - like working hours.
_Time Calc is written in Java programming language and using the Swing framework._
![Tux, the Linux mascot](images/screenshot.png)
## Usage
### 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
### Restart of application
You can restart the app, if you press the **"Restart"** button.
- Then you are asked again for start time and overtime.
### End of application
You can stop the app, if you press the **"Exit"** button or click on the exit window button.
- Then application is stopped.
## Special files
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.
If file starttime.txt does not exist, then the default start time is 7:00.
### overtime.txt
This file contains the default overtime - used during the previous run of the app.
If file overtime.txt does not exist, then the default overtime is 0:00.
### test.txt
If file test.txt exists, then user is not asked for start time and overtime. Instead, the values in files starttime.txt and overtime.txt are used.
### focus.txt
Requests focus for the window.

BIN
images/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -4,9 +4,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>rvc</groupId>
<groupId>org.nanoboot.utils</groupId>
<artifactId>time-calc</artifactId>
<version>1.0.0</version>
<version>0.1.0-SNAPSHOT</version>
<name>time-calc</name>
<description>time-calc</description>
@ -40,7 +40,7 @@
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>rvc.timecalc.Main</mainClass>
<mainClass>org.nanoboot.utils.timecalc.main.Main</mainClass>
</manifest>
</archive>
</configuration>
@ -53,7 +53,7 @@
<!-- <configuration>-->
<!-- <archive>-->
<!-- <manifest>-->
<!-- <mainClass>rvc.timecalc.Main</mainClass>-->
<!-- <mainClass>Main</mainClass>-->
<!-- <addDefaultImplementationEntries>true</addDefaultImplementationEntries>-->
<!-- </manifest>-->
<!-- <manifestEntries>-->

View File

@ -1,8 +1,9 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
import org.nanoboot.utils.timecalc.main.TimeCalcConf;
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;

View File

@ -1,14 +1,13 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
import org.nanoboot.utils.timecalc.main.TimeCalcConf;
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;

View File

@ -1,4 +1,6 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
import org.nanoboot.utils.timecalc.utils.Utils;
import java.awt.Color;
import java.awt.Dimension;

View File

@ -1,14 +1,12 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class ProgressSquare extends Widget {

View File

@ -0,0 +1,13 @@
package org.nanoboot.utils.timecalc.gui;
import javax.swing.JButton;
/**
* @author Robert
* @since 21.02.2024
*/
public class TimeCalcButton extends JButton {
public TimeCalcButton(String label) {
super(label);
}
}

View File

@ -1,4 +1,4 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
/**
* Java Toaster is a java utility class for your swing applications
* that show an animate box coming from the bottom of your screen
@ -28,6 +28,8 @@ package rvc.timecalc;
* }
*/
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;

View File

@ -1,4 +1,6 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
@ -19,7 +21,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
/**
* @author Robert
* @author pc00289
* @since 16.02.2024
*/
public class WeatherWindow extends JFrame {

View File

@ -1,4 +1,6 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.gui;
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.swing.JPanel;
import javax.swing.Timer;
@ -7,7 +9,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* @author Robert
* @author pc00289
* @since 20.02.2024
*/
public class Widget extends JPanel {

View File

@ -0,0 +1,60 @@
package org.nanoboot.utils.timecalc.main;
import org.nanoboot.utils.timecalc.utils.Constants;
import org.nanoboot.utils.timecalc.utils.Utils;
import org.nanoboot.utils.timecalc.utils.FileConstants;
import javax.swing.JOptionPane;
import java.io.IOException;
/**
* @author Robert
* @since 31.01.2024
*/
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
boolean test = FileConstants.TEST_TXT.exists();
String oldStartTime = Utils.readTextFromFile(
FileConstants.STARTTIME_TXT);
String oldOvertime = Utils.readTextFromFile(
FileConstants.OVERTIME_TXT);
String newStartTime =
test ? (oldStartTime != null ? oldStartTime : Constants.DEFAULT_START_TIME) : (String) JOptionPane.showInputDialog(
null,
"Start Time:",
"Start Time",
JOptionPane.PLAIN_MESSAGE,
null,
null,
oldStartTime == null ? Constants.DEFAULT_START_TIME : oldStartTime
);
String newOvertime =
test ? (oldOvertime != null ? oldOvertime : Constants.DEFAULT_OVERTIME) : (String) JOptionPane.showInputDialog(
null,
"Overtime:",
"Overtime",
JOptionPane.PLAIN_MESSAGE,
null,
null,
oldOvertime == null ? Constants.DEFAULT_OVERTIME : oldOvertime
);
Utils.writeTextToFile(FileConstants.STARTTIME_TXT, newStartTime);
Utils.writeTextToFile(FileConstants.OVERTIME_TXT, newOvertime);
try {
TimeCalcWindow timeCalc =
new TimeCalcWindow(newStartTime, newOvertime);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error: " + e.getMessage(),
e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
}
}

View File

@ -1,4 +1,4 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.main;
import java.io.File;
import java.io.FileInputStream;
@ -6,7 +6,7 @@ import java.io.IOException;
import java.util.Properties;
/**
* @author Robert
* @author pc00289
* @since 20.02.2024
*/
public class TimeCalcConf {
@ -37,34 +37,25 @@ public class TimeCalcConf {
}
public boolean areClockHandsLong() {
if(!properties.containsKey(CLOCK_HANDS_LONG)) {
return true;
}
return properties.get(CLOCK_HANDS_LONG).equals("true");
return getBooleanProperty(CLOCK_HANDS_LONG, true);
}
public boolean isJokeVisible() {
if(!properties.containsKey(JOKE_VISIBLE)) {
return true;
}
return properties.get(JOKE_VISIBLE).equals("true");
return getBooleanProperty(JOKE_VISIBLE, true);
}
public boolean areBatteryWavesEnabled() {
if(!properties.containsKey(BATTERY_WAVES_ENABLED)) {
return true;
}
return properties.get(BATTERY_WAVES_ENABLED).equals("true");
return getBooleanProperty(BATTERY_WAVES_ENABLED, true);
}
public boolean isEverythingHidden() {
if(!properties.containsKey(EVERYTHING_HIDDEN)) {
return false;
}
return properties.get(EVERYTHING_HIDDEN).equals("true");
return getBooleanProperty(EVERYTHING_HIDDEN, false);
}
public boolean areToastsEnabled() {
if(!properties.containsKey(TOASTS_ENABLED)) {
return true;
return getBooleanProperty(TOASTS_ENABLED, true);
}
private boolean getBooleanProperty(String key, boolean defaultValue) {
if(!properties.containsKey(key)) {
return defaultValue;
}
return properties.get(EVERYTHING_HIDDEN).equals("true");
return properties.get(key).equals("true");
}
}

View File

@ -0,0 +1,11 @@
package org.nanoboot.utils.timecalc.main;
/**
* @author Robert
* @since 21.02.2024
*/
public class TimeCalcException extends RuntimeException{
public TimeCalcException(String msg) {
super(msg);
}
}

View File

@ -1,4 +1,15 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.main;
import org.nanoboot.utils.timecalc.gui.TimeCalcButton;
import org.nanoboot.utils.timecalc.gui.Toaster;
import org.nanoboot.utils.timecalc.gui.WeatherWindow;
import org.nanoboot.utils.timecalc.gui.AnalogClock;
import org.nanoboot.utils.timecalc.gui.Battery;
import org.nanoboot.utils.timecalc.gui.ProgressCircle;
import org.nanoboot.utils.timecalc.gui.ProgressSquare;
import org.nanoboot.utils.timecalc.utils.Constants;
import org.nanoboot.utils.timecalc.utils.Jokes;
import org.nanoboot.utils.timecalc.utils.Utils;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
@ -34,13 +45,17 @@ import java.util.Set;
*/
public class TimeCalcWindow {
public static final String WALL = "||";
private static final String DEFAULT_OVERTIME = "0:00";
private static final int WORKING_HOURS_LENGTH = 8;
private static final int WORKING_MINUTES_LENGTH = 30;
private static final String NEW_LINE = "\n";
private final static DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
private static final int MARGIN = 10;
public static final int BUTTON_WIDTH = 100;
public static final int BUTTON_HEIGHT = 30;
private final String startTime;
private final String windowTitle;
private String overTime;
private final int startHour;
private final int startMinute;
@ -60,7 +75,7 @@ public class TimeCalcWindow {
this.startTime = startTimeIn;
this.overTime = (overTimeIn == null || overTimeIn.isEmpty()) ?
DEFAULT_OVERTIME : overTimeIn;
Constants.DEFAULT_OVERTIME : overTimeIn;
this.startHour = Integer.valueOf(startTime.split(":")[0]);
this.startMinute = Integer.valueOf(startTime.split(":")[1]);
@ -86,12 +101,25 @@ public class TimeCalcWindow {
JFrame window = new JFrame();
JButton focusButton = new JButton("F");
JButton commandButton = new JButton("Command");
JButton weatherButton = new JButton("Weather");
JButton jokeButton = new JButton("Joke");
JButton restartButton = new JButton("Restart");
JButton exitButton = new JButton("Exit");
TimeCalcButton focusButton = new TimeCalcButton("F");
TimeCalcButton commandButton = new TimeCalcButton("Command");
TimeCalcButton weatherButton = new TimeCalcButton("Weather");
TimeCalcButton jokeButton = new TimeCalcButton("Joke");
TimeCalcButton restartButton = new TimeCalcButton("Restart");
TimeCalcButton exitButton = new TimeCalcButton("Exit");
TimeCalcButton aboutButton = new TimeCalcButton("About");
aboutButton.addActionListener(e -> {
String version = Utils.getVersion();
String buildDate = Utils.getBuildDate();
if (version == null) {
version = "unknown";
}
if (buildDate == null) {
buildDate = "unknown";
}
JOptionPane.showMessageDialog(null, "Version: " + version + "\n" + "Built on (universal time): " + buildDate, "About \"Pdf DME Downloader\"", JOptionPane.INFORMATION_MESSAGE);
});
//window.add(weatherButton);
window.add(commandButton);
@ -168,20 +196,24 @@ public class TimeCalcWindow {
window.add(text);
weatherButton
.setBounds(20, text.getY() + text.getHeight() + 10, 100, 30);
commandButton.setBounds(20, text.getY() + text.getHeight() + 10, 100, 30);
.setBounds(20, text.getY() + text.getHeight() + MARGIN, BUTTON_WIDTH,
BUTTON_HEIGHT);
commandButton.setBounds(20, text.getY() + text.getHeight() + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT);
jokeButton.setBounds(140, text.getY() + text.getHeight() + 10, 100, 30);
jokeButton.setBounds(140, text.getY() + text.getHeight() + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT);
restartButton
.setBounds(280, text.getY() + text.getHeight() + 10, 100, 30);
exitButton.setBounds(390, text.getY() + text.getHeight() + 10, 100, 30);
.setBounds(280, text.getY() + text.getHeight() + MARGIN,
BUTTON_WIDTH, BUTTON_HEIGHT);
exitButton.setBounds(390, text.getY() + text.getHeight() + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT);
aboutButton.setBounds(exitButton.getX(), exitButton.getY() + exitButton.getHeight() + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT);
focusButton.setBounds(exitButton.getX() + 10 + 10 + 10 + exitButton.getWidth() + 20, 10, 60, 30);
focusButton.setBounds(exitButton.getX() + 3 * MARGIN + exitButton.getWidth() + 20, MARGIN, 60, BUTTON_HEIGHT);
window.setSize(520 + 20 + 100, 580);
window.setSize(520 + 20 + 100, 580 + MARGIN + BUTTON_WIDTH);
window.setLayout(null);
window.setVisible(true);
window.setTitle("Time Calc");
this.windowTitle = createWindowTitle();
window.setTitle(windowTitle);
window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
window.addWindowListener(new java.awt.event.WindowAdapter() {
@ -210,7 +242,7 @@ public class TimeCalcWindow {
case "color": Utils.highlighted.set(commandsAsArray[1].equals("1"));break;
case "gray": Utils.ultraLight.set(commandsAsArray[1].equals("1"));break;
case "waves": Battery.wavesOff = commandsAsArray[1].equals("0");break;
case "uptime": JOptionPane.showMessageDialog(null, ((int)((System.nanoTime() - Main.startNanoTime) / 1000000000 / 60)) + " minutes");break;
case "uptime": JOptionPane.showMessageDialog(null, Utils.getCountOfMinutesSinceAppStarted() + " minutes");break;
case "toast":
Toaster t = new Toaster();
t.setToasterWidth(800);
@ -493,6 +525,10 @@ public class TimeCalcWindow {
window.dispose();
}
private String createWindowTitle() {
return "Time Calc " + Utils.getVersion();
}
private static final String createSpaces(int spaceCount) {
return create(spaceCount, ' ');
}

View File

@ -1,7 +1,7 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.utils;
/**
* @author Robert
* @author pc00289
* @since 16.02.2024
*/
public class BooleanHolder {

View File

@ -0,0 +1,14 @@
package org.nanoboot.utils.timecalc.utils;
/**
* @author Robert
* @since 21.02.2024
*/
public class Constants {
public static final String DEFAULT_START_TIME = "7:00";
public static final String DEFAULT_OVERTIME = "0:00";
private Constants() {
//Not meant to be instantiated.
}
}

View File

@ -0,0 +1,11 @@
package org.nanoboot.utils.timecalc.utils;
/**
* @author Robert
* @since 21.02.2024
*/
public class DateFormats {
private DateFormats() {
//Not meant to be instantiated.
}
}

View File

@ -0,0 +1,16 @@
package org.nanoboot.utils.timecalc.utils;
import java.io.File;
/**
* @author Robert
* @since 21.02.2024
*/
public class FileConstants {
private FileConstants() {
//Not meant to be instantiated.
}
public static final File STARTTIME_TXT = new File("starttime.txt");
public static final File OVERTIME_TXT = new File("overtime.txt");
public static final File TEST_TXT = new File("test.txt");
}

View File

@ -1,10 +1,10 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.utils;
import java.io.File;
import java.io.IOException;
/**
* @author Robert
* @author pc00289
* @since 16.02.2024
*/
public class HttpProxy {

View File

@ -1,4 +1,7 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.utils;
import org.nanoboot.utils.timecalc.gui.Toaster;
import org.nanoboot.utils.timecalc.main.TimeCalcConf;
import javax.swing.JFrame;
import javax.swing.JTextPane;

View File

@ -1,4 +1,4 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.utils;
import java.io.BufferedReader;
import java.io.IOException;

View File

@ -0,0 +1,11 @@
package org.nanoboot.utils.timecalc.utils;
/**
* @author Robert
* @since 21.02.2024
*/
public class NumberFormats {
private NumberFormats() {
//Not meant to be instantiated.
}
}

View File

@ -1,17 +1,24 @@
package rvc.timecalc;
package org.nanoboot.utils.timecalc.utils;
import org.nanoboot.utils.timecalc.main.Main;
import org.nanoboot.utils.timecalc.main.TimeCalcException;
import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
/**
* @author Robert
* @author pc00289
* @since 15.02.2024
*/
public class Utils {
private static long startNanoTime;
public static final BooleanHolder highlighted = new BooleanHolder();
public static final BooleanHolder ultraLight = new BooleanHolder();
public static final BooleanHolder everythingHidden = new BooleanHolder();
@ -21,6 +28,12 @@ public class Utils {
* Count of bytes per one kilobyte.
*/
private static final int COUNT_OF_BYTES_PER_ONE_KILOBYTE = 1024;
public static void startApp() {
if(startNanoTime == 0) {
throw new TimeCalcException("App is already started.");
}
startNanoTime = System.nanoTime();
}
private Utils() {
//Not meant to be instantiated.
}
@ -74,4 +87,41 @@ public class Utils {
return new Color(((int) (Math.random() * 256)),
((int) (Math.random() * 256)), ((int) (Math.random() * 256)));
}
public static int getCountOfMinutesSinceAppStarted() {
return ((int)((System.nanoTime() - startNanoTime) / 1000000000 / 60));
}
/**
* Returns version of "Time Calc" from jar file.
* @return version
*/
public static String getVersion() {
String version = Main.class.getPackage().getImplementationVersion();
return version;
}
/**
* Returns build date of "Time Calc" from jar file.
* @return build date
*/
public static String getBuildDate() {
Class clazz = Main.class;
String className = clazz.getSimpleName() + ".class";
String classPath = clazz.getResource(className).toString();
if (!classPath.startsWith("jar")) {
return null;
}
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1)
+ "/META-INF/MANIFEST.MF";
Manifest manifest;
try {
manifest = new Manifest(new URL(manifestPath).openStream());
} catch (IOException e) {
System.err.println(e.getMessage());
return "";
}
Attributes attr = manifest.getMainAttributes();
return attr.getValue("Build-Date");
}
}

View File

@ -1,57 +0,0 @@
package rvc.timecalc;
import javax.swing.JOptionPane;
import java.io.File;
import java.io.IOException;
/**
* @author Robert
* @since 31.01.2024
*/
public class Main {
public static long startNanoTime;
public static void main(String[] args) throws IOException {
startNanoTime = System.nanoTime();
while (true) {
boolean test = new File("test.txt").exists();
File starttimeTxt = new File("starttime.txt");
File overtimeTxt = new File("overtime.txt");
String lastStartTime = Utils.readTextFromFile(starttimeTxt);
String lastOvertime = Utils.readTextFromFile(overtimeTxt);
String startTime =
test ? (lastStartTime != null ? lastStartTime : "7:00") : (String) JOptionPane.showInputDialog(
null,
"Start Time:",
"Start Time",
JOptionPane.PLAIN_MESSAGE,
null,
null,
lastStartTime == null ? "7:00" : lastStartTime
);
String overTime =
test ? (lastOvertime != null ? lastOvertime : "0:00") : (String) JOptionPane.showInputDialog(
null,
"Overtime:",
"Overtime",
JOptionPane.PLAIN_MESSAGE,
null,
null,
lastOvertime == null ? "0:00" : lastOvertime
);
Utils.writeTextToFile(starttimeTxt, startTime);
Utils.writeTextToFile(overtimeTxt, overTime);
try {
TimeCalcWindow timeCalc =
new TimeCalcWindow(startTime, overTime);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error: " + e.getMessage(),
e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
}
}

View File

@ -2,4 +2,4 @@ clock.colorful=false
clock.hands.long=true
jokes.visible=true
battery.waves.enabled=true
everything-hidden=true
everything-hidden=false