From 06054d6c6258cb24e8c4702638ec9bf51b57a2e2 Mon Sep 17 00:00:00 2001 From: Nikolay Borodin Date: Thu, 13 Jun 2024 17:08:54 +0200 Subject: [PATCH 1/4] Added date picker to InviteWindow --- build.xml | 4 +- ivy.xml | 1 + src/org/p2pvpn/gui/Calendar.java | 77 ++++++++++++++++++++++++++++ src/org/p2pvpn/gui/InviteWindow.form | 57 ++++++++++++-------- src/org/p2pvpn/gui/InviteWindow.java | 57 ++++++++++++++------ 5 files changed, 157 insertions(+), 39 deletions(-) create mode 100644 src/org/p2pvpn/gui/Calendar.java diff --git a/build.xml b/build.xml index 3355f5b..916cecb 100644 --- a/build.xml +++ b/build.xml @@ -26,7 +26,7 @@ - + @@ -110,7 +110,7 @@ - + diff --git a/ivy.xml b/ivy.xml index fee153f..462dde6 100644 --- a/ivy.xml +++ b/ivy.xml @@ -14,5 +14,6 @@ + diff --git a/src/org/p2pvpn/gui/Calendar.java b/src/org/p2pvpn/gui/Calendar.java new file mode 100644 index 0000000..1a898e5 --- /dev/null +++ b/src/org/p2pvpn/gui/Calendar.java @@ -0,0 +1,77 @@ +/* + Copyright 2023-2024 Nikolay Borodin + + This file is part of Lanemu. + + Lanemu is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Lanemu is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Lanemu. If not, see . +*/ +package org.p2pvpn.gui; +import com.github.lgooddatepicker.components.CalendarPanel; +import com.github.lgooddatepicker.zinternaltools.CustomPopup; +import com.github.lgooddatepicker.zinternaltools.CustomPopup.CustomPopupCloseListener; +import java.awt.Component; +import java.awt.Point; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; +import javax.swing.JSpinner; +import javax.swing.SwingUtilities; + +/** + * Calendar widget for the date entry field in InviteWindow. + * Uses internal library methods. + * @author monsterovich + */ +public class Calendar implements CustomPopupCloseListener { + private final CalendarPanel calendarPanel; + private final Component parentComponent; + private final JSpinner inputField; + + public Calendar(Component component, JSpinner field) { + parentComponent = component; + inputField = field; + + calendarPanel = new CalendarPanel(); + } + + void show() { + Date originalDate = (Date) inputField.getModel().getValue(); + calendarPanel.setSelectedDate(LocalDate.ofInstant(originalDate.toInstant(), ZoneId.systemDefault())); + + CustomPopup calendarPopup = + new CustomPopup( + calendarPanel, + SwingUtilities.getWindowAncestor(parentComponent), + this, + null); + + Point pointOnScreen = new Point(); + SwingUtilities.convertPointToScreen(pointOnScreen, parentComponent); + + calendarPopup.setLocation(pointOnScreen.x, pointOnScreen.y + parentComponent.getHeight() + 1); + calendarPopup.show(); + calendarPanel.requestFocus(); + } + + public void zEventCustomPopupWasClosed(CustomPopup popup) { + LocalDate calendarDate = calendarPanel.getSelectedDate(); + if (calendarDate != null) { + Date originalDate = (Date) inputField.getModel().getValue(); + Date date = Date.from(calendarDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + date.setHours(originalDate.getHours()); + date.setMinutes(originalDate.getMinutes()); + inputField.getModel().setValue(date); + } + } +} diff --git a/src/org/p2pvpn/gui/InviteWindow.form b/src/org/p2pvpn/gui/InviteWindow.form index abef7ff..8a9058f 100644 --- a/src/org/p2pvpn/gui/InviteWindow.form +++ b/src/org/p2pvpn/gui/InviteWindow.form @@ -31,29 +31,35 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -73,7 +79,10 @@ - + + + + @@ -204,5 +213,13 @@ + + + + + + + + diff --git a/src/org/p2pvpn/gui/InviteWindow.java b/src/org/p2pvpn/gui/InviteWindow.java index 4aa2cde..3174b38 100644 --- a/src/org/p2pvpn/gui/InviteWindow.java +++ b/src/org/p2pvpn/gui/InviteWindow.java @@ -1,6 +1,6 @@ /* Copyright 2008, 2009 Wolfgang Ginolas - Copyright 2023 Nikolay Borodin + Copyright 2023-2024 Nikolay Borodin This file is part of Lanemu. @@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with Lanemu. If not, see . - */ +*/ package org.p2pvpn.gui; import java.awt.Toolkit; @@ -39,6 +39,7 @@ import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import org.p2pvpn.tools.AdvProperties; +import org.p2pvpn.gui.Calendar; /** * This window is shown, when the user wants to invite another persion. @@ -49,6 +50,8 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner MainControl mainControl; JFileChooser fileChooser; + Calendar calendar; + /** * Creates new form InviteWindow @@ -77,6 +80,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner }); menu.add(mitem); txtInvitation.setComponentPopupMenu(menu); + calendar = new Calendar(btnCalendar, spnExpiryDate); } /** @@ -110,6 +114,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner lblNote = new javax.swing.JLabel(); radNever = new javax.swing.JRadioButton(); radDate = new javax.swing.JRadioButton(); + btnCalendar = new javax.swing.JButton(); setTitle("Generate Invitation"); @@ -177,6 +182,13 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner grpDate.add(radDate); + btnCalendar.setText("..."); + btnCalendar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCalendarActionPerformed(evt); + } + }); + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -185,24 +197,28 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() - .add(0, 338, Short.MAX_VALUE) - .add(btnClose)) .add(layout.createSequentialGroup() - .add(lblDate) - .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() - .add(radDate) + .add(lblDate) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) - .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 251, Short.MAX_VALUE)) - .add(radNever))) - .add(layout.createSequentialGroup() - .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(chkNetwork) - .add(lblNote) - .add(btnGenerate)) - .add(0, 0, Short.MAX_VALUE))) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(radDate) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 262, Short.MAX_VALUE)) + .add(radNever))) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(chkNetwork) + .add(lblNote) + .add(btnGenerate)) + .add(0, 0, Short.MAX_VALUE))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(btnCalendar)) + .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() + .add(0, 0, Short.MAX_VALUE) + .add(btnClose))) .addContainerGap()) ); layout.setVerticalGroup( @@ -217,7 +233,9 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(radDate) - .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(spnExpiryDate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(btnCalendar))) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(lblNote) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) @@ -232,6 +250,10 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner pack(); }// //GEN-END:initComponents + private void btnCalendarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCalendarActionPerformed + calendar.show(); + }//GEN-LAST:event_btnCalendarActionPerformed + private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_btnCloseActionPerformed setVisible(false); }// GEN-LAST:event_btnCloseActionPerformed @@ -293,6 +315,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCalendar; private javax.swing.JButton btnClose; private javax.swing.JButton btnGenerate; private javax.swing.JButton btnSave; From f9cb334002d704927fca9fa5ca35c81ba8f2343f Mon Sep 17 00:00:00 2001 From: Nikolay Borodin Date: Thu, 13 Jun 2024 17:14:16 +0200 Subject: [PATCH 2/4] Fixed unknown symbol --- src/org/p2pvpn/gui/Calendar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/p2pvpn/gui/Calendar.java b/src/org/p2pvpn/gui/Calendar.java index 1a898e5..84e1c39 100644 --- a/src/org/p2pvpn/gui/Calendar.java +++ b/src/org/p2pvpn/gui/Calendar.java @@ -47,7 +47,7 @@ public class Calendar implements CustomPopupCloseListener { void show() { Date originalDate = (Date) inputField.getModel().getValue(); - calendarPanel.setSelectedDate(LocalDate.ofInstant(originalDate.toInstant(), ZoneId.systemDefault())); + calendarPanel.setSelectedDate(originalDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); CustomPopup calendarPopup = new CustomPopup( From b72bddee1c1b2b31eb3f52ba152f27fa69c9a264 Mon Sep 17 00:00:00 2001 From: Nikolay Borodin Date: Thu, 13 Jun 2024 18:18:37 +0200 Subject: [PATCH 3/4] Improved calendar --- src/org/p2pvpn/gui/Calendar.java | 23 ++++++++++++++++------- src/org/p2pvpn/gui/InviteWindow.form | 1 + src/org/p2pvpn/gui/InviteWindow.java | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/org/p2pvpn/gui/Calendar.java b/src/org/p2pvpn/gui/Calendar.java index 84e1c39..d58e766 100644 --- a/src/org/p2pvpn/gui/Calendar.java +++ b/src/org/p2pvpn/gui/Calendar.java @@ -19,7 +19,9 @@ package org.p2pvpn.gui; import com.github.lgooddatepicker.components.CalendarPanel; import com.github.lgooddatepicker.zinternaltools.CustomPopup; -import com.github.lgooddatepicker.zinternaltools.CustomPopup.CustomPopupCloseListener; +import com.github.lgooddatepicker.zinternaltools.CalendarSelectionEvent; +import com.github.lgooddatepicker.zinternaltools.YearMonthChangeEvent; +import com.github.lgooddatepicker.optionalusertools.CalendarListener; import java.awt.Component; import java.awt.Point; import java.time.LocalDate; @@ -33,8 +35,9 @@ import javax.swing.SwingUtilities; * Uses internal library methods. * @author monsterovich */ -public class Calendar implements CustomPopupCloseListener { +public class Calendar implements CalendarListener { private final CalendarPanel calendarPanel; + private CustomPopup calendarPopup; private final Component parentComponent; private final JSpinner inputField; @@ -43,17 +46,18 @@ public class Calendar implements CustomPopupCloseListener { inputField = field; calendarPanel = new CalendarPanel(); + calendarPanel.addCalendarListener(this); } void show() { Date originalDate = (Date) inputField.getModel().getValue(); calendarPanel.setSelectedDate(originalDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); - CustomPopup calendarPopup = + calendarPopup = new CustomPopup( calendarPanel, SwingUtilities.getWindowAncestor(parentComponent), - this, + null, null); Point pointOnScreen = new Point(); @@ -64,14 +68,19 @@ public class Calendar implements CustomPopupCloseListener { calendarPanel.requestFocus(); } - public void zEventCustomPopupWasClosed(CustomPopup popup) { - LocalDate calendarDate = calendarPanel.getSelectedDate(); - if (calendarDate != null) { + public void selectedDateChanged(CalendarSelectionEvent event) { + LocalDate calendarDate = event.getSource().getSelectedDate(); + if (calendarDate != null && event.getNewDate().equals(event.getOldDate())) { Date originalDate = (Date) inputField.getModel().getValue(); Date date = Date.from(calendarDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); date.setHours(originalDate.getHours()); date.setMinutes(originalDate.getMinutes()); inputField.getModel().setValue(date); + calendarPopup.hide(); } } + + public void yearMonthChanged(YearMonthChangeEvent event) { + + } } diff --git a/src/org/p2pvpn/gui/InviteWindow.form b/src/org/p2pvpn/gui/InviteWindow.form index 8a9058f..a4505be 100644 --- a/src/org/p2pvpn/gui/InviteWindow.form +++ b/src/org/p2pvpn/gui/InviteWindow.form @@ -216,6 +216,7 @@ + diff --git a/src/org/p2pvpn/gui/InviteWindow.java b/src/org/p2pvpn/gui/InviteWindow.java index 3174b38..c1e4f69 100644 --- a/src/org/p2pvpn/gui/InviteWindow.java +++ b/src/org/p2pvpn/gui/InviteWindow.java @@ -183,6 +183,7 @@ public class InviteWindow extends javax.swing.JDialog implements ClipboardOwner grpDate.add(radDate); btnCalendar.setText("..."); + btnCalendar.setToolTipText("Open calendar"); btnCalendar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnCalendarActionPerformed(evt); From f706cbb6d8fa5388db2135d050d7a0a0916fb711 Mon Sep 17 00:00:00 2001 From: Nikolay Borodin Date: Thu, 13 Jun 2024 18:19:46 +0200 Subject: [PATCH 4/4] Code refactoring --- src/org/p2pvpn/gui/Calendar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/p2pvpn/gui/Calendar.java b/src/org/p2pvpn/gui/Calendar.java index d58e766..69f01c4 100644 --- a/src/org/p2pvpn/gui/Calendar.java +++ b/src/org/p2pvpn/gui/Calendar.java @@ -70,7 +70,7 @@ public class Calendar implements CalendarListener { public void selectedDateChanged(CalendarSelectionEvent event) { LocalDate calendarDate = event.getSource().getSelectedDate(); - if (calendarDate != null && event.getNewDate().equals(event.getOldDate())) { + if (calendarDate != null && event.isDuplicate()) { Date originalDate = (Date) inputField.getModel().getValue(); Date date = Date.from(calendarDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); date.setHours(originalDate.getHours());