diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java index 7ef2650..458d655 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java @@ -99,13 +99,16 @@ public class TimeCalcApp { } Utils.writeTextToFile(FileConstants.STARTTIME_TXT, newStartTime); Utils.writeTextToFile(FileConstants.OVERTIME_TXT, newOvertime); + MainWindow timeCalcMainWindow = null; try { - MainWindow timeCalc + timeCalcMainWindow = new MainWindow(newStartTime, newOvertime, this); } catch (Exception e) { JOptionPane.showMessageDialog(null, "Error: " + e.getMessage(), e.getMessage(), JOptionPane.ERROR_MESSAGE); e.printStackTrace(); + timeCalcMainWindow.setVisible(false); + timeCalcMainWindow.dispose(); } } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/ActivityRepositoryApi.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/ActivityRepositoryApi.java index 2551490..c4cea41 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/ActivityRepositoryApi.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/ActivityRepositoryApi.java @@ -22,12 +22,16 @@ public interface ActivityRepositoryApi { void delete(String id); - public List getYears(); + List getYears(); - public void putToClipboard(Activity activity); + void putToClipboard(Activity activity); - public Activity getFromClipboard(); + Activity getFromClipboard(); - public int getNextSortkey(int year, int month, int day); + default int getSortkeySpace() { + return 1000; + } + + int getNextSortkey(int year, int month, int day); } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java index 1ffe0ea..b22dcd7 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java @@ -9,7 +9,6 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Types; import java.util.ArrayList; import java.util.List; import java.util.OptionalInt; @@ -353,18 +352,26 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi { OptionalInt optional = list(year, month, day).stream().map(Activity::getSortkey) .mapToInt(e -> e).max(); + int sortkeySpace = getSortkeySpace(); if (optional.isPresent()) { System.out.println("getLargestSortkey=" +optional.getAsInt()); - int result = optional.getAsInt() + 10; - if(result % 10 != 0) { - while(result % 10 != 0) { + + if(optional.getAsInt() >= (Integer.MAX_VALUE - sortkeySpace - 1)) { + throw new TimeCalcException("Fatal exception. Cannot get new sort key, because it would exceed the Integer max value."); + } + int result = optional.getAsInt() + sortkeySpace; + if(result % sortkeySpace != 0) { + while(result % sortkeySpace != 0) { result++; } } return result; } else { - return 10; + return sortkeySpace; } } + public int getSortkeySpace() { + return 1000; + } } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java index bcdb0c2..8478278 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java @@ -98,6 +98,7 @@ public class ActivitiesWindow extends TWindow { YearPanel yearPanel = years.get(sourceTabbedPane.getTitleAt(index)); + yearPanel.load(); MonthPanel monthPanel = yearPanel.getMonthPanel("1"); monthPanel.load(); monthPanel.getDayPanel("1").load(); @@ -105,8 +106,13 @@ public class ActivitiesWindow extends TWindow { }; tp.addChangeListener(changeListener); tp.switchTo(currentYearS); - getYearPanel(currentYearS).setSelectedMonth(currentMonthS); - getYearPanel(currentYearS).getMonthPanel(currentMonthS).setSelectedDay(currentDayS); + YearPanel yearPanel = getYearPanel(currentYearS); + yearPanel.load(); + yearPanel.setSelectedMonth(currentMonthS); + MonthPanel monthPanel = yearPanel.getMonthPanel(currentMonthS); + monthPanel.load(); + monthPanel.setSelectedDay(currentDayS); + monthPanel.getDayPanel(currentDayS).load(); } public YearPanel getYearPanel(String year) { diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java index 63bec21..0c2d553 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java @@ -221,11 +221,13 @@ public class ActivityPanel extends JPanel implements Comparable { moveButton.addActionListener(e-> { this.dayPanel.markActivityPanelToBeMoved(this); }); - dayPanel.sortActivityPanels(); } @Override public int compareTo(ActivityPanel o) { return this.getActivity().compareTo(o.getActivity()); } + public TTextField getSortkeyTTextField() { + return sortkey; + } } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java index beaa08f..c13d0f5 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java @@ -11,7 +11,6 @@ import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; -import javax.swing.Timer; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; @@ -33,6 +32,9 @@ import java.util.stream.Collectors; */ public class DayPanel extends JPanel { + private static final String FOR_ACTIVITY_ID = "for-activity-id"; + private static final Dimension MAXIMUM_SIZE = new Dimension(1300, 40); + private static final Dimension MAXIMUM_SIZE_2 = new Dimension(1200, 20); private final String year; private final String month; private final String day; @@ -44,6 +46,64 @@ public class DayPanel extends JPanel { private JPanel panelInsideScrollPane; private ActivityPanel markActivityPanelToBeMoved = null; + class MoveHereButton extends JButton { + public MoveHereButton(String activityId) { + setText("Move here"); + setMaximumSize(MAXIMUM_SIZE_2); + putClientProperty(FOR_ACTIVITY_ID, activityId); + setVisible(true); + addActionListener(e-> { + List list = getActivities(); + Activity activityToBeMoved = activityRepository.read(markActivityPanelToBeMoved.getActivity().getId()); + Activity activityTarget = activityRepository.read(activityId); + int activityTargetSortkey = activityTarget.getSortkey(); + int newSortKey = activityToBeMoved.getSortkey(); + for(int i = 0; i < list.size(); i++) { + if(activityToBeMoved.getSortkey() == activityTarget.getSortkey()) { + //nothing to do + break; + } + if(i >= 1 && activityToBeMoved.getSortkey() == activityTarget.getSortkey()) { + //nothing to do + break; + } + if(list.get(i).getId().equals(activityTarget.getId())) { + Activity activityBefore = i == 0 ? null : list.get(i - 1); + int activityBeforeSortkey = activityBefore == null ? activityTargetSortkey : activityBefore.getSortkey(); + int start = activityBeforeSortkey + 1; + int end = activityTargetSortkey - 1; + if(start > end) { + start = end; + } + if(start == end) { + newSortKey = end; + break; + } + newSortKey = start + (end - start) / 2; + if(newSortKey > activityTargetSortkey) { + newSortKey = activityTargetSortkey; + } + break; + } + + } + activityToBeMoved.setSortkey(newSortKey); + ActivityPanel activityPanelForActivity = + getActivityPanelForActivity(activityToBeMoved); + activityPanelForActivity.getActivity().setSortkey(newSortKey); + activityPanelForActivity.getSortkeyTTextField().setText( + String.valueOf(newSortKey)); + activityRepository.update(activityToBeMoved); + sortActivityPanels(); + + + }); + } + public String getActivityId() { + return (String) getClientProperty(FOR_ACTIVITY_ID); + } + } + public DayPanel(String yearIn, String monthIn, String dayIn, ActivityRepositoryApi activityRepository) { super(); @@ -82,7 +142,7 @@ public class DayPanel extends JPanel { this.setLayout(boxLayout); JPanel buttons = new JPanel(); - //buttons.setBorder(BorderFactory.createLineBorder(Color.BLUE, 1)); + buttons.setLayout(new FlowLayout(FlowLayout.LEFT)); buttons.setAlignmentX(LEFT_ALIGNMENT); JButton newButton = new JButton("New"); @@ -107,39 +167,34 @@ public class DayPanel extends JPanel { panelInsideScrollPane.add(activityHeader); activityHeader.setMaximumSize(new Dimension(1200, 40)); - buttons.setMaximumSize(new Dimension(1000, 40)); - for (Activity a : activityRepository.list( + List list = activityRepository.list( Integer.valueOf(year), Integer.valueOf(month), - Integer.valueOf(day))) { - + Integer.valueOf(day)); + Collections.sort(list); + for (Activity a : list) { ActivityPanel comp = new ActivityPanel(activityRepository, a, this); - comp.setMaximumSize(new Dimension(1300, 40)); + comp.setMaximumSize(MAXIMUM_SIZE); + panelInsideScrollPane.add(comp); } - new Timer(100, e -> { - List - list = Arrays.stream(panelInsideScrollPane.getComponents()).filter(c-> c instanceof ActivityPanel).filter(c-> ((ActivityPanel)c).isDeleted()).collect( - Collectors.toList()); - if(!list.isEmpty()) { - list.forEach(c->panelInsideScrollPane.remove(c)); - sortActivityPanels(); - } - revalidate(); - }).start(); revalidate(); newButton.addActionListener(e-> { Activity newActivity = new Activity(UUID.randomUUID().toString(), Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day), "", "", "", 0, 0, "", activityRepository.getNextSortkey(Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day))); ActivityPanel comp = new ActivityPanel(activityRepository, newActivity, this); - comp.setMaximumSize(new Dimension(1200, 40)); + comp.setMaximumSize(new Dimension(1300, 40)); add(comp); activityRepository.create(newActivity); - + if(this.markActivityPanelToBeMoved != null) { + panelInsideScrollPane.add(new MoveHereButton(newActivity.getId())); + } else { + //comp.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0)); + } panelInsideScrollPane.add(comp); revalidate(); @@ -157,7 +212,11 @@ public class DayPanel extends JPanel { comp.setMaximumSize(new Dimension(1200, 40)); add(comp); activityRepository.create(newActivity); - + if(this.markActivityPanelToBeMoved != null) { + panelInsideScrollPane.add(new MoveHereButton(newActivity.getId())); + } else { + //comp.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0)); + } panelInsideScrollPane.add(comp); revalidate(); @@ -222,7 +281,7 @@ public class DayPanel extends JPanel { Optional optional = Arrays .stream(panelInsideScrollPane.getComponents()) .filter(c-> c instanceof ActivityPanel) - .filter(c-> ((ActivityPanel) c).getActivity().equals(a)) + .filter(c-> ((ActivityPanel) c).getActivity().getId().equals(a.getId())) .findFirst(); if(optional.isPresent()) { return (ActivityPanel) optional.get(); @@ -231,16 +290,45 @@ public class DayPanel extends JPanel { } } public void sortActivityPanels() { + System.out.println("sortActivityPanels()"); List list = new ArrayList<>(); Arrays .stream(panelInsideScrollPane.getComponents()) - .filter(c-> c instanceof ActivityPanel).forEach(e-> list.add((ActivityPanel) e)); + .filter(c-> c instanceof ActivityPanel).filter(c-> !((ActivityPanel)c).isDeleted()).forEach(e-> list.add((ActivityPanel) e)); Collections.sort(list); + Arrays + .stream(panelInsideScrollPane.getComponents()) + .filter(c-> {return (c instanceof MoveHereButton);}).forEach(c-> panelInsideScrollPane.remove(c)); + + //.filter(c -> getClientProperty( FOR_ACTIVITY_ID) != null) for(ActivityPanel ap:list) { panelInsideScrollPane.remove(ap); } double done = 0d; double todo = 8d; + int lastSortkey = 0; + boolean recalculateSortKeys = false; + for(ActivityPanel ap:list) { + if(ap.getActivity().getSortkey() - lastSortkey < 4) { + recalculateSortKeys = true; + break; + } else { + lastSortkey = ap.getActivity().getSortkey(); + } + } + int sortkey = 0; + if(recalculateSortKeys) { + int sortkeySpace = activityRepository.getSortkeySpace(); + + for(ActivityPanel ap:list) { + sortkey = sortkey + sortkeySpace; + ap.getActivity().setSortkey(sortkey); + activityRepository.update(ap.getActivity()); + ap.getSortkeyTTextField().setText(String.valueOf(sortkey)); + + } + } + Collections.sort(list); for(ActivityPanel ap:list) { double now = ap.getActivity().getSpentHours() + ap.getActivity().getSpentMinutes() / 60d; @@ -252,16 +340,40 @@ public class DayPanel extends JPanel { TTime todoTTime = TTime.ofMilliseconds((int) (todo * 60d * 60d * 1000d)); ap.remains.setText(todoTTime.toString().substring(0,todoTTime.isNegative() ? 6 : 5)); + { + if(this.markActivityPanelToBeMoved != null) { + MoveHereButton mhb = + new MoveHereButton(ap.getActivity().getId()); + panelInsideScrollPane.add(mhb); + } else { +// Component mhb = new MoveHereButton(ap.getActivity().getId()); +// panelInsideScrollPane.add(mhb); + } + } panelInsideScrollPane.add(ap); ap.setVisible(false); ap.setVisible(true); ap.revalidate(); } + revalidate(); } public void markActivityPanelToBeMoved(ActivityPanel activityPanel) { - this.markActivityPanelToBeMoved = activityPanel; + boolean moveHereButtonsExist = Arrays + .stream(panelInsideScrollPane.getComponents()) + .filter(c-> {return (c instanceof MoveHereButton);}).findFirst().isPresent(); + boolean deletion = this.markActivityPanelToBeMoved == activityPanel; + boolean enabling = this.markActivityPanelToBeMoved == null && activityPanel != null; + this.markActivityPanelToBeMoved = deletion ? null : activityPanel; + if(moveHereButtonsExist && deletion) { + sortActivityPanels(); + } + if(!moveHereButtonsExist && enabling) { + sortActivityPanels(); + } + } + } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java index 3290522..9c25c73 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java @@ -18,6 +18,8 @@ public class YearPanel extends JPanel { private final String year; private final Map months; private final TTabbedPane tp; + private final ActivityRepositoryApi activityRepository; + private boolean loaded = false; public YearPanel(String yearIn, ActivityRepositoryApi activityRepository) { super(); @@ -28,6 +30,7 @@ public class YearPanel extends JPanel { add(tp); tp.setBounds(0, 0, 1450, 700); + this.activityRepository = activityRepository; ChangeListener changeListener = new ChangeListener() { private boolean secondOrLaterChange = false; public void stateChanged(ChangeEvent changeEvent) { @@ -46,14 +49,22 @@ public class YearPanel extends JPanel { }; tp.addChangeListener(changeListener); + } + + public void load() { + if(loaded) { + //nothing to do + return; + } + System.out.println("Loaded: " + year); for (int month = 1; month <= 12; month++) { final String monthS = String.valueOf(month); MonthPanel monthPanel = new MonthPanel(year, String.valueOf(month), activityRepository); tp.add(String.valueOf(month), monthPanel); months.put(monthS, monthPanel); } + loaded = true; } - public void setSelectedMonth(String month) { tp.switchTo(month); } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/AnalogClock.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/AnalogClock.java index 63d33ba..88be4ed 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/AnalogClock.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/AnalogClock.java @@ -376,7 +376,7 @@ public class AnalogClock extends Widget { } public int getTimerDelay() { - return 20; + return 10; } } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/Time.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/Time.java index ad53c8b..eb26a5a 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/Time.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/progress/Time.java @@ -104,7 +104,7 @@ public class Time extends Thread { dayOfWeekReadWriteProperty .setValue(dayOfWeek); try { - Thread.sleep(100); + Thread.sleep(10); } catch (InterruptedException e) { System.out.println(e); }