This commit is contained in:
Robert Vokac 2024-03-23 08:20:07 +01:00
parent 5f33e62c76
commit 7f035a931d
No known key found for this signature in database
GPG Key ID: 693D30BEE3329055
12 changed files with 366 additions and 10 deletions

View File

@ -188,6 +188,8 @@ public class TimeCalcConfiguration {
= new IntegerProperty(TimeCalcProperty.MONEY_PER_MONTH.getKey());
public final StringProperty moneyCurrencyProperty
= new StringProperty(TimeCalcProperty.MONEY_CURRENCY.getKey());
public final BooleanProperty weatherVisibleProperty
= new BooleanProperty(TimeCalcProperty.WEATHER_VISIBLE.getKey());
public final StringProperty mainWindowCustomTitleProperty
= new StringProperty(
TimeCalcProperty.MAIN_WINDOW_CUSTOM_TITLE.getKey());
@ -278,6 +280,7 @@ public class TimeCalcConfiguration {
moneyTypeProperty,
moneyPerMonthProperty,
moneyCurrencyProperty,
weatherVisibleProperty,
mainWindowCustomTitleProperty,
profileNameProperty,
activityNeededFlagsProperty,

View File

@ -95,6 +95,7 @@ public enum TimeCalcProperty {
MONEY_TYPE("money.type", "Money : Type"),
MONEY_PER_MONTH("money.per-month", "Money : Per month", Integer.class),
MONEY_CURRENCY("money.currency", "Money : Currency", String.class),
WEATHER_VISIBLE("weather.visible", "Weather"),
MAIN_WINDOW_CUSTOM_TITLE("main-window.custom-title","Main Window : Custom Title"),
PROFILE_NAME("profile.name", "Profile : Name"),
TEST_ENABLED("test.enabled", "Test : Enabled", Boolean.class),

View File

@ -4,6 +4,7 @@ import org.nanoboot.utils.timecalc.app.TimeCalcException;
import org.nanoboot.utils.timecalc.entity.WidgetType;
import org.nanoboot.utils.timecalc.swing.progress.AnalogClock;
import org.nanoboot.utils.timecalc.swing.progress.Battery;
import org.nanoboot.utils.timecalc.swing.progress.ProgressWeather;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
@ -55,7 +56,7 @@ public class WidgetMenu extends JPopupMenu {
BiConsumer<JMenuItem, WidgetType> typeActionCreator = (m,w) -> {
m.addActionListener(e -> {
if(((widget instanceof Battery) || (widget instanceof AnalogClock)) && !widget.typeProperty.getValue().equals(w.name().toLowerCase(Locale.ROOT))) {
if(((widget instanceof Battery) || (widget instanceof AnalogClock) || (widget instanceof ProgressWeather)) && !widget.typeProperty.getValue().equals(w.name().toLowerCase(Locale.ROOT))) {
//nothing to do
return;
}

View File

@ -0,0 +1,36 @@
package org.nanoboot.utils.timecalc.swing.progress;
import lombok.Getter;
import org.nanoboot.utils.timecalc.app.TimeCalcException;
import java.util.Arrays;
import java.util.Optional;
/**
* @author pc00289
* @since 22.03.2024
*/
public enum DayOfWeekTC {
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6),
SUNDAY(7);
@Getter
private final int number;
public static DayOfWeekTC forNumber(int number) {
Optional<DayOfWeekTC> result = Arrays.stream(DayOfWeekTC.values()).filter(d -> d.getNumber() == number).findFirst();
if(result.isPresent()) {
return result.get();
} else {
throw new TimeCalcException("There is noDayOfWeekTC with number: " + number);
}
}
DayOfWeekTC(int number) {
this.number = number;
}
}

View File

@ -27,14 +27,12 @@ import java.util.Locale;
*/
public class ProgressMoney extends Widget implements GetProperty {
private final Time time;
public IntegerProperty perMonthProperty
= new IntegerProperty("money.perMonthProperty");
public StringProperty currencyProperty
= new StringProperty("money.currencyProperty");
public ProgressMoney(Time time) {
this.time = time;
public ProgressMoney() {
setFont(new Font(Font.MONOSPACED, Font.PLAIN, 11));
setFocusable(false);

View File

@ -0,0 +1,164 @@
package org.nanoboot.utils.timecalc.swing.progress;
import org.nanoboot.utils.timecalc.app.GetProperty;
import org.nanoboot.utils.timecalc.entity.Visibility;
import org.nanoboot.utils.timecalc.entity.WidgetType;
import org.nanoboot.utils.timecalc.swing.common.SwingUtils;
import org.nanoboot.utils.timecalc.swing.common.Widget;
import org.nanoboot.utils.timecalc.swing.windows.MainWindow;
import org.nanoboot.utils.timecalc.utils.common.DateFormats;
import org.nanoboot.utils.timecalc.utils.common.FileConstants;
import org.nanoboot.utils.timecalc.utils.common.TTime;
import org.nanoboot.utils.timecalc.utils.common.Utils;
import org.nanoboot.utils.timecalc.utils.property.Property;
import javax.swing.Timer;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author Robert Vokac
* @since 21.02.2024
*/
public class ProgressWeather extends Widget implements GetProperty {
private final Time time;
public ProgressWeather(Time time) {
this.time = time;
setFont(new Font(Font.MONOSPACED, Font.PLAIN, 11));
setFocusable(false);
setForeground(Color.GRAY);
setBackground(MainWindow.BACKGROUND_COLOR);
this.typeProperty.setValue(WidgetType.DAY.name().toLowerCase(Locale.ROOT));
new Timer(100, e -> {
Visibility visibility
= Visibility.valueOf(visibilityProperty.getValue());
setForeground(
visibility.isStronglyColored()
|| mouseOver
? Color.BLACK : Color.LIGHT_GRAY);
}).start();
}
private static Map<Integer, List<WeatherForecast>> forecastsForYears = new HashMap<>();
@Override
public void paintWidget(Graphics brush) {
Visibility visibility
= Visibility.valueOf(visibilityProperty.getValue());
brush.setColor(visibility.isStronglyColored() ? Color.BLUE
: visibility.isWeaklyColored() ? Color.GRAY
: Color.LIGHT_GRAY);
brush.setFont(SwingUtils.MEDIUM_MONOSPACE_FONT);
int year = time.yearProperty.getValue();
if(!forecastsForYears.containsKey(year)) {
File weatherFile = new File(FileConstants.WEATHER_TXT.getParentFile(),
String.valueOf(year) + '_' + FileConstants.WEATHER_TXT.getName());
System.out.println(weatherFile.getAbsolutePath());
if (!weatherFile.exists()) {
List<WeatherForecast> forecasts = WeatherForecast.createForecast();
Utils.writeTextToFile(weatherFile,
forecasts.stream().map(w -> w.toCsv()).collect(
Collectors.joining("\n")));
}
List<WeatherForecast> forecasts = new ArrayList<>();
try {
Arrays.stream(Utils.readTextFromFile(weatherFile).split("\n")).filter(line -> !line.isEmpty()).forEach(line -> forecasts.add(new WeatherForecast().fromCsv(line)));
} catch (IOException e) {
System.out.println("Loading file failed: " + weatherFile + " " + e
.getMessage());
e.printStackTrace();
return;
}
forecastsForYears.put(year, forecasts);
}
List<WeatherForecast> forecasts = forecastsForYears.get(year);
int currentSecond = time.secondProperty.getValue();
Calendar cal = time.asCalendar();
int add = (currentSecond % 14);
switch (add) {
case 0:
add = 0; break;
case 1:
add = 0; break;
case 2:
add = 1; break;
case 3:
add = 1; break;
case 4:
add = 2; break;
case 5:
add = 2; break;
case 6:
add = 3; break;
case 7:
add = 3; break;
case 8:
add = 4; break;
case 9:
add = 4; break;
case 10:
add = 5; break;
case 11:
add = 5; break;
case 12:
add = 6; break;
case 13:
add = 6; break;
default:
add = 7; break;
}
add = add / 2;
if (add > 0) {
cal.add(Calendar.DAY_OF_MONTH, add);
}
int currentDayOfWeek = time.dayOfWeekProperty.getValue();
int forecastDayOfWeek = currentDayOfWeek + add;
// String dayOfWeekAsString = DayOfWeekTC.forNumber(forecastDayOfWeek).name();
// dayOfWeekAsString = dayOfWeekAsString.substring(0,1).toUpperCase(Locale.ROOT) + dayOfWeekAsString.substring(1, dayOfWeekAsString.length());
WeatherForecast weatherForecast = forecasts.stream().filter(f -> f.getDate().equals(DateFormats.DATE_TIME_FORMATTER_YYYYMMDD.format(cal.getTime()))).findFirst().orElse(new WeatherForecast());
int rowHeight = 25;
int row = 10;
brush.drawString(DateFormats.DATE_TIME_FORMATTER_YYYYMMDD.format(cal.getTime()), SwingUtils.MARGIN, SwingUtils.MARGIN + row);
row = row + rowHeight;
brush.drawString(DateFormats.DATE_TIME_FORMATTER_DAY_OF_WEEK.format(cal.getTime()), SwingUtils.MARGIN, SwingUtils.MARGIN + row);
row = row + rowHeight;
brush.drawString(weatherForecast.asPrettyString(new TTime(time.hourProperty.getValue(),
time.minuteProperty.getValue(),
time.secondProperty.getValue(),
time.millisecondProperty.getValue()).toTotalMilliseconds() / 1000d / 60d / 60d), SwingUtils.MARGIN, SwingUtils.MARGIN + row);
row = row + rowHeight;
}
@Override
public Property getVisibilityProperty() {
return visibilityProperty;
}
@Override
public Property getVisibilitySupportedColoredProperty() {
return visibilitySupportedColoredProperty;
}
}

View File

@ -0,0 +1,136 @@
package org.nanoboot.utils.timecalc.swing.progress;
import lombok.Getter;
import org.nanoboot.utils.timecalc.utils.common.FileConstants;
import org.nanoboot.utils.timecalc.utils.common.NumberFormats;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* @author pc00289
* @since 22.03.2024
*/
@Getter
public class WeatherForecast {
//01:00-4:00 - minimum
//13:00-16:00 - maximum
//20240101.minTempC=
//20240101.maxTempC=
// 20240101.minTempTime=
//20240101.maxTempTime=
//20240101.wind={m/s}
//20240101.cloudiness={0.0 - 1.0}
//20240101.thunder={0.0 - 1.0}
//20240101.rain={mm}
//20240101.snow={mm}
//#20240101.sunrise=7:53
//#20240101.sunset=16:02
private String date;
private double minimumCelsius;
private double maximumCelsius;
private double minimumCelsiusTime;
private double maximumCelsiusTime;
private double wind;
private double cloudiness;
private double thunder;
private double rain;
private double snow;
public static List<WeatherForecast> createForecast() {
List<WeatherForecast> list = new ArrayList<>();
Properties climateProperties = new Properties();
if(FileConstants.CLIMATE_TXT.exists()) {
try {
climateProperties.load(new FileInputStream(FileConstants.CLIMATE_TXT));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Loading file failed: " + FileConstants.WEATHER_TXT + " " + e.getMessage());
return list;
}
} else {
System.out.println("File does not exist: " + FileConstants.CLIMATE_TXT);
return list;
}
double min1= Double.valueOf(climateProperties.getProperty("1.min", "0"));
double min2= Double.valueOf(climateProperties.getProperty("2.min", "1"));
double min3= Double.valueOf(climateProperties.getProperty("3.min", "2"));
double min4= Double.valueOf(climateProperties.getProperty("4.min", "4"));
double min5= Double.valueOf(climateProperties.getProperty("5.min", "6"));
double min6= Double.valueOf(climateProperties.getProperty("6.min", "8"));
double min7= Double.valueOf(climateProperties.getProperty("7.min", "8"));
double min8= Double.valueOf(climateProperties.getProperty("8.min", "6"));
double min9= Double.valueOf(climateProperties.getProperty("9.min", "4"));
double min10= Double.valueOf(climateProperties.getProperty("10.min", "2"));
double min11= Double.valueOf(climateProperties.getProperty("11.min", "1"));
double min12= Double.valueOf(climateProperties.getProperty("12.min", "0"));
return list;
}
public String toCsv() {
StringBuilder sb = new StringBuilder();
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(minimumCelsius)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(maximumCelsius)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(minimumCelsiusTime)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(maximumCelsiusTime)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(wind)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(cloudiness)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(thunder)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(rain)).append('\t');
sb.append(NumberFormats.FORMATTER_FIVE_DECIMAL_PLACES.format(snow));
return sb.toString();
}
public WeatherForecast fromCsv(String csv) {
String[] values = csv.split("\t");
int i = 0;
minimumCelsius = Double.valueOf(values[i++]);
maximumCelsius = Double.valueOf(values[i++]);
minimumCelsiusTime = Double.valueOf(values[i++]);
maximumCelsiusTime = Double.valueOf(values[i++]);
wind = Double.valueOf(values[i++]);
cloudiness = Double.valueOf(values[i++]);
thunder = Double.valueOf(values[i++]);
rain = Double.valueOf(values[i++]);
snow = Double.valueOf(values[i++]);
return this;
}
public String asPrettyString(double forHour) {
return "14°C, wind 7/s, rain 2mm, cloudy";
}
}
/*
climate.txt
1.max=18.8
2.max=22.0
3.max=26.2
4.max=31.8
5.max=35.0
6.max=38.9
7.max=40.2
8.max=40.4
9.max=37.4
10.max=30,3
11.max=24,0
12.max=19.8
1.min=-36.2
2.min=-42.2
3.min=-32.0
4.min=-22.0
5.min=-13.1
6.min=-8.3
7.min=-6.9
8.min=-5.0
9.min=-10.5
10.min=-19.9
11.min=-25.4
12.min=-34.0
*/

View File

@ -200,6 +200,8 @@ public class ConfigWindow extends TWindow {
= new JCheckBox(TimeCalcProperty.LIFE_VISIBLE.getKey());
public final JTextField lifeTypeProperty
= new JTextField(TimeCalcProperty.LIFE_TYPE.getKey());
public final JTextField lifeBirthDateProperty
= new JTextField(TimeCalcProperty.LIFE_BIRTH_DATE.getKey());
public final JCheckBox moneyVisibleProperty
= new JCheckBox(TimeCalcProperty.MONEY_VISIBLE.getKey());
public final JTextField moneyTypeProperty
@ -208,8 +210,8 @@ public class ConfigWindow extends TWindow {
= new JTextField(TimeCalcProperty.MONEY_PER_MONTH.getKey());
public final JTextField moneyCurrencyProperty
= new JTextField(TimeCalcProperty.MONEY_CURRENCY.getKey());
public final JTextField lifeBirthDateProperty
= new JTextField(TimeCalcProperty.LIFE_BIRTH_DATE.getKey());
public final JCheckBox weatherVisibleProperty
= new JCheckBox(TimeCalcProperty.WEATHER_VISIBLE.getKey());
private final JTextField mainWindowCustomTitleProperty
= new JTextField();
private final JTextField profileNameProperty
@ -386,6 +388,7 @@ public class ConfigWindow extends TWindow {
squareVisibleProperty.setSelected(enable);
lifeVisibleProperty.setSelected(enable);
moneyVisibleProperty.setSelected(enable);
weatherVisibleProperty.setSelected(enable);
circleVisibleProperty.setSelected(enable);
swingVisibleProperty.setSelected(enable);
swingQuarterIconVisibleProperty.setSelected(enable);
@ -460,6 +463,7 @@ public class ConfigWindow extends TWindow {
moneyTypeProperty,
moneyPerMonthProperty,
moneyCurrencyProperty,
weatherVisibleProperty,
mainWindowCustomTitleProperty,
profileNameProperty,
activityNeededFlagsProperty,

View File

@ -37,6 +37,7 @@ import org.nanoboot.utils.timecalc.swing.progress.ProgressLife;
import org.nanoboot.utils.timecalc.swing.progress.ProgressMoney;
import org.nanoboot.utils.timecalc.swing.progress.ProgressSquare;
import org.nanoboot.utils.timecalc.swing.progress.ProgressSwing;
import org.nanoboot.utils.timecalc.swing.progress.ProgressWeather;
import org.nanoboot.utils.timecalc.swing.progress.Time;
import org.nanoboot.utils.timecalc.swing.progress.WalkingHumanProgress;
import org.nanoboot.utils.timecalc.swing.progress.WeekBattery;
@ -102,6 +103,7 @@ public class MainWindow extends TWindow {
private final TButton saveButton;
private final ProgressLife progressLife;
private final ProgressMoney progressMoney;
private final ProgressWeather progressWeather;
private HelpWindow helpWindow = null;
private ConfigWindow configWindow = null;
private ActivitiesWindow activitiesWindow = null;
@ -342,7 +344,7 @@ public class MainWindow extends TWindow {
this.progressMoney
= new ProgressMoney(time);
= new ProgressMoney();
progressMoney.setBounds(progressLife.getX(), progressSwing.getY() + progressLife.getHeight() + SwingUtils.MARGIN,
100, 50);
@ -354,9 +356,17 @@ public class MainWindow extends TWindow {
.bindTo(timeCalcConfiguration.moneyPerMonthProperty);
progressMoney.currencyProperty
.bindTo(timeCalcConfiguration.moneyCurrencyProperty);
add(progressMoney);
this.progressWeather
= new ProgressWeather(time);
progressWeather.setBounds(progressLife.getX() + progressLife.getWidth() + SwingUtils.MARGIN, progressLife.getY(),
100, 100);
progressWeather.visibleProperty
.bindTo(timeCalcConfiguration.weatherVisibleProperty);
add(progressWeather);
TLabel arrivalTextFieldLabel = new TLabel("Arrival:", 70);
arrivalTextFieldLabel.setBoundsFromTop(progressSwing, 3);

View File

@ -15,6 +15,8 @@ public class DateFormats {
= new SimpleDateFormat("HH:mm:ss:SSS", Locale.ENGLISH);
public static DateFormat DATE_TIME_FORMATTER_LONG
= new SimpleDateFormat("yyyy-MM-dd : EEEE", Locale.ENGLISH);
public static DateFormat DATE_TIME_FORMATTER_DAY_OF_WEEK
= new SimpleDateFormat("EEEE", Locale.ENGLISH);
public static DateFormat DATE_TIME_FORMATTER_YYYYMMDD
= new SimpleDateFormat("yyyy-MM-dd");

View File

@ -9,7 +9,6 @@ import java.io.File;
public class FileConstants {
public static final File TC_DIRECTORY = new File(".tc");
public static final File TEST_TXT = new File(TC_DIRECTORY, "test.txt");
public static final File TIME_CALC_PROFILES_TXT_FILE
= new File(TC_DIRECTORY, "time-calc-profiles.txt");
public static final File TIME_CALC_CURRENT_PROFILE_TXT_FILE
@ -18,7 +17,8 @@ public class FileConstants {
= new File(TC_DIRECTORY, "timecalc.conf");
public static final File JOKES_TXT = new File(TC_DIRECTORY, "time-calc-jokes.txt");
public static final File DB_FILE = new File(FileConstants.TC_DIRECTORY.getAbsolutePath() + "/" + "time-calc.sqlite3");
public static final File CLIMATE_TXT = new File(TC_DIRECTORY, "climate.txt");
public static final File WEATHER_TXT = new File(TC_DIRECTORY, "weather.txt");
private FileConstants() {
//Not meant to be instantiated.
}

View File

@ -58,6 +58,7 @@ money.visible=false
money.type=day
money.per-month=0
money.currency=
weather.visible=true
walking-human.visible=true
walking-human.type=day
main-window.custom-title=---