From bf1ec599eeabdb14e46b6dacf4b2904dc7888820 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Fri, 6 Feb 2026 17:10:41 +0100 Subject: [PATCH] menu improved --- pom.xml | 8 +- .../java/cz/kamma/jkeepass/KeepassApp.java | 130 ++++++++++++++---- 2 files changed, 104 insertions(+), 34 deletions(-) diff --git a/pom.xml b/pom.xml index 19d13d5..ef1fade 100644 --- a/pom.xml +++ b/pom.xml @@ -9,8 +9,8 @@ 1.0-SNAPSHOT - 17 - 17 + 11 + 11 UTF-8 @@ -29,8 +29,8 @@ maven-compiler-plugin 3.11.0 - 17 - 17 + 11 + 11 diff --git a/src/main/java/cz/kamma/jkeepass/KeepassApp.java b/src/main/java/cz/kamma/jkeepass/KeepassApp.java index e91e736..22e7ab1 100644 --- a/src/main/java/cz/kamma/jkeepass/KeepassApp.java +++ b/src/main/java/cz/kamma/jkeepass/KeepassApp.java @@ -88,6 +88,15 @@ public class KeepassApp extends JFrame { private String currentPassword; private TrayIcon trayIcon; + + // Menu items that need state management + private JMenuItem menuSave; + private JMenuItem menuLock; + private JMenuItem menuEntryAdd; + private JMenuItem menuEntryEdit; + private JMenuItem menuEntryDelete; + private JMenuItem menuEditCopyUser; + private JMenuItem menuEditCopyPass; public KeepassApp() { @@ -282,22 +291,22 @@ public class KeepassApp extends JFrame { JMenu fileMenu = new JMenu("File"); JMenuItem openItem = new JMenuItem("Open Database..."); recentMenu = new JMenu("Open Recent"); - JMenuItem saveItem = new JMenuItem("Save"); + menuSave = new JMenuItem("Save"); JMenuItem minimizeItem = new JMenuItem(SystemTray.isSupported() ? "Minimize to Tray" : "Minimize & Lock"); - JMenuItem lockItem = new JMenuItem("Lock Database"); + menuLock = new JMenuItem("Lock Database"); JMenuItem exitItem = new JMenuItem("Exit"); openItem.addActionListener(e -> openDatabase(null)); - saveItem.addActionListener(e -> saveDatabase()); + menuSave.addActionListener(e -> saveDatabase()); minimizeItem.addActionListener(e -> minimizeToCustomTray()); - lockItem.addActionListener(e -> lockDatabase()); + menuLock.addActionListener(e -> lockDatabase()); exitItem.addActionListener(e -> System.exit(0)); fileMenu.add(openItem); fileMenu.add(recentMenu); - fileMenu.add(saveItem); + fileMenu.add(menuSave); fileMenu.addSeparator(); - fileMenu.add(lockItem); + fileMenu.add(menuLock); fileMenu.add(minimizeItem); fileMenu.add(exitItem); @@ -305,40 +314,42 @@ public class KeepassApp extends JFrame { // Entry Menu JMenu entryMenu = new JMenu("Entry"); - JMenuItem addItem = new JMenuItem("Add Entry..."); - JMenuItem editItem = new JMenuItem("Edit Entry..."); - JMenuItem delItem = new JMenuItem("Delete Entry"); + menuEntryAdd = new JMenuItem("Add Entry..."); + menuEntryEdit = new JMenuItem("Edit Entry..."); + menuEntryDelete = new JMenuItem("Delete Entry"); - addItem.addActionListener(e -> addEntry()); - editItem.addActionListener(e -> editEntry()); - delItem.addActionListener(e -> deleteEntry()); + menuEntryAdd.addActionListener(e -> addEntry()); + menuEntryEdit.addActionListener(e -> editEntry()); + menuEntryDelete.addActionListener(e -> deleteEntry()); - entryMenu.add(addItem); - entryMenu.add(editItem); - entryMenu.add(delItem); + entryMenu.add(menuEntryAdd); + entryMenu.add(menuEntryEdit); + entryMenu.add(menuEntryDelete); // Edit Menu JMenu editMenu = new JMenu("Edit"); - JMenuItem copyUserItem = new JMenuItem("Copy Username"); - JMenuItem copyPassItem = new JMenuItem("Copy Password"); + menuEditCopyUser = new JMenuItem("Copy Username"); + menuEditCopyPass = new JMenuItem("Copy Password"); - copyUserItem.addActionListener(e -> copyToClipboard(true)); - copyPassItem.addActionListener(e -> copyToClipboard(false)); + menuEditCopyUser.addActionListener(e -> copyToClipboard(true)); + menuEditCopyPass.addActionListener(e -> copyToClipboard(false)); - editMenu.add(copyUserItem); - editMenu.add(copyPassItem); + editMenu.add(menuEditCopyUser); + editMenu.add(menuEditCopyPass); // View Menu JMenu viewMenu = new JMenu("View"); JCheckBoxMenuItem onTopItem = new JCheckBoxMenuItem("Always on Top"); onTopItem.addActionListener(e -> setAlwaysOnTop(onTopItem.isSelected())); viewMenu.add(onTopItem); - menuBar.add(fileMenu); menuBar.add(entryMenu); menuBar.add(editMenu); menuBar.add(viewMenu); setJMenuBar(menuBar); + + // Initialize menu state (all disabled until database is loaded) + updateMenuState(); } private void initComponents() { @@ -350,6 +361,7 @@ public class KeepassApp extends JFrame { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) groupTree.getLastSelectedPathComponent(); if (selectedNode != null && selectedNode.getUserObject() instanceof GroupWrapper) { displayEntriesInGroup(((GroupWrapper) selectedNode.getUserObject()).getGroup()); + updateMenuState(); } }); groupTree.addMouseListener(new MouseAdapter() { @@ -419,6 +431,7 @@ public class KeepassApp extends JFrame { } else { notesArea.setText(""); } + updateMenuState(); } }); entryTable.addMouseListener(new MouseAdapter() { @@ -430,14 +443,26 @@ public class KeepassApp extends JFrame { if (row >= 0 && col >= 0) { int modelRow = entryTable.convertRowIndexToModel(row); Entry entry = currentEntries.get(modelRow); - String content = switch (col) { - case 0 -> entry.getTitle(); - case 1 -> entry.getUsername(); - case 2 -> entry.getPassword(); - case 3 -> entry.getUrl(); - case 4 -> entry.getNotes(); - default -> ""; - }; + String content; + switch (col) { + case 0: + content = entry.getTitle(); + break; + case 1: + content = entry.getUsername(); + break; + case 2: + content = entry.getPassword(); + break; + case 3: + content = entry.getUrl(); + break; + case 4: + content = entry.getNotes(); + break; + default: + content = ""; + } copyTextToClipboard(content, entryTable.getColumnName(col)); } } @@ -462,11 +487,20 @@ public class KeepassApp extends JFrame { JPopupMenu popup = new JPopupMenu(); + boolean hasGroup = currentGroup != null; + boolean hasEntry = row >= 0; + JMenuItem addPop = new JMenuItem("Add Entry"); JMenuItem editPop = new JMenuItem("Edit"); JMenuItem copyPop = new JMenuItem("Copy Username"); JMenuItem copyPassPop = new JMenuItem("Copy Password"); JMenuItem delPop = new JMenuItem("Delete"); + + addPop.setEnabled(hasGroup); + editPop.setEnabled(hasEntry); + copyPop.setEnabled(hasEntry); + copyPassPop.setEnabled(hasEntry); + delPop.setEnabled(hasEntry); addPop.addActionListener(al -> addEntry()); editPop.addActionListener(al -> editEntry()); @@ -551,6 +585,35 @@ public class KeepassApp extends JFrame { } } + /** + * Update menu item enabled states based on current application state + */ + private void updateMenuState() { + // Safely check if menu items are initialized (they might not be during early init) + if (menuSave == null || menuLock == null || menuEntryAdd == null || + menuEntryEdit == null || menuEntryDelete == null || + menuEditCopyUser == null || menuEditCopyPass == null) { + return; + } + + boolean dbIsLoaded = database != null; + boolean hasGroupSelected = currentGroup != null; + boolean hasEntrySelected = entryTable != null && entryTable.getSelectedRow() >= 0; + + // File menu items + menuSave.setEnabled(dbIsLoaded); + menuLock.setEnabled(dbIsLoaded); + + // Entry menu items + menuEntryAdd.setEnabled(dbIsLoaded && hasGroupSelected); + menuEntryEdit.setEnabled(hasEntrySelected); + menuEntryDelete.setEnabled(hasEntrySelected); + + // Edit menu items + menuEditCopyUser.setEnabled(hasEntrySelected); + menuEditCopyPass.setEnabled(hasEntrySelected); + } + private void updateRecentMenu() { recentMenu.removeAll(); String recentFiles = prefs.get(PREF_RECENT_LIST, ""); @@ -630,6 +693,7 @@ public class KeepassApp extends JFrame { updateTree(this.database.getRootGroup()); saveRecentFile(selectedFile.getAbsolutePath()); statusLabel.setText(" Database loaded: " + selectedFile.getName()); + updateMenuState(); } catch (Exception ex) { JOptionPane.showMessageDialog(this, "Error loading database: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); ex.printStackTrace(); @@ -664,6 +728,7 @@ public class KeepassApp extends JFrame { treeModel.setRoot(new DefaultMutableTreeNode("Database locked")); statusLabel.setText(" Database locked."); + updateMenuState(); // Re-open password prompt if (currentFile != null) { @@ -686,6 +751,7 @@ public class KeepassApp extends JFrame { updateEntryFromDialog(entry, dialog); displayEntriesInGroup(currentGroup); statusLabel.setText(" Entry added. Remember to Save."); + updateMenuState(); } } @@ -699,6 +765,7 @@ public class KeepassApp extends JFrame { updateEntryFromDialog(entry, dialog); displayEntriesInGroup(currentGroup); statusLabel.setText(" Entry updated. Remember to Save."); + updateMenuState(); } } else { JOptionPane.showMessageDialog(this, "Please select an entry to edit.", "Warning", JOptionPane.WARNING_MESSAGE); @@ -715,6 +782,7 @@ public class KeepassApp extends JFrame { currentGroup.removeEntry(entry); displayEntriesInGroup(currentGroup); statusLabel.setText(" Entry deleted. Remember to Save."); + updateMenuState(); } } else { JOptionPane.showMessageDialog(this, "Please select an entry to delete.", "Warning", JOptionPane.WARNING_MESSAGE); @@ -735,6 +803,7 @@ public class KeepassApp extends JFrame { parentGroup.addGroup(database.newGroup(name.trim())); updateTree(database.getRootGroup()); statusLabel.setText(" Category added. Remember to Save."); + updateMenuState(); } } @@ -770,6 +839,7 @@ public class KeepassApp extends JFrame { parentGroup.removeGroup(group); updateTree(database.getRootGroup()); statusLabel.setText(" Category deleted. Remember to Save."); + updateMenuState(); } }