From 38f09021b34805c68615e58049873df8832fecf4 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sat, 28 Jul 2018 18:11:36 -0400 Subject: [PATCH] Button tooltips and improvements. --- .../masterpassword/gui/util/Components.java | 3 +- .../masterpassword/gui/view/FilesPanel.java | 8 +-- .../gui/view/UserContentPanel.java | 55 ++++++++++++------ .../src/main/resources/media/icon_delete.png | Bin 1372 -> 1526 bytes .../main/resources/media/icon_delete@2x.png | Bin 3338 -> 2122 bytes 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/util/Components.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/util/Components.java index 1eb68e5a..8bc68a9f 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/util/Components.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/util/Components.java @@ -235,7 +235,7 @@ public abstract class Components { } ); } - public static JButton button(final Icon icon, @Nullable final ActionListener actionListener) { + public static JButton button(final Icon icon, @Nullable final ActionListener actionListener, @Nullable String toolTip) { JButton iconButton = button( new AbstractAction( null, icon ) { @Override public void actionPerformed(final ActionEvent e) { @@ -248,6 +248,7 @@ public abstract class Components { return actionListener != null; } } ); + iconButton.setToolTipText( toolTip ); iconButton.setFocusable( false ); return iconButton; diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/FilesPanel.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/FilesPanel.java index 18937afc..8aa0778c 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/FilesPanel.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/FilesPanel.java @@ -3,9 +3,7 @@ package com.lyndir.masterpassword.gui.view; import static com.lyndir.masterpassword.util.Utilities.*; import com.google.common.collect.ImmutableSortedSet; -import com.lyndir.masterpassword.gui.util.Res; -import com.lyndir.masterpassword.gui.util.CollectionListModel; -import com.lyndir.masterpassword.gui.util.Components; +import com.lyndir.masterpassword.gui.util.*; import com.lyndir.masterpassword.model.MPUser; import com.lyndir.masterpassword.model.impl.MPFileUser; import com.lyndir.masterpassword.model.impl.MPFileUserManager; @@ -24,7 +22,8 @@ public class FilesPanel extends JPanel implements MPFileUserManager.Listener { private final Collection listeners = new CopyOnWriteArraySet<>(); - private final JButton avatarButton = Components.button( Res.icons().avatar( 0 ), event -> setAvatar() ); + private final JButton avatarButton = Components.button( Res.icons().avatar( 0 ), event -> setAvatar(), + "Click to change the user's avatar." ); private final CollectionListModel> usersModel = CollectionListModel.>copy( MPFileUserManager.get().getFiles() ).selection( this::setUser ); @@ -43,7 +42,6 @@ public class FilesPanel extends JPanel implements MPFileUserManager.Listener { add( avatarButton ); avatarButton.setHorizontalAlignment( SwingConstants.CENTER ); avatarButton.setMaximumSize( new Dimension( Integer.MAX_VALUE, 0 ) ); - avatarButton.setToolTipText( "The avatar for your user. Click to change it." ); // - add( Components.strut( Components.margin() ) ); diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java index 8734f5b6..5fecd091 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java @@ -35,7 +35,10 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU private static final Random random = new Random(); private static final Logger logger = Logger.get( UserContentPanel.class ); - private static final JButton iconButton = Components.button( Res.icons().user(), null ); + private static final JButton iconButton = Components.button( Res.icons().user(), null, null ); + + private final JButton addButton = Components.button( Res.icons().add(), event -> addUser(), + "Add a new user to Master Password." ); private final JPanel userToolbar = Components.panel( BoxLayout.PAGE_AXIS ); private final JPanel siteToolbar = Components.panel( BoxLayout.PAGE_AXIS ); @@ -108,11 +111,23 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU } ); } + private void addUser() { + Object fullName = JOptionPane.showInputDialog( + this, strf( "Enter your full legal name:" ), "Add User", + JOptionPane.QUESTION_MESSAGE, null, null, "Robert Lee Mitchell" ); + if (fullName == null) + return; + + setUser( MPFileUserManager.get().add( fullName.toString() ) ); + } + private final class NoUserPanel extends JPanel { private NoUserPanel() { setLayout( new BoxLayout( this, BoxLayout.PAGE_AXIS ) ); + userToolbar.add( addButton ); + add( Box.createGlue() ); add( Components.heading( "Select a user to proceed." ) ); add( Box.createGlue() ); @@ -125,8 +140,8 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU @Nonnull private final MPUser user; - private final JButton addButton = Components.button( Res.icons().add(), event -> addUser() ); - private final JButton deleteButton = Components.button( Res.icons().delete(), event -> deleteUser() ); + private final JButton deleteButton = Components.button( Res.icons().delete(), event -> deleteUser(), + "Delete this user from Master Password." ); private final JPasswordField masterPasswordField = Components.passwordField(); private final JLabel errorLabel = Components.label(); @@ -159,16 +174,6 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU add( Box.createGlue() ); } - private void addUser() { - Object fullName = JOptionPane.showInputDialog( - this, strf( "Enter your full legal name:" ), "Add User", - JOptionPane.QUESTION_MESSAGE, null, null, "Robert Lee Mitchell" ); - if (fullName == null) - return; - - setUser( MPFileUserManager.get().add( fullName.toString() ) ); - } - private void deleteUser() { MPFileUser fileUser = (user instanceof MPFileUser)? (MPFileUser) user: null; if (fileUser == null) @@ -248,11 +253,16 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU public static final int SIZE_RESULT = 48; - private final JButton userButton = Components.button( Res.icons().user(), event -> showUserPreferences() ); - private final JButton logoutButton = Components.button( Res.icons().lock(), event -> logoutUser() ); - private final JButton settingsButton = Components.button( Res.icons().settings(), event -> showSiteSettings() ); - private final JButton questionsButton = Components.button( Res.icons().question(), null ); - private final JButton deleteButton = Components.button( Res.icons().delete(), event -> deleteSite() ); + private final JButton userButton = Components.button( Res.icons().user(), event -> showUserPreferences(), + "Show user preferences." ); + private final JButton logoutButton = Components.button( Res.icons().lock(), event -> logoutUser(), + "Sign out and lock user." ); + private final JButton settingsButton = Components.button( Res.icons().settings(), event -> showSiteSettings(), + "Show site settings." ); + private final JButton questionsButton = Components.button( Res.icons().question(), null, + "Show site recovery questions." ); + private final JButton deleteButton = Components.button( Res.icons().delete(), event -> deleteSite(), + "Delete the site from the user." ); @Nonnull private final MPUser user; @@ -272,6 +282,7 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU this.user = user; + userToolbar.add( addButton ); userToolbar.add( userButton ); userToolbar.add( logoutButton ); @@ -279,6 +290,7 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU siteToolbar.add( questionsButton ); siteToolbar.add( deleteButton ); settingsButton.setEnabled( false ); + deleteButton.setEnabled( false ); add( Components.heading( user.getFullName(), SwingConstants.CENTER ) ); @@ -366,7 +378,10 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU if (site == null) return; - user.deleteSite( site ); + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog( + this, strf( "Forget the site %s?", site.getSiteName() ), + "Delete Site", JOptionPane.YES_NO_OPTION )) + user.deleteSite( site ); } private String getSiteDescription(@Nonnull final MPSite site) { @@ -434,6 +449,7 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU passwordLabel.setText( " " ); passwordField.setText( " " ); settingsButton.setEnabled( false ); + deleteButton.setEnabled( false ); } ); return; } @@ -448,6 +464,7 @@ public class UserContentPanel extends JPanel implements FilesPanel.Listener, MPU passwordLabel.setText( strf( "Your password for %s:", site.getSiteName() ) ); passwordField.setText( result ); settingsButton.setEnabled( true ); + deleteButton.setEnabled( true ); } ); } catch (final MPKeyUnavailableException | MPAlgorithmException e) { diff --git a/platform-independent/java/gui/src/main/resources/media/icon_delete.png b/platform-independent/java/gui/src/main/resources/media/icon_delete.png index 801d2c5587f4298bca743d1ec15a9117e549457b..5a82d20d30e6b43f1f73a4f5506b8aa334f10e5c 100644 GIT binary patch literal 1526 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=hEVFsEgPM3hAM`dB6B=jtV<?;Zqle1Gx6p~WYGxKbf-tXS8q>!0ns}yePYv5bpoSKp8QB{;0T;&&% zT$P<{nWAKGr(jcI1vDTxwIorYA~z?m*s8)-32d$vkPQ;nS5g2gDap1~as*kZ5aAo3 z;GAESs$i;Tpqp%9W}skZsAp(wVs37(qhMrUXrOOkq;F`XYiMp|Y-D9%pa2C*K--E^ z(yW49+@N*=dA3R!B_#z``ugSN<$C4Ddih1^`i7R4mLM~XjC6r2bc-wVN)jt{^NN*W zCb*;)Cl_TFlw{`TDS%8&Ov*1Uu~h=P6yk;40$*Ra!Fk2dfC2`Yennz|zM-Cher_(v zUtrb6B|)hOXJA!b98y`3svneEoL^d$oC;K~4ATq@JNy=b6armi7u7M@JCVPIfV z^K@|xi8%arx_`ECpvck3YHQyKH7STLO}WVOhoP=Puj^84UQ@hdLHv@_b=?Xt4h4xf z?cmXq7AREB6zR&%ouqcwC;6<(WY5pftNbhdNg$i4#-d!ap+ma)iw|?;9F48Sndp9qC`st_JcgDOkJkP(p zF?ngwOWyT=8Tzvue;V*?S3jR;BRBu^a^CD8UNJZNeNt|V?1)<#V#n9+{A;#?@XavR z8Nbi`N-$73P}N+im2&vQ`qe(GnTpTwrtPdRb8Gm@HCc31(vRt(&*nT)Jo9al9iynl z`Si`r{@%7P#s70{N?h;mz^daC$g($KrTX7bOmp)*fPBrpDPZ2)1uq9Ua(rWh74%{}6qj^MwOg{+?$yRKDQNPnMDe-DYW(ja8SG7cj?e zF+9zEMd~Wtmg^NntQJ1;{BwWBzO#2y^R()g=O0}B zcO9!yeA)i8eWCp)zWeiWwH~s)H$7>c)}-k#M6OlM+t03VbVXE9+++WpJ6bX!S>r7`_nPT+w!OhR&@9p2#yn81f=E-F9LCHDRvar!&^NBS^ z{xeJu-o7yF)0$O1J6=Z@#%%R}t$uq_&!;74^tWpn{7(O}{wHUSc$a*KP-Ot9xb}4Q Kb6Mw<&;$Sk#Wk1! delta 1354 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 QQ~&?~07*qoM6N<$f|R~?Gynhq