Initial commit.

This commit is contained in:
2026-02-27 12:07:00 +01:00
commit 3f7a52f16e
6 changed files with 310 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

17
LICENSE Normal file
View File

@@ -0,0 +1,17 @@
Copyright (C) 2026 Nicolás A. Ortega Froysa <nicolas@ortegas.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

39
README.md Normal file
View File

@@ -0,0 +1,39 @@
# VacCalc
## Building
### Prerequisites
- Java 11 or higher
- Maven 3.6 or higher
### Compile
```bash
mvn clean compile
```
### Package
```bash
mvn package
```
### Run
Using Maven:
```bash
mvn exec:java@com.calendar.CalendarApp
```
Using Java directly:
```bash
java -jar target/vaccalc-1.0.0.jar
```
## License
This project is licensed under the Zlib license. See the [license](LICENSE)
file for more information.

66
pom.xml Normal file
View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>com.calendar</groupId>
<artifactId>vaccalc</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>VacCalc</name>
<description>Vacation Calculator - A calendar app to calculate vacation days in a point-based system.</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>net.themusicinnoise.vaccalc.VacCalc</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>net.themusicinnoise.vaccalc.VacCalc</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,106 @@
package net.themusicinnoise.vaccalc;
import javax.swing.*;
import java.awt.*;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.DayOfWeek;
public class CalendarPanel extends JPanel {
private YearMonth currentMonth;
private final int cellHeight = 60;
private final int cellWidth = 80;
public CalendarPanel() {
this.currentMonth = YearMonth.now();
setPreferredSize(new Dimension(7 * cellWidth, 8 * cellHeight));
setBackground(Color.WHITE);
}
public void previousMonth() {
currentMonth = currentMonth.minusMonths(1);
repaint();
}
public void nextMonth() {
currentMonth = currentMonth.plusMonths(1);
repaint();
}
public YearMonth getCurrentMonth() {
return currentMonth;
}
public void setCurrentMonth(YearMonth month) {
currentMonth = month;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawDayHeaders(g2);
drawDays(g2);
}
private void drawDayHeaders(Graphics2D g) {
String[] dayNames = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
g.setColor(new Color(70, 130, 180));
g.fillRect(0, 0, 7 * cellWidth, cellHeight);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 14));
FontMetrics fm = g.getFontMetrics();
for (int i = 0; i < 7; i++) {
String day = dayNames[i];
int x = i * cellWidth;
int textX = x + (cellWidth - fm.stringWidth(day)) / 2;
int textY = (cellHeight - fm.getHeight()) / 2 + fm.getAscent();
g.drawString(day, textX, textY);
}
}
private void drawDays(Graphics2D g) {
LocalDate firstDay = currentMonth.atDay(1);
int firstDayOfWeek = firstDay.getDayOfWeek().getValue() % 7;
int daysInMonth = currentMonth.lengthOfMonth();
LocalDate today = LocalDate.now();
g.setFont(new Font("Arial", Font.PLAIN, 14));
FontMetrics fm = g.getFontMetrics();
int row = 1;
int col = firstDayOfWeek;
for (int day = 1; day <= daysInMonth; day++) {
int x = col * cellWidth;
int y = row * cellHeight;
LocalDate cellDate = currentMonth.atDay(day);
boolean isToday = cellDate.equals(today);
if (isToday) {
g.setColor(new Color(255, 200, 100));
g.fillRect(x, y, cellWidth, cellHeight);
}
g.setColor(Color.BLACK);
g.drawRect(x, y, cellWidth, cellHeight);
String dayStr = String.valueOf(day);
int textX = x + (cellWidth - fm.stringWidth(dayStr)) / 2;
int textY = y + (cellHeight - fm.getHeight()) / 2 + fm.getAscent();
g.drawString(dayStr, textX, textY);
col++;
if (col == 7) {
col = 0;
row++;
}
}
}
}

View File

@@ -0,0 +1,81 @@
package net.themusicinnoise.vaccalc;
import javax.swing.*;
import java.awt.*;
import java.time.YearMonth;
public class VacCalc extends JFrame {
private CalendarPanel calendarPanel;
private JLabel monthLabel;
public VacCalc() {
setTitle("VacCalc");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
calendarPanel = new CalendarPanel();
JPanel headerPanel = createHeaderPanel();
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(headerPanel, BorderLayout.NORTH);
mainPanel.add(calendarPanel, BorderLayout.CENTER);
add(mainPanel);
pack();
}
private JPanel createHeaderPanel() {
JPanel headerPanel = new JPanel(new BorderLayout());
headerPanel.setBackground(new Color(230, 230, 230));
headerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
monthLabel = new JLabel();
monthLabel.setFont(new Font("Arial", Font.BOLD, 18));
monthLabel.setHorizontalAlignment(JLabel.CENTER);
JButton prevButton = new JButton("< Previous");
prevButton.addActionListener(e -> {
calendarPanel.previousMonth();
updateMonthLabel();
});
JButton nextButton = new JButton("Next >");
nextButton.addActionListener(e -> {
calendarPanel.nextMonth();
updateMonthLabel();
});
JButton todayButton = new JButton("Today");
todayButton.addActionListener(e -> {
calendarPanel.setCurrentMonth(YearMonth.now());
updateMonthLabel();
});
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
buttonPanel.setBackground(new Color(230, 230, 230));
buttonPanel.add(prevButton);
buttonPanel.add(todayButton);
buttonPanel.add(nextButton);
headerPanel.add(monthLabel, BorderLayout.CENTER);
headerPanel.add(buttonPanel, BorderLayout.SOUTH);
updateMonthLabel();
return headerPanel;
}
private void updateMonthLabel() {
YearMonth current = calendarPanel.getCurrentMonth();
monthLabel.setText(String.format("%s %d",
current.getMonth().toString(),
current.getYear()));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
VacCalc app = new VacCalc();
app.setVisible(true);
});
}
}