Skip to content

Commit ae5c102

Browse files
author
edu
committed
feat: Implementación de sistema centralizado de metadata en app.properties para facilitar rebranding
- Se creó un archivo `app.properties` que centraliza la metadata de la aplicación, incluyendo nombre, versión, iconos y categorías por plataforma. - Se implementó la clase `AppConfig` para acceder a la metadata de manera estática y con valores por defecto. - Se actualizaron las referencias en `Main` y `AppDataDirectory` para utilizar la metadata desde `app.properties`, eliminando constantes hardcodeadas. - Se modificaron los scripts de empaquetado para leer la metadata y usar iconos según la configuración. - Se añadió una carpeta para iconos y un README con instrucciones sobre cómo cambiar el nombre y el icono de la aplicación. Fixes: mejora en la gestión de metadata y simplificación del proceso de rebranding.
1 parent 6e1e56b commit ae5c102

File tree

16 files changed

+425
-59
lines changed

16 files changed

+425
-59
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.example.forevernote;
2+
3+
import java.io.InputStream;
4+
import java.util.Properties;
5+
import java.util.logging.Logger;
6+
7+
/**
8+
* Centralized application configuration.
9+
* Reads metadata from app.properties file.
10+
*
11+
* This allows easy rebranding by modifying a single properties file.
12+
*/
13+
public class AppConfig {
14+
15+
private static final Logger logger = Logger.getLogger(AppConfig.class.getName());
16+
private static Properties properties = null;
17+
18+
static {
19+
loadProperties();
20+
}
21+
22+
/**
23+
* Loads application properties from app.properties file.
24+
*/
25+
private static void loadProperties() {
26+
properties = new Properties();
27+
try (InputStream input = AppConfig.class.getClassLoader()
28+
.getResourceAsStream("app.properties")) {
29+
30+
if (input == null) {
31+
logger.warning("app.properties not found, using defaults");
32+
// Set defaults
33+
properties.setProperty("app.name", "Forevernote");
34+
properties.setProperty("app.version", "1.0.0");
35+
properties.setProperty("app.vendor", "Forevernote");
36+
properties.setProperty("app.description", "A free and open-source note-taking application");
37+
properties.setProperty("app.copyright", "Copyright 2025 Forevernote");
38+
properties.setProperty("app.window.title", "Forevernote - Free Note Taking");
39+
return;
40+
}
41+
42+
properties.load(input);
43+
logger.info("Application properties loaded successfully");
44+
} catch (Exception e) {
45+
logger.warning("Failed to load app.properties: " + e.getMessage() + ", using defaults");
46+
// Set defaults on error
47+
properties.setProperty("app.name", "Forevernote");
48+
properties.setProperty("app.version", "1.0.0");
49+
properties.setProperty("app.vendor", "Forevernote");
50+
properties.setProperty("app.description", "A free and open-source note-taking application");
51+
properties.setProperty("app.copyright", "Copyright 2025 Forevernote");
52+
properties.setProperty("app.window.title", "Forevernote - Free Note Taking");
53+
}
54+
}
55+
56+
/**
57+
* Gets a property value, with optional default.
58+
*/
59+
private static String getProperty(String key, String defaultValue) {
60+
return properties.getProperty(key, defaultValue);
61+
}
62+
63+
// Application metadata
64+
public static String getAppName() {
65+
return getProperty("app.name", "Forevernote");
66+
}
67+
68+
public static String getAppVersion() {
69+
return getProperty("app.version", "1.0.0");
70+
}
71+
72+
public static String getAppVendor() {
73+
return getProperty("app.vendor", "Forevernote");
74+
}
75+
76+
public static String getAppDescription() {
77+
return getProperty("app.description", "A free and open-source note-taking application");
78+
}
79+
80+
public static String getAppCopyright() {
81+
return getProperty("app.copyright", "Copyright 2025 Forevernote");
82+
}
83+
84+
public static String getWindowTitle() {
85+
return getProperty("app.window.title", "Forevernote - Free Note Taking");
86+
}
87+
88+
// Window icon path (for JavaFX, relative to resources root, e.g., "com/example/forevernote/ui/images/app-icon.png")
89+
public static String getWindowIconPath() {
90+
return getProperty("app.icon.window", "com/example/forevernote/ui/images/app-icon.png");
91+
}
92+
93+
// Packaging icon paths (relative to project root)
94+
public static String getIconPathWindows() {
95+
return getProperty("app.icon.windows", "src/main/resources/icons/app-icon.ico");
96+
}
97+
98+
public static String getIconPathMacOS() {
99+
return getProperty("app.icon.macos", "src/main/resources/icons/app-icon.icns");
100+
}
101+
102+
public static String getIconPathLinux() {
103+
return getProperty("app.icon.linux", "src/main/resources/icons/app-icon.png");
104+
}
105+
106+
// Package information
107+
public static String getPackageName() {
108+
return getProperty("app.package.name", "forevernote");
109+
}
110+
111+
public static String getPackageCategoryWindows() {
112+
return getProperty("app.package.category.windows", "Productivity");
113+
}
114+
115+
public static String getPackageCategoryMacOS() {
116+
return getProperty("app.package.category.macos", "public.app-category.productivity");
117+
}
118+
119+
public static String getPackageCategoryLinux() {
120+
return getProperty("app.package.category.linux", "Office");
121+
}
122+
}
123+

Forevernote/src/main/java/com/example/forevernote/AppDataDirectory.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
*/
1717
public class AppDataDirectory {
1818

19-
private static final String APP_NAME = "Forevernote";
2019
private static String baseDir = null;
2120

2221
/**
@@ -69,24 +68,26 @@ private static String getPlatformAppDataDirectory() {
6968
String home = System.getProperty("user.home");
7069
File appDataDir;
7170

71+
String appName = AppConfig.getAppName();
72+
7273
if (osName.contains("win")) {
73-
// Windows: %APPDATA%\Forevernote
74+
// Windows: %APPDATA%\AppName
7475
String appData = System.getenv("APPDATA");
7576
if (appData != null && !appData.isEmpty()) {
76-
appDataDir = new File(appData, APP_NAME);
77+
appDataDir = new File(appData, appName);
7778
} else {
78-
appDataDir = new File(home, "AppData\\Roaming\\" + APP_NAME);
79+
appDataDir = new File(home, "AppData\\Roaming\\" + appName);
7980
}
8081
} else if (osName.contains("mac")) {
81-
// macOS: ~/Library/Application Support/Forevernote
82-
appDataDir = new File(home, "Library/Application Support/" + APP_NAME);
82+
// macOS: ~/Library/Application Support/AppName
83+
appDataDir = new File(home, "Library/Application Support/" + appName);
8384
} else {
84-
// Linux: ~/.config/Forevernote (XDG Base Directory)
85+
// Linux: ~/.config/AppName (XDG Base Directory)
8586
String xdgConfig = System.getenv("XDG_CONFIG_HOME");
8687
if (xdgConfig != null && !xdgConfig.isEmpty()) {
87-
appDataDir = new File(xdgConfig, APP_NAME);
88+
appDataDir = new File(xdgConfig, appName);
8889
} else {
89-
appDataDir = new File(home, ".config/" + APP_NAME);
90+
appDataDir = new File(home, ".config/" + appName);
9091
}
9192
}
9293

Forevernote/src/main/java/com/example/forevernote/Main.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ public void start(Stage primaryStage) {
4343
scene.getStylesheets().add(cssResource.toExternalForm());
4444
}
4545

46-
primaryStage.setTitle("Forevernote - Free Note Taking");
46+
primaryStage.setTitle(AppConfig.getWindowTitle());
4747

48+
// Load window icon from app.properties
4849
try {
49-
var iconStream = getClass().getResourceAsStream(
50-
"/com/example/forevernote/ui/images/app-icon.png");
50+
String iconPath = "/" + AppConfig.getWindowIconPath();
51+
var iconStream = getClass().getResourceAsStream(iconPath);
5152
if (iconStream != null) {
5253
primaryStage.getIcons().add(new Image(iconStream));
5354
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Application Metadata
2+
# This file centralizes all application metadata for easy customization
3+
# Modify these values to rebrand the application
4+
5+
# Application Information
6+
app.name=Forevernote
7+
app.version=1.0.0
8+
app.vendor=Forevernote
9+
app.description=A free and open-source note-taking application
10+
app.copyright=Copyright 2025 Forevernote
11+
12+
# Application Window Title
13+
app.window.title=Forevernote - Free Note Taking
14+
15+
# Icon Paths
16+
# Window icon (for JavaFX window, PNG format, relative to resources root)
17+
app.icon.window=com/example/forevernote/ui/images/app-icon.png
18+
19+
# Packaging icons (relative to project root)
20+
# All icon formats are ready: icon.ico (Windows), icon.icns (macOS), icon.png (Linux)
21+
app.icon.windows=src/main/resources/icons/icon.ico
22+
app.icon.macos=src/main/resources/icons/icon.icns
23+
app.icon.linux=src/main/resources/icons/icon.png
24+
25+
# Package Information
26+
app.package.name=forevernote
27+
app.package.category.windows=Productivity
28+
app.package.category.macos=public.app-category.productivity
29+
app.package.category.linux=Office
30+
223 KB
Loading
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Application Icons
2+
3+
Place your application icons here in the following formats:
4+
5+
- **Windows**: `app-icon.ico` (multiple sizes: 16x16, 32x32, 48x48, 256x256)
6+
- **macOS**: `app-icon.icns` (Apple icon format)
7+
- **Linux**: `app-icon.png` (128x128 or 256x256 recommended)
8+
9+
## Icon Requirements
10+
11+
### Windows (.ico)
12+
- Format: ICO file with multiple embedded sizes
13+
- Recommended sizes: 16x16, 32x32, 48x48, 256x256
14+
- Tools: Use online converters or tools like GIMP, ImageMagick
15+
16+
### macOS (.icns)
17+
- Format: ICNS (Apple Icon Image format)
18+
- Recommended sizes: 16x16, 32x32, 128x128, 256x256, 512x512, 1024x1024
19+
- Tools: Use `iconutil` on macOS or online converters
20+
21+
### Linux (.png)
22+
- Format: PNG with transparency
23+
- Recommended size: 128x128 or 256x256
24+
- Tools: Any image editor (GIMP, Photoshop, etc.)
25+
26+
## Configuration
27+
28+
Icon paths are configured in `src/main/resources/app.properties`:
29+
- `app.icon.windows=src/main/resources/icons/app-icon.ico`
30+
- `app.icon.macos=src/main/resources/icons/app-icon.icns`
31+
- `app.icon.linux=src/main/resources/icons/app-icon.png`
32+
33+
If icons are not found, the packaging scripts will skip the `--icon` parameter (application will still work, just without custom icon).
34+
223 KB
Loading
230 KB
Binary file not shown.
229 KB
Binary file not shown.
223 KB
Loading

0 commit comments

Comments
 (0)