summaryrefslogtreecommitdiff
path: root/BKUCommonGUI/src
diff options
context:
space:
mode:
authortzefferer <tzefferer@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-10-16 09:54:37 +0000
committertzefferer <tzefferer@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-10-16 09:54:37 +0000
commit4b8b858ddcab0bfbde80304a0f631233388a13d1 (patch)
tree7e39eb2039427a4d3771a6555753a316bd2c25eb /BKUCommonGUI/src
parent91b596dcba1e95e787134d22a776ea0cee815e57 (diff)
downloadmocca-4b8b858ddcab0bfbde80304a0f631233388a13d1.tar.gz
mocca-4b8b858ddcab0bfbde80304a0f631233388a13d1.tar.bz2
mocca-4b8b858ddcab0bfbde80304a0f631233388a13d1.zip
Keyboard accessibility for Online-BKU
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@528 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'BKUCommonGUI/src')
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java5
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java280
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpKeyListener.java46
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpLinkFocusManager.java138
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpViewer.java4
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java35
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusFocusListener.java38
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusListener.java44
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties2
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties2
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/help_focus.pngbin0 -> 343 bytes
-rw-r--r--BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUITest.java2
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
new file mode 100644
index 00000000..d650bea2
--- /dev/null
+++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/help_focus.png
Binary files differ
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();