diff options
12 files changed, 557 insertions, 39 deletions
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java index 6c27910a..e4af6443 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java @@ -46,6 +46,7 @@ public interface BKUGUIFacade { public static final String DEFAULT_BACKGROUND = "/at/gv/egiz/bku/gui/chip32.png"; public static final String DEFAULT_ICON = "/at/gv/egiz/bku/gui/chiperling105.png"; public static final String HELP_IMG = "/at/gv/egiz/bku/gui/help.png"; + public static final String HELP_IMG_FOCUS = "/at/gv/egiz/bku/gui/help_focus.png"; public static final String HASHDATA_FONT = "Monospaced"; public static final Color ERROR_COLOR = Color.RED; public static final Color HYPERLINK_COLOR = Color.BLUE; @@ -75,6 +76,8 @@ public interface BKUGUIFacade { public static final String MESSAGE_ENTERPIN_PINPAD = "enterpin.pinpad"; public static final String MESSAGE_HASHDATALINK = "hashdatalink"; public static final String MESSAGE_HASHDATALINK_TINY = "hashdatalink.tiny"; + public static final String MESSAGE_HASHDATALINK_FOCUS = "hashdatalink.focus"; + public static final String MESSAGE_HASHDATALINK_TINY_FOCUS = "hashdatalink.tiny.focus"; public static final String MESSAGE_HASHDATALIST = "hashdatalist"; public static final String MESSAGE_RETRIES = "retries"; public static final String MESSAGE_LAST_RETRY = "retries.last"; @@ -153,4 +156,6 @@ public interface BKUGUIFacade { public void showMessageDialog(String titleKey, String msgKey); + + public void getFocusFromBrowser(); } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java index b84a2164..e83502a8 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java @@ -26,6 +26,10 @@ import java.awt.Font; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; @@ -45,11 +49,14 @@ import javax.swing.JTable; import javax.swing.LayoutStyle; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + + /** * * @author clemens @@ -62,7 +69,9 @@ public class BKUGUIImpl implements BKUGUIFacade { LEFT, ABOVE } - protected HelpMouseListener helpListener; + protected HelpMouseListener helpMouseListener; + protected HelpKeyListener helpKeyListener; + protected SwitchFocusFocusListener switchFocusKeyListener; protected SecureViewerDialog secureViewer; protected Container contentPane; @@ -77,6 +86,7 @@ public class BKUGUIImpl implements BKUGUIFacade { /** right side fixed labels */ protected JLabel titleLabel; protected JLabel helpLabel; + protected JLabel switchFocusDummyLabel; /** remember the pinfield to return to worker */ protected JPasswordField pinField; @@ -107,7 +117,8 @@ public class BKUGUIImpl implements BKUGUIFacade { Locale locale, Style guiStyle, URL background, - ActionListener helpListener) { + ActionListener helpListener, + SwitchFocusListener switchFocusListener) { this.contentPane = contentPane; loadMessageBundle(locale); @@ -122,8 +133,13 @@ public class BKUGUIImpl implements BKUGUIFacade { pinLabelPos = PinLabelPosition.ABOVE; } + // ensure that buttons can be fired with enter key too + UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); + registerHelpListener(helpListener); + registerSwitchFocusListener(switchFocusListener); + createGUI(background); } @@ -224,12 +240,35 @@ public class BKUGUIImpl implements BKUGUIFacade { mainPanel.setOpaque(false); buttonPanel = new JPanel(); buttonPanel.setOpaque(false); - + helpLabel = new JLabel(); helpLabel.setIcon(new ImageIcon(getClass().getResource(HELP_IMG))); helpLabel.getAccessibleContext().setAccessibleName(getMessage(ALT_HELP)); - helpLabel.addMouseListener(helpListener); + helpLabel.setFocusable(true); + helpLabel.addMouseListener(helpMouseListener); + helpLabel.addKeyListener(helpKeyListener); + helpLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + helpLabel.setIcon(new ImageIcon(getClass().getResource(HELP_IMG_FOCUS))); + } + + @Override + public void focusLost(FocusEvent e) { + + helpLabel.setIcon(new ImageIcon(getClass().getResource(HELP_IMG))); + } + + + }); helpLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + + switchFocusDummyLabel = new JLabel(); + switchFocusDummyLabel.setText(""); + switchFocusDummyLabel.setFocusable(true); + switchFocusDummyLabel.addFocusListener(switchFocusKeyListener); buttonSize = initButtonSize(); @@ -248,11 +287,15 @@ public class BKUGUIImpl implements BKUGUIFacade { headerPanelLayout.createSequentialGroup() .addComponent(titleLabel, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(helpLabel)); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ); headerPanelLayout.setVerticalGroup( headerPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(titleLabel, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addComponent(helpLabel)); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ); } GroupLayout contentPanelLayout = new GroupLayout(contentPanel); @@ -566,7 +609,8 @@ public class BKUGUIImpl implements BKUGUIFacade { } else { infoLabel.setText(MessageFormat.format(infoPattern, new Object[] {pinSpec.getLocalizedName()})); } - helpListener.setHelpTopic(HELP_CARDPIN); + helpMouseListener.setHelpTopic(HELP_CARDPIN); + helpKeyListener.setHelpTopic(HELP_CARDPIN); } else { String retryPattern; if (numRetries < 2) { @@ -577,7 +621,8 @@ public class BKUGUIImpl implements BKUGUIFacade { infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() | java.awt.Font.BOLD)); infoLabel.setText(MessageFormat.format(retryPattern, new Object[]{String.valueOf(numRetries)})); infoLabel.setForeground(ERROR_COLOR); - helpListener.setHelpTopic(HELP_RETRY); + helpMouseListener.setHelpTopic(HELP_RETRY); + helpKeyListener.setHelpTopic(HELP_RETRY); } JLabel pinsizeLabel = new JLabel(); @@ -595,9 +640,13 @@ public class BKUGUIImpl implements BKUGUIFacade { if (!renderHeaderPanel) { infoHorizontal .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(helpLabel); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; infoVertical - .addComponent(helpLabel); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; } // align pinfield and pinsize to the right @@ -668,7 +717,9 @@ public class BKUGUIImpl implements BKUGUIFacade { buttonPanelLayout.setHorizontalGroup(buttonHorizontal); buttonPanelLayout.setVerticalGroup(buttonVertical); - pinField.requestFocusInWindow(); +// pinField.requestFocusInWindow(); +// helpLabel.requestFocus(); + pinField.requestFocus(); contentPanel.validate(); } @@ -715,7 +766,7 @@ public class BKUGUIImpl implements BKUGUIFacade { } } - JLabel infoLabel = new JLabel(); + final JLabel infoLabel = new JLabel(); if (numRetries < 0) { infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); if (shortText) { @@ -723,6 +774,7 @@ public class BKUGUIImpl implements BKUGUIFacade { } else { infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); } + infoLabel.setFocusable(true); infoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); infoLabel.setForeground(HYPERLINK_COLOR); infoLabel.addMouseListener(new MouseAdapter() { @@ -733,7 +785,47 @@ public class BKUGUIImpl implements BKUGUIFacade { hashdataListener.actionPerformed(e); } }); - helpListener.setHelpTopic(HELP_SIGNPIN); + + infoLabel.addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + + if(e.getKeyCode() == KeyEvent.VK_ENTER) { + ActionEvent e1 = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand); + hashdataListener.actionPerformed(e1); + } + } + + }); + + infoLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + if (shortText) { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY_FOCUS)); + } else { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_FOCUS)); + } + } + + @Override + public void focusLost(FocusEvent e) { + + if (shortText) { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY)); + } else { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); + } + + } + + }); + + helpMouseListener.setHelpTopic(HELP_SIGNPIN); + helpKeyListener.setHelpTopic(HELP_SIGNPIN); } else { String retryPattern; if (numRetries < 2) { @@ -741,10 +833,12 @@ public class BKUGUIImpl implements BKUGUIFacade { } else { retryPattern = getMessage(MESSAGE_RETRIES); } + infoLabel.setFocusable(true); infoLabel.setText(MessageFormat.format(retryPattern, new Object[]{String.valueOf(numRetries)})); infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() | java.awt.Font.BOLD)); infoLabel.setForeground(ERROR_COLOR); - helpListener.setHelpTopic(HELP_RETRY); + helpMouseListener.setHelpTopic(HELP_RETRY); + helpKeyListener.setHelpTopic(HELP_RETRY); } String msgPattern = getMessage(MESSAGE_ENTERPIN_PINPAD); @@ -766,9 +860,13 @@ public class BKUGUIImpl implements BKUGUIFacade { if (!renderHeaderPanel) { infoHorizontal .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(helpLabel); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; infoVertical - .addComponent(helpLabel); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; } mainPanelLayout.setHorizontalGroup( @@ -837,7 +935,7 @@ public class BKUGUIImpl implements BKUGUIFacade { } } - JLabel infoLabel = new JLabel(); + final JLabel infoLabel = new JLabel(); if (numRetries < 0) { infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); if (shortText) { @@ -845,6 +943,7 @@ public class BKUGUIImpl implements BKUGUIFacade { } else { infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); } + infoLabel.setFocusable(true); infoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); infoLabel.setForeground(HYPERLINK_COLOR); infoLabel.addMouseListener(new MouseAdapter() { @@ -855,7 +954,49 @@ public class BKUGUIImpl implements BKUGUIFacade { hashdataListener.actionPerformed(e); } }); - helpListener.setHelpTopic(HELP_SIGNPIN); + + infoLabel.addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + + if(e.getKeyCode() == KeyEvent.VK_ENTER) { + ActionEvent e1 = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand); + hashdataListener.actionPerformed(e1); + } + } + + }); + + infoLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + + if (shortText) { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY_FOCUS)); + } else { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_FOCUS)); + } + } + + @Override + public void focusLost(FocusEvent e) { + + + if (shortText) { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY)); + } else { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); + } + + } + + }); + + helpMouseListener.setHelpTopic(HELP_SIGNPIN); + helpKeyListener.setHelpTopic(HELP_SIGNPIN); } else { String retryPattern; if (numRetries < 2) { @@ -863,10 +1004,12 @@ public class BKUGUIImpl implements BKUGUIFacade { } else { retryPattern = getMessage(MESSAGE_RETRIES); } + infoLabel.setFocusable(true); infoLabel.setText(MessageFormat.format(retryPattern, new Object[]{String.valueOf(numRetries)})); infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() | java.awt.Font.BOLD)); infoLabel.setForeground(ERROR_COLOR); - helpListener.setHelpTopic(HELP_RETRY); + helpMouseListener.setHelpTopic(HELP_RETRY); + helpKeyListener.setHelpTopic(HELP_RETRY); } JButton signButton = new JButton(); @@ -895,6 +1038,7 @@ public class BKUGUIImpl implements BKUGUIFacade { } }); + JLabel pinsizeLabel = new JLabel(); pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont(pinsizeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, pinsizeLabel.getFont().getSize()-2)); pinsizeLabel.setText(MessageFormat.format(getMessage(LABEL_PINSIZE), pinSpec.getLocalizedLength())); @@ -910,9 +1054,13 @@ public class BKUGUIImpl implements BKUGUIFacade { if (!renderHeaderPanel) { infoHorizontal .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(helpLabel); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; infoVertical - .addComponent(helpLabel); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; } // align pinfield and pinsize to the right @@ -973,21 +1121,27 @@ public class BKUGUIImpl implements BKUGUIFacade { buttonHorizontal .addComponent(signButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE); + .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) + ; buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(signButton) - .addComponent(cancelButton); + .addComponent(cancelButton) + ; } else { buttonHorizontal - .addComponent(signButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE); + .addComponent(signButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) + ; buttonVertical = buttonPanelLayout.createSequentialGroup() - .addComponent(signButton); + .addComponent(signButton) + ; } buttonPanelLayout.setHorizontalGroup(buttonHorizontal); buttonPanelLayout.setVerticalGroup(buttonVertical); - pinField.requestFocusInWindow(); +// pinField.requestFocusInWindow(); +// helpLabel.requestFocus(); + pinField.requestFocus(); contentPanel.validate(); } @@ -1065,7 +1219,8 @@ public class BKUGUIImpl implements BKUGUIFacade { titleLabel.setText(getMessage(titleKey)); } - helpListener.setHelpTopic(msgKey); + helpMouseListener.setHelpTopic(msgKey); + helpKeyListener.setHelpTopic(msgKey); String msgPattern = getMessage(msgKey); String msg = MessageFormat.format(msgPattern, msgParams); @@ -1080,6 +1235,9 @@ public class BKUGUIImpl implements BKUGUIFacade { GroupLayout.ParallelGroup mainHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING); GroupLayout.SequentialGroup mainVertical = mainPanelLayout.createSequentialGroup(); + log.debug("focus to contentPanel"); + contentPanel.requestFocus(); + if (!renderHeaderPanel) { JLabel titleLabel = new JLabel(); titleLabel.setFont(titleLabel.getFont().deriveFont(titleLabel.getFont().getStyle() | Font.BOLD)); @@ -1092,11 +1250,18 @@ public class BKUGUIImpl implements BKUGUIFacade { .addGroup(mainPanelLayout.createSequentialGroup() .addComponent(titleLabel) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(helpLabel)); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ); mainVertical .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(titleLabel) - .addComponent(helpLabel)); + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ); + + log.debug("focus to helpLabel"); + helpLabel.requestFocus(); } mainPanelLayout.setHorizontalGroup(mainHorizontal @@ -1105,6 +1270,7 @@ public class BKUGUIImpl implements BKUGUIFacade { .addComponent(msgLabel)); if (okListener != null) { + JButton okButton = new JButton(); okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~java.awt.Font.BOLD)); okButton.setText(getMessage((buttonKey != null) ? buttonKey : BUTTON_OK)); @@ -1120,6 +1286,9 @@ public class BKUGUIImpl implements BKUGUIFacade { buttonPanelLayout.setVerticalGroup( buttonPanelLayout.createSequentialGroup() .addComponent(okButton)); + + log.debug("focus to ok-button"); + okButton.requestFocus(); } contentPanel.validate(); @@ -1243,7 +1412,7 @@ public class BKUGUIImpl implements BKUGUIFacade { log.debug("show secure viewer [" + Thread.currentThread().getName() + "]"); if (secureViewer == null) { secureViewer = new SecureViewerDialog(null, messages, - helpListener.getActionListener()); + helpMouseListener.getActionListener()); // workaround for [#439] // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top. @@ -1276,7 +1445,8 @@ public class BKUGUIImpl implements BKUGUIFacade { titleLabel.setText(getMessage(TITLE_HASHDATA)); } - helpListener.setHelpTopic(HELP_HASHDATALIST); + helpMouseListener.setHelpTopic(HELP_HASHDATALIST); + helpKeyListener.setHelpTopic(HELP_HASHDATALIST); JLabel refIdLabel = new JLabel(); refIdLabel.setFont(refIdLabel.getFont().deriveFont(refIdLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); @@ -1335,10 +1505,14 @@ public class BKUGUIImpl implements BKUGUIFacade { if (!renderHeaderPanel) { messageHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(helpLabel); - messageVertical - .addComponent(helpLabel); + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; + messageVertical + .addComponent(switchFocusDummyLabel) + .addComponent(helpLabel) + ; } mainPanelLayout.setHorizontalGroup( @@ -1469,19 +1643,42 @@ public class BKUGUIImpl implements BKUGUIFacade { private void registerHelpListener(ActionListener helpListener) { if (helpListener != null) { - this.helpListener = new HelpMouseListener(helpListener); + this.helpMouseListener = new HelpMouseListener(helpListener); + this.helpKeyListener = new HelpKeyListener(helpListener); } else { log.error("no help listener provided, will not be able to display help"); - this.helpListener = new HelpMouseListener(new ActionListener() { + this.helpMouseListener = new HelpMouseListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { log.error("no help listener registered (requested help topic: " + e.getActionCommand() + ")"); } }); + this.helpKeyListener = new HelpKeyListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + log.error("no help listener registered (requested help topic: " + e.getActionCommand() + ")"); + } + }); } } + private void registerSwitchFocusListener(ActionListener switchFocusListener) { + if (switchFocusListener != null) { + this.switchFocusKeyListener = new SwitchFocusFocusListener(switchFocusListener); + + } else { + + this.switchFocusKeyListener = new SwitchFocusFocusListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + log.warn("no switch focus listener registered"); + } + }); + } + } //////////////////////////////////////////////////////////////////////////// // INITIALIZERS (MAY BE OVERRIDDEN BY SUBCLASSES) @@ -1539,4 +1736,13 @@ public class BKUGUIImpl implements BKUGUIFacade { } return bs; } + + @Override + public void getFocusFromBrowser() { + + // This method puts the focus to the helpLabel as this + // element is supposed to appear in each dialogue. + helpLabel.requestFocus(); + + } } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpKeyListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpKeyListener.java new file mode 100644 index 00000000..4ca20f7e --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpKeyListener.java @@ -0,0 +1,46 @@ +package at.gv.egiz.bku.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Thomas Zefferer <thomas.zefferer@iaik.tugraz.at>
+ */
+public class HelpKeyListener extends KeyAdapter {
+
+ protected static final Log log = LogFactory.getLog(HelpKeyListener.class);
+
+ protected ActionListener helpListener;
+ protected String locale;
+ protected String topic;
+
+ public HelpKeyListener(ActionListener externalHelpListener) {
+ super();
+ this.helpListener = externalHelpListener;
+ }
+
+ public void setHelpTopic(String topic) {
+ log.trace("setting help topic: " + topic);
+ this.topic = topic;
+ }
+
+ public ActionListener getActionListener() {
+ return helpListener;
+ }
+
+ @Override
+ public void keyPressed(KeyEvent arg0) {
+
+ if(arg0.getKeyCode() == KeyEvent.VK_ENTER) {
+ ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, topic);
+ helpListener.actionPerformed(e);
+ }
+ }
+
+}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpLinkFocusManager.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpLinkFocusManager.java new file mode 100644 index 00000000..f5882b3d --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpLinkFocusManager.java @@ -0,0 +1,138 @@ +package at.gv.egiz.bku.gui;
+
+import java.awt.Color;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.net.URL;
+
+import javax.accessibility.AccessibleHyperlink;
+import javax.accessibility.AccessibleHypertext;
+import javax.swing.JEditorPane;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Element;
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+
+/**
+ *
+ * @author Thomas Zefferer <thomas.zefferer@iaik.tugraz.at>
+ */
+public final class HelpLinkFocusManager extends KeyAdapter {
+
+ private static final int FOCUS_UNDEFINED = -1;
+
+ private int focusedHyperlinkIndex = FOCUS_UNDEFINED;
+ private JEditorPane displayPane;
+
+ public HelpLinkFocusManager(JEditorPane displayPane) {
+
+ super();
+ this.displayPane = displayPane;
+ }
+
+ public void keyPressed(KeyEvent e) {
+
+ AccessibleHypertext accessibleHypertext = (AccessibleHypertext) this.displayPane
+ .getAccessibleContext().getAccessibleText();
+
+ if (accessibleHypertext.getLinkCount() > 0) {
+ switch (e.getKeyCode()) {
+
+ case KeyEvent.VK_RIGHT:
+ if (this.focusedHyperlinkIndex != FOCUS_UNDEFINED) {
+ removeHyperlinkFocus();
+ }
+
+ this.focusedHyperlinkIndex++;
+
+ if (this.focusedHyperlinkIndex >= accessibleHypertext
+ .getLinkCount()) {
+
+ this.focusedHyperlinkIndex = 0;
+ }
+
+ setHyperlinkFocus();
+ break;
+
+ case KeyEvent.VK_LEFT:
+ if (this.focusedHyperlinkIndex != FOCUS_UNDEFINED) {
+ removeHyperlinkFocus();
+ }
+
+ this.focusedHyperlinkIndex--;
+
+ if (this.focusedHyperlinkIndex < 0) {
+ this.focusedHyperlinkIndex = accessibleHypertext
+ .getLinkCount() - 1;
+ }
+
+ setHyperlinkFocus();
+ break;
+
+ case KeyEvent.VK_SPACE:
+ case KeyEvent.VK_ENTER:
+
+
+ AccessibleHyperlink link = accessibleHypertext
+ .getLink(this.focusedHyperlinkIndex);
+ if (link != null) {
+ URL url = (URL) link.getAccessibleActionObject(0);
+ Element element = ((DefaultStyledDocument) this.displayPane
+ .getDocument()).getCharacterElement(link
+ .getStartIndex());
+ HyperlinkEvent linkEvent = new HyperlinkEvent(
+ this.displayPane,
+ HyperlinkEvent.EventType.ACTIVATED, url, null,
+ element);
+ this.displayPane.fireHyperlinkUpdate(linkEvent);
+ }
+
+ removeHyperlinkFocus();
+ this.focusedHyperlinkIndex = FOCUS_UNDEFINED;
+ break;
+ default:
+ // nothig to do
+ break;
+ }
+ }
+ }
+
+ private void setHyperlinkFocus() {
+
+ AccessibleHypertext accessibleHypertext = (AccessibleHypertext) this.displayPane
+ .getAccessibleContext().getAccessibleText();
+ AccessibleHyperlink link = accessibleHypertext
+ .getLink(this.focusedHyperlinkIndex);
+
+ if (link != null) {
+
+ MutableAttributeSet style = new SimpleAttributeSet();
+ StyleConstants.setForeground(style, Color.RED);
+ ((DefaultStyledDocument) this.displayPane.getDocument())
+ .setCharacterAttributes(link.getStartIndex(), link
+ .getEndIndex()
+ - link.getStartIndex(), style, false);
+ }
+ }
+
+ private void removeHyperlinkFocus() {
+ Color textColor = Color.BLUE;
+ AccessibleHypertext accessibleHypertext = (AccessibleHypertext) this.displayPane
+ .getAccessibleContext().getAccessibleText();
+ AccessibleHyperlink link = accessibleHypertext
+ .getLink(this.focusedHyperlinkIndex);
+
+ if (link != null) {
+
+ MutableAttributeSet style = new SimpleAttributeSet();
+ StyleConstants.setForeground(style, textColor);
+ ((DefaultStyledDocument) this.displayPane.getDocument())
+ .setCharacterAttributes(link.getStartIndex(), link
+ .getEndIndex()
+ - link.getStartIndex(), style, false);
+ }
+ }
+
+}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpViewer.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpViewer.java index 48393101..0f887f78 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpViewer.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpViewer.java @@ -135,6 +135,10 @@ public class HelpViewer extends JDialog try { viewer.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); viewer.setPage(helpURL); + + HelpLinkFocusManager editorFocusManager = new HelpLinkFocusManager (viewer); + viewer.addKeyListener(editorFocusManager ); + viewer.addHyperlinkListener(new HyperlinkListener() { @Override diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java index 84c2a5ff..ef70f94b 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java @@ -24,6 +24,10 @@ import java.awt.Font; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.BufferedOutputStream; @@ -149,7 +153,8 @@ public class SecureViewerDialog extends JDialog implements ActionListener { infoVertical.addComponent(viewerLabel); if (helpListener != null) { - JLabel helpLabel = new JLabel(); + final JLabel helpLabel = new JLabel(); + helpLabel.setFocusable(true); helpLabel.setIcon(new ImageIcon(getClass().getResource(BKUGUIFacade.HELP_IMG))); helpLabel.getAccessibleContext().setAccessibleName(messages.getString(BKUGUIFacade.ALT_HELP)); helpLabel.addMouseListener(new MouseAdapter() { @@ -160,6 +165,34 @@ public class SecureViewerDialog extends JDialog implements ActionListener { helpListener.actionPerformed(e); } }); + helpLabel.addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent arg0) { + + if(arg0.getKeyCode() == KeyEvent.VK_ENTER) { + ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, BKUGUIFacade.HELP_HASHDATAVIEWER); + helpListener.actionPerformed(e); + } + } + }); + + helpLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + helpLabel.setIcon(new ImageIcon(getClass().getResource(BKUGUIFacade.HELP_IMG_FOCUS))); + } + + @Override + public void focusLost(FocusEvent e) { + + helpLabel.setIcon(new ImageIcon(getClass().getResource(BKUGUIFacade.HELP_IMG))); + } + + + }); helpLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); infoHorizontal.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE).addComponent(helpLabel); diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusFocusListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusFocusListener.java new file mode 100644 index 00000000..06e37a89 --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusFocusListener.java @@ -0,0 +1,38 @@ +package at.gv.egiz.bku.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Thomas Zefferer <thomas.zefferer@iaik.tugraz.at>
+ */
+public class SwitchFocusFocusListener extends FocusAdapter {
+
+ protected static final Log log = LogFactory.getLog(SwitchFocusFocusListener.class);
+
+ protected ActionListener swichFocusListener;
+
+ public SwitchFocusFocusListener(ActionListener externalSwitchFocusListener) {
+ super();
+ this.swichFocusListener = externalSwitchFocusListener;
+ }
+
+ public ActionListener getActionListener() {
+ return swichFocusListener;
+ }
+
+ @Override
+ public void focusGained(FocusEvent arg0) {
+
+ ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null);
+ swichFocusListener.actionPerformed(e);
+ }
+
+
+}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusListener.java new file mode 100644 index 00000000..1e3fabbd --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusListener.java @@ -0,0 +1,44 @@ +package at.gv.egiz.bku.gui;
+
+import java.applet.AppletContext;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Thomas Zefferer <thomas.zefferer@iaik.tugraz.at>
+ */
+public class SwitchFocusListener implements ActionListener {
+
+ protected final static Log log = LogFactory.getLog(SwitchFocusListener.class);
+
+ protected AppletContext ctx;
+ protected String javascriptFunction;
+
+ public SwitchFocusListener(AppletContext ctx, String javascriptFunction) {
+
+ this.ctx = ctx;
+ this.javascriptFunction = javascriptFunction;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+
+ try {
+ ctx.showDocument
+ (new URL("javascript:" + javascriptFunction));
+ }
+ catch (MalformedURLException me) {
+
+ log.warn("Unable to call external javascript function.", me);
+ }
+
+
+ }
+
+}
diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties index 146d9353..a96b835f 100644 --- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties @@ -40,6 +40,8 @@ enterpin=<html>{0} eingeben</html> enterpin.pinpad=<html>{0} ({1} stellig) am Kartenleser eingeben</html> hashdatalink=<html><a href=\"anzeige\">Signaturdaten anzeigen</a></html> hashdatalink.tiny=<html><a href=\"anzeige\">Signaturdaten</a></html> +hashdatalink.focus=<html><a href=\"anzeige\">[Signaturdaten anzeigen]</a></html> +hashdatalink.tiny.focus=<html><a href=\"anzeige\">[Signaturdaten]</a></html> #message.hashdata=<html>Hinweis: Dies ist eine Voransicht des zu signierenden Inhalts. F\u00FCr eine standardkonforme Darstellung siehe Hilfe (i).</html> #message.hashdata=<html>Dies ist eine Voransicht des zu signierenden Inhaltes. F\u00FCr Details siehe Hilfe (i).</html> #verwenden sie bitte die von ihrem System zur Verf\u00FCgung gestellte {0} Anwendung. diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties index 1a40aeea..c795b3fa 100644 --- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties @@ -40,6 +40,8 @@ enterpin=<html>Enter {0}</html> enterpin.pinpad=<html>Enter {0} ({1} digits) on card reader pinpad</html> hashdatalink=<html><a href=\"anzeige\">Display signature data</a></html> hashdatalink.tiny=<html><a href=\"anzeige\">signature data</a></html> +hashdatalink.focus=<html><a href=\"anzeige\">[Display signature data]</a></html> +hashdatalink.tiny.focus=<html><a href=\"anzeige\">[signature data]</a></html> #message.hashdata=<html>Remark: This is a preview of the data to-be signed. For standards compliant display see help.</html> hashdatalist=<html>{0} signature data objects:</html> retries.last=<html>Last try!</html> diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/help_focus.png b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/help_focus.png Binary files differnew file mode 100644 index 00000000..d650bea2 --- /dev/null +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/help_focus.png diff --git a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUITest.java b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUITest.java index b3eaf8c7..9f1cb612 100644 --- a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUITest.java +++ b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUITest.java @@ -41,7 +41,7 @@ public class BKUGUITest { Container contentPane = testFrame.getContentPane(); // contentPane.setPreferredSize(new Dimension(170, 150)); contentPane.setPreferredSize(new Dimension(290, 190)); - BKUGUIFacade gui = new BKUGUIImpl(contentPane, null, BKUGUIFacade.Style.advanced, null, null); + BKUGUIFacade gui = new BKUGUIImpl(contentPane, null, BKUGUIFacade.Style.advanced, null, null, null); BKUGUIWorker worker = new BKUGUIWorker(); worker.init(gui); testFrame.pack(); |