From 3f7a52f16ef5d231b6727ce44ca21ae52f335564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ortega=20Froysa?= Date: Fri, 27 Feb 2026 12:07:00 +0100 Subject: [PATCH] Initial commit. --- .gitignore | 1 + LICENSE | 17 +++ README.md | 39 +++++++ pom.xml | 66 +++++++++++ .../vaccalc/CalendarPanel.java | 106 ++++++++++++++++++ .../net/themusicinnoise/vaccalc/VacCalc.java | 81 +++++++++++++ 6 files changed, 310 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/net/themusicinnoise/vaccalc/CalendarPanel.java create mode 100644 src/main/java/net/themusicinnoise/vaccalc/VacCalc.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1f69cc4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,17 @@ +Copyright (C) 2026 Nicolás A. Ortega Froysa + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3daeffc --- /dev/null +++ b/README.md @@ -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. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e357671 --- /dev/null +++ b/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.calendar + vaccalc + 1.0.0 + jar + + VacCalc + Vacation Calculator - A calendar app to calculate vacation days in a point-based system. + + + 11 + 11 + UTF-8 + + + + + junit + junit + 4.13.2 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + net.themusicinnoise.vaccalc.VacCalc + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + net.themusicinnoise.vaccalc.VacCalc + + + + + diff --git a/src/main/java/net/themusicinnoise/vaccalc/CalendarPanel.java b/src/main/java/net/themusicinnoise/vaccalc/CalendarPanel.java new file mode 100644 index 0000000..82da867 --- /dev/null +++ b/src/main/java/net/themusicinnoise/vaccalc/CalendarPanel.java @@ -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++; + } + } + } +} diff --git a/src/main/java/net/themusicinnoise/vaccalc/VacCalc.java b/src/main/java/net/themusicinnoise/vaccalc/VacCalc.java new file mode 100644 index 0000000..9537142 --- /dev/null +++ b/src/main/java/net/themusicinnoise/vaccalc/VacCalc.java @@ -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); + }); + } +}