From b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 5 May 2010 15:29:01 +0000 Subject: Merged feature branch mocca-1.2.13-id@r724 back to trunk. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@725 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- BKUCommonGUI/src/main/java/META-INF/MANIFEST.MF | 3 - .../at/gv/egiz/bku/gui/AbstractHelpListener.java | 103 - .../main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java | 22 +- .../main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java | 4160 +++++++++++++------- .../src/main/java/at/gv/egiz/bku/gui/BKUIcons.java | 17 +- .../java/at/gv/egiz/bku/gui/DeafHelpListener.java | 67 + .../at/gv/egiz/bku/gui/DefaultHelpListener.java | 81 - .../main/java/at/gv/egiz/bku/gui/FocusBorder.java | 69 + .../at/gv/egiz/bku/gui/HashDataTableModel.java | 12 +- .../java/at/gv/egiz/bku/gui/HelpKeyListener.java | 46 - .../main/java/at/gv/egiz/bku/gui/HelpListener.java | 84 + .../java/at/gv/egiz/bku/gui/HelpMouseListener.java | 54 - .../java/at/gv/egiz/bku/gui/HelpURLProvider.java | 33 + .../main/java/at/gv/egiz/bku/gui/HelpViewer.java | 13 +- .../java/at/gv/egiz/bku/gui/HyperlinkRenderer.java | 11 + .../main/java/at/gv/egiz/bku/gui/ImagePanel.java | 2 + .../at/gv/egiz/bku/gui/SecureViewerDialog.java | 139 +- .../gv/egiz/bku/gui/SwitchFocusFocusListener.java | 82 +- .../at/gv/egiz/bku/gui/SwitchFocusListener.java | 98 +- .../at/gv/egiz/bku/gui/ViewerHelpListener.java | 101 + .../at/gv/egiz/bku/gui/WindowCloseAdapter.java | 54 + .../egiz/bku/gui/html/RestrictedHTMLEditorKit.java | 3 +- .../egiz/bku/gui/viewer/FontProviderException.java | 2 + .../bku/gui/viewer/SecureViewerSaveDialog.java | 51 +- .../gv/egiz/stal/impl/ByteArrayHashDataInput.java | 8 +- .../at/gv/egiz/bku/gui/Messages.properties | 3 +- .../at/gv/egiz/bku/gui/Messages_en.properties | 4 +- 27 files changed, 3339 insertions(+), 1983 deletions(-) delete mode 100644 BKUCommonGUI/src/main/java/META-INF/MANIFEST.MF delete mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/AbstractHelpListener.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DeafHelpListener.java delete mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DefaultHelpListener.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/FocusBorder.java delete mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpKeyListener.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpListener.java delete mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpMouseListener.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpURLProvider.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ViewerHelpListener.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/WindowCloseAdapter.java (limited to 'BKUCommonGUI/src/main') diff --git a/BKUCommonGUI/src/main/java/META-INF/MANIFEST.MF b/BKUCommonGUI/src/main/java/META-INF/MANIFEST.MF deleted file mode 100644 index 5e949512..00000000 --- a/BKUCommonGUI/src/main/java/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Class-Path: - diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/AbstractHelpListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/AbstractHelpListener.java deleted file mode 100644 index 6fd1ffea..00000000 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/AbstractHelpListener.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package at.gv.egiz.bku.gui; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Locale; -import java.util.ResourceBundle; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Implement the showDocument(URL) method to provide an actual HelpListener. - * This class does not keep a GUI reference and subclasses should not interfere with the GUI. - * Therefore, any errors occurring in showDocument() should be handled/displayed within - * showDocument() and exceptions thrown from showDocument() are logged, not displayed in the GUI. - *
- * The help URL is build as [baseURL]/[locale]/[helpTopic].html - * (note that no session information is contained). - * - * @author Clemens Orthacker - */ -public abstract class AbstractHelpListener implements ActionListener { - - /** - * any locale not in the list will be mapped to 'de' - */ - public static final String[] SUPPORTED_LANGUAGES = new String[] { "de" }; - - protected final static Log log = LogFactory.getLog(AbstractHelpListener.class); - protected URL baseURL; - protected Locale locale; - protected ResourceBundle messages; - - public AbstractHelpListener(URL baseURL, Locale locale) { - if (baseURL == null || "".equals(baseURL.toString())) { - throw new RuntimeException("no help URL provided"); - } - this.baseURL = baseURL; - this.locale = locale; - if (locale != null) { - messages = ResourceBundle.getBundle(BKUGUIFacade.MESSAGES_BUNDLE, locale); - } else { - messages = ResourceBundle.getBundle(BKUGUIFacade.MESSAGES_BUNDLE); - } - } - - @Override - public void actionPerformed(ActionEvent e) { - log.debug("received help action: " + e.getActionCommand()); - URL helpURL = constructHelpURL(baseURL, e.getActionCommand()); - try { - showDocument(helpURL, e.getActionCommand()); - } catch (Exception ex) { - log.error("could not display help document " + helpURL + ": " + ex.getMessage()); - } - } - - private URL constructHelpURL(URL baseURL, String helpTopic) { - URL helpURL = baseURL; - log.trace("constructing help URL: " + helpURL); - try { - // not localized for now - //check if locale.getLanguage() supported and add default if not -// if (locale != null) { -// helpURL = new URL(helpURL, locale.toString() + "/"); -// log.trace("constructing help URL: " + helpURL); -// } - if (helpTopic != null && !"".equals(helpTopic)) { - helpURL = new URL(helpURL, "de/" + helpTopic + ".html"); - log.trace("constructing help URL: " + helpURL); - } - } catch (MalformedURLException ex) { - log.error("Failed to construct help URL for help item " + helpTopic + ": " + ex.getMessage()); - } - return helpURL; - } - - /** - * Errors from HelpListeners should not (are not) displayed in the applet, - * but should rather be in the HelpListener specific way. - * Therefore, implementations SHOULD NOT throw exceptions (these are only logged). - * @param helpDocument - * @throws java.lang.Exception - */ - public abstract void showDocument(URL helpDocument, String helpTopic) throws Exception; -} 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 1e23c64c..b7ab156f 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 @@ -17,7 +17,7 @@ package at.gv.egiz.bku.gui; import at.gv.egiz.stal.HashDataInput; -import at.gv.egiz.smcc.PINSpec; +import at.gv.egiz.smcc.PinInfo; import java.awt.Color; import java.awt.event.ActionListener; import java.util.List; @@ -46,10 +46,14 @@ 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_L = "/at/gv/egiz/bku/gui/help_l.png"; + public static final String HELP_IMG_XL = "/at/gv/egiz/bku/gui/help_xl.png"; + public static final String HELP_IMG_XXL = "/at/gv/egiz/bku/gui/help_xxl.png"; public static final String HELP_IMG_FOCUS = "/at/gv/egiz/bku/gui/help.png"; //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; + public static final Color HELP_COLOR = new Color(70, 148, 169); public static final String TITLE_WELCOME = "title.welcome"; public static final String TITLE_INSERTCARD = "title.insertcard"; public static final String TITLE_CARD_NOT_SUPPORTED = "title.cardnotsupported"; @@ -114,11 +118,17 @@ public interface BKUGUIFacade { public static final String SAVE_HASHDATAINPUT_PREFIX = "save.hashdatainput.prefix"; public static final String ALT_HELP = "alt.help"; - public void showEnterPINDirect(PINSpec spec, int retries); + public static final String SIGDATA_TOOLTIPTEXT = "dialog.sigpin.infolabel.sigdata.tooltiptext"; + public static final String SWITCH_FOCUS_DUMMY_LABEL_NAME = "DummyLabel"; + + public enum DIALOG_TYPE {DIALOGUE_UNDEFINED, DIALOGUE_VERIFY_PIN, DIALOGUE_ENTER_PIN, DIALOGUE_SHOW_SIG_DATA, DIALOGUE_SIGNATURE_PIN, DIALOGUE_MESSAGE}; + + + public void showEnterPINDirect(PinInfo pinInfo, int retries); - public void showEnterPIN(PINSpec spec, int retries); + public void showEnterPIN(PinInfo pinInfo, int retries); - public void showSignatureDataDialog(PINSpec spec, ActionListener listener, String string, ActionListener aThis0, String string0, ActionListener aThis1, String string1); + public void showSignatureDataDialog(PinInfo pinInfo, ActionListener listener, String string, ActionListener aThis0, String string0, ActionListener aThis1, String string1); public void correctionButtonPressed(); @@ -134,11 +144,11 @@ public interface BKUGUIFacade { */ public Locale getLocale(); - public void showVerifyPINDialog(PINSpec pinSpec, int numRetries, + public void showVerifyPINDialog(PinInfo pinSpec, int numRetries, ActionListener okListener, String okCommand, ActionListener cancelListener, String cancelCommand); - public void showSignaturePINDialog(PINSpec pinSpec, int numRetries, + public void showSignaturePINDialog(PinInfo pinSpec, int numRetries, ActionListener signListener, String signCommand, ActionListener cancelListener, String cancelCommand, ActionListener viewerListener, String viewerCommand); 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 e005836c..d806c5fa 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 @@ -20,15 +20,19 @@ package at.gv.egiz.bku.gui; import at.gv.egiz.bku.gui.viewer.FontProviderException; import at.gv.egiz.bku.gui.viewer.FontProvider; import at.gv.egiz.bku.gui.viewer.SecureViewerSaveDialog; -import at.gv.egiz.smcc.PINSpec; +import at.gv.egiz.smcc.PinInfo; import at.gv.egiz.stal.HashDataInput; import java.awt.Color; +import java.awt.Component; import java.awt.Container; import java.awt.Cursor; +import java.awt.FocusTraversalPolicy; import java.awt.Font; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; @@ -36,16 +40,19 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URL; import java.text.MessageFormat; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; -import java.util.logging.Level; -import java.util.logging.Logger; + +import javax.swing.BorderFactory; import javax.swing.GroupLayout; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; @@ -59,1607 +66,2730 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.text.BadLocationException; import javax.swing.text.Document; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * + * * @author clemens */ public class BKUGUIImpl implements BKUGUIFacade { - - protected static final Log log = LogFactory.getLog(BKUGUIImpl.class); - protected enum PinLabelPosition { - LEFT, ABOVE - } + private final Logger log = LoggerFactory.getLogger(BKUGUIImpl.class); - protected HelpMouseListener helpMouseListener; - protected HelpKeyListener helpKeyListener; - protected SwitchFocusFocusListener switchFocusKeyListener; - protected SecureViewerDialog secureViewer; - protected FontProvider fontProvider; - - protected Container contentPane; - protected ResourceBundle messages; - /** left and right side main panels */ - protected JPanel iconPanel; - protected JPanel contentPanel; - /** right side content panels and layouts */ - protected JPanel headerPanel; - protected JPanel mainPanel; - protected JPanel buttonPanel; - /** right side fixed labels */ - protected JLabel titleLabel; - protected JLabel helpLabel; - protected JLabel switchFocusDummyLabel; - /** remember the pinfield to return to worker */ - protected JPasswordField pinField; - protected Document pinpadPIN; - - protected int buttonSize; - - /** gui style config (default 'simple') */ - protected boolean renderHeaderPanel = false; - protected boolean renderIconPanel = false; - protected boolean renderCancelButton = false; - protected boolean shortText = false; - protected PinLabelPosition pinLabelPos = PinLabelPosition.LEFT; - protected boolean renderRefId = false; - - /** - * set contentPane - * init message bundle - * configure the style - * register the help listener - * create GUI (on event-dispatching thread) - * - * @param contentPane - * @param locale - * @param guiStyle - * @param background - * @param helpListener - */ - public BKUGUIImpl(Container contentPane, - Locale locale, - Style guiStyle, - URL background, - FontProvider fontProvider, - ActionListener helpListener, - SwitchFocusListener switchFocusListener) { - this.contentPane = contentPane; - - loadMessageBundle(locale); - - if (guiStyle == Style.advanced) { - renderHeaderPanel = true; - renderIconPanel = false; - renderCancelButton = true; - renderRefId = true; - } else if (guiStyle == Style.tiny) { - shortText = true; - pinLabelPos = PinLabelPosition.ABOVE; - } - - // ensure that buttons can be fired with enter key too - UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); - - registerHelpListener(helpListener); - - registerSwitchFocusListener(switchFocusListener); - - this.fontProvider = fontProvider; - createGUI(background); - } - - private void createGUI(final URL background) { - - try { - - log.debug("scheduling gui initialization"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("[" + Thread.currentThread().getName() + "] initializing gui"); - - if (renderIconPanel) { - initIconPanel(background); - initContentPanel(null); - } else { - initContentPanel(background); - } - - GroupLayout layout = new GroupLayout(contentPane); - contentPane.setLayout(layout); - - if (renderIconPanel) { - layout.setHorizontalGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(iconPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(contentPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()); - layout.setVerticalGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(iconPanel, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(contentPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()); - } else { - layout.setHorizontalGroup(layout.createSequentialGroup() - // left border - .addContainerGap() - .addComponent(contentPanel) - .addContainerGap()); - layout.setVerticalGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(contentPanel) - .addContainerGap()); - } - } - }); - } catch (Exception ex) { - throw new RuntimeException("Failed to init GUI: " + ex.getMessage()); - } - } - - protected void initIconPanel(URL background) { - if (background == null) { - background = getClass().getResource(DEFAULT_ICON); - } - if ("file".equals(background.getProtocol())) { - log.warn("file:// background images not permitted: " + background + - ", loading default background"); - background = getClass().getResource(DEFAULT_ICON); - } - log.debug("loading icon panel background " + background); - - iconPanel = new JPanel(); - JLabel iconLabel = new JLabel(); - iconLabel.setIcon(new ImageIcon(background)); - - GroupLayout iconPanelLayout = new GroupLayout(iconPanel); - iconPanel.setLayout(iconPanelLayout); - iconPanelLayout.setHorizontalGroup( - iconPanelLayout.createSequentialGroup() - .addComponent(iconLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)); - iconPanelLayout.setVerticalGroup( - iconPanelLayout.createSequentialGroup() - .addComponent(iconLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)); - } + protected enum PinLabelPosition { + LEFT, ABOVE + } - protected void initContentPanel(URL background) { - - if (background == null) { - log.debug("no background image set"); -// contentPanel = new ImagePanel(getClass().getResource(DEFAULT_BACKGROUND)); - contentPanel = new JPanel(); - } else if ("file".equals(background.getProtocol())) { - log.warn("file:// background images not permitted: " + background); - contentPanel = new JPanel(); - } else { - log.debug("loading background " + background); - contentPanel = new ImagePanel(background); - } - contentPanel.setOpaque(false); - mainPanel = new JPanel(); - 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.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(); - - if (renderHeaderPanel) { - headerPanel = new JPanel(); - headerPanel.setOpaque(false); - - titleLabel = new JLabel(); - titleLabel.setFont(titleLabel.getFont().deriveFont(titleLabel.getFont().getStyle() | - java.awt.Font.BOLD, titleLabel.getFont().getSize() + 2)); - - GroupLayout headerPanelLayout = new GroupLayout(headerPanel); - headerPanel.setLayout(headerPanelLayout); - - headerPanelLayout.setHorizontalGroup( - headerPanelLayout.createSequentialGroup() - .addComponent(titleLabel, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ); - headerPanelLayout.setVerticalGroup( - headerPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(titleLabel, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ); - } - - GroupLayout contentPanelLayout = new GroupLayout(contentPanel); - contentPanel.setLayout(contentPanelLayout); - - // align header, main and button to the right - GroupLayout.ParallelGroup horizontalContent = - contentPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING); //LEADING); - GroupLayout.SequentialGroup verticalContent = - contentPanelLayout.createSequentialGroup(); - - if (renderHeaderPanel) { - horizontalContent - .addComponent(headerPanel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE); - verticalContent - .addComponent(headerPanel, 0, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); - - } - horizontalContent - .addComponent(mainPanel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonPanel, 0, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); //Short.MAX_VALUE); - verticalContent - .addComponent(mainPanel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(buttonPanel, 0, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - - contentPanelLayout.setHorizontalGroup(horizontalContent); //Outer); - contentPanelLayout.setVerticalGroup(verticalContent); + protected Component primaryFocusHolder; + protected SecureViewerDialog secureViewer; + + protected HelpListener helpListener; + protected SwitchFocusFocusListener switchFocusKeyListener; + protected FontProvider fontProvider; + + protected Container contentPane; + protected WindowCloseAdapter windowCloseAdapter; + protected ResourceBundle messages; + /** left and right side main panels */ + protected JPanel iconPanel; + protected JPanel contentPanel; + /** right side content panels and layouts */ + protected JPanel headerPanel; + protected JPanel mainPanel; + protected JPanel buttonPanel; + /** right side fixed labels */ + protected JLabel titleLabel; + protected JLabel msgTitleLabel; + protected JLabel helpLabel; + protected JLabel switchFocusDummyLabel; + /** remember the pinfield to return to worker */ + protected JPasswordField pinField; + protected Document pinpadPIN; + + protected JButton okButton; + protected JButton backButton; + protected JButton enterPINButton; + protected final JButton cancelButton; + protected JLabel infoLabel; + protected final JLabel pinsizeLabel; + protected final JLabel signPinLabel; + protected final JButton signButton; + protected JLabel cardPinLabel; + protected JLabel pinLabel; + protected JPasswordField pinpadPINField; + protected JLabel msgLabel; + protected boolean showMessageOKButton; + protected JLabel refIdLabel; + protected JScrollPane hashDataScrollPane; + protected JTable hashDataTable; + protected HyperlinkRenderer hyperlinkRenderer; + protected int baseTableRowHeight; + + protected FocusBorder sigDataFocusBorder; + protected FocusBorder helpFocusBorder; + + protected Method methodToRunAtResize; + + protected int buttonSize; + protected int baseButtonSize; + protected Integer baseWidth; + protected Integer baseHeight; + protected int baseFontSize; + + /** gui style config (default 'simple') */ + protected boolean renderHeaderPanel = false; + protected boolean renderIconPanel = false; + protected boolean renderCancelButton = false; + protected boolean shortText = false; + protected PinLabelPosition pinLabelPos = PinLabelPosition.LEFT; + protected boolean renderRefId = false; + protected boolean useFocusTraversalPolicy = false; + +// protected HashDataInput storedSelection; + protected List signedReferences; + protected Integer referenceIndex; + private at.gv.egiz.bku.gui.BKUGUIImpl.SignedReferencesSelectionListener.SignedReferencesListDisplayer storedBackToListListener; + + /** + * set contentPane init message bundle configure the style register the help + * listener create GUI (on event-dispatching thread) + * + * @param contentPane + * @param locale + * @param guiStyle + * @param background + * @param helpListener + */ + public BKUGUIImpl(Container contentPane, Locale locale, Style guiStyle, + URL background, FontProvider fontProvider, + HelpListener helpListener, SwitchFocusListener switchFocusListener) { + this.contentPane = contentPane; + Window w = SwingUtilities.getWindowAncestor(contentPane); + if (w != null && w instanceof JFrame) { + this.windowCloseAdapter = new WindowCloseAdapter(); + ((JFrame) w).addWindowListener(windowCloseAdapter); } + + loadMessageBundle(locale); + + cancelButton = new JButton(); + infoLabel = new JLabel(); + cardPinLabel = new JLabel(); + pinsizeLabel = new JLabel(); + signPinLabel = new JLabel(); + signButton = new JButton(); + pinLabel = new JLabel(); + pinpadPINField = new JPasswordField(); + msgLabel = new JLabel(); + showMessageOKButton = false; + + this.baseFontSize = new JLabel().getFont().getSize(); + this.baseTableRowHeight = new JTable().getRowHeight(); + + if (guiStyle == Style.advanced) { + renderHeaderPanel = true; + renderIconPanel = false; + renderCancelButton = true; + renderRefId = true; + useFocusTraversalPolicy = true; + } else if (guiStyle == Style.tiny) { + shortText = true; + pinLabelPos = PinLabelPosition.ABOVE; + } + + // ensure that buttons can be fired with enter key too + UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); + + registerSwitchFocusListener(switchFocusListener); + + this.fontProvider = fontProvider; + this.helpListener = helpListener; + createGUI(background); - /** - * BKUWorker inits signaturecard with locale - * @return - */ - @Override - public Locale getLocale() { - return messages.getLocale(); - } + } - /** - * to be overridden by subclasses providing additional resource messages - * @param key - * @return - */ - protected String getMessage(String key) { - return messages.getString(key); - } + private void createGUI(final URL background) { + + try { + + log.debug("Scheduling gui initialization."); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("[{}] Initializing gui.", Thread.currentThread().getName()); + + if (renderIconPanel) { + initIconPanel(background); + initContentPanel(null); + } else { + initContentPanel(background); + } + + contentPanel.addComponentListener(new ComponentAdapter() { + + @Override + public void componentResized(ComponentEvent e) { + + log.debug("Component resize detected."); + + resize(); + } + + }); + + GroupLayout layout = new GroupLayout(contentPane); + contentPane.setLayout(layout); + + if (renderIconPanel) { + layout + .setHorizontalGroup(layout + .createSequentialGroup() + .addContainerGap() + .addComponent(iconPanel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(contentPanel, + GroupLayout.DEFAULT_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE) + .addContainerGap()); + layout + .setVerticalGroup(layout + .createSequentialGroup() + .addContainerGap() + .addGroup( + layout + .createParallelGroup( + GroupLayout.Alignment.LEADING) + .addComponent( + iconPanel, + GroupLayout.Alignment.TRAILING, + GroupLayout.DEFAULT_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE) + .addComponent( + contentPanel, + GroupLayout.DEFAULT_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)) + .addContainerGap()); + } else { + layout.setHorizontalGroup(layout + .createSequentialGroup() + // left border + .addContainerGap().addComponent(contentPanel) + .addContainerGap()); + layout.setVerticalGroup(layout.createSequentialGroup() + .addContainerGap().addComponent(contentPanel) + .addContainerGap()); + } + } + }); + + } catch (Exception ex) { + throw new RuntimeException("Failed to init GUI: " + ex.getMessage()); + } + } - /** - * to be overridden by subclasses providing additional resource messages - * @param key - * @return - */ - protected boolean hasMessage(String key) { - return messages.containsKey(key); - } + protected void initIconPanel(URL background) { + if (background == null) { + background = getClass().getResource(DEFAULT_ICON); + } + if ("file".equals(background.getProtocol())) { + log.warn("file:// background images not permitted: {}, " + + "loading default background", background); + background = getClass().getResource(DEFAULT_ICON); + } + log.debug("Loading icon panel background {}.", background); + + iconPanel = new JPanel(); + JLabel iconLabel = new JLabel(); + iconLabel.setIcon(new ImageIcon(background)); + + GroupLayout iconPanelLayout = new GroupLayout(iconPanel); + iconPanel.setLayout(iconPanelLayout); + iconPanelLayout.setHorizontalGroup(iconPanelLayout + .createSequentialGroup().addComponent(iconLabel, + GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE)); + iconPanelLayout.setVerticalGroup(iconPanelLayout + .createSequentialGroup().addComponent(iconLabel, + GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE)); + } + + protected void initContentPanel(URL background) { + + if (background == null) { + log.debug("No background image set."); + // contentPanel = new + // ImagePanel(getClass().getResource(DEFAULT_BACKGROUND)); + contentPanel = new JPanel(); + } else if ("file".equals(background.getProtocol())) { + log.warn("file:// background images not permitted: {}.", background); + contentPanel = new JPanel(); + } else { + log.debug("Loading background {}.", background); + contentPanel = new ImagePanel(background); + } + contentPanel.setOpaque(false); + mainPanel = new JPanel(); + mainPanel.setOpaque(false); + buttonPanel = new JPanel(); + buttonPanel.setOpaque(false); + + okButton = new JButton(); + backButton = new JButton(); + enterPINButton = new JButton(); + + sigDataFocusBorder = new FocusBorder(HYPERLINK_COLOR); + helpFocusBorder = new FocusBorder(HELP_COLOR); + + if (helpListener.implementsListener()) { + helpLabel = new JLabel(); + helpLabel.setIcon(new ImageIcon(getClass().getResource(HELP_IMG))); + helpLabel.getAccessibleContext().setAccessibleName( + getMessage(ALT_HELP)); + helpLabel.setFocusable(true); + helpLabel.addMouseListener(helpListener); + helpLabel.addKeyListener(helpListener); + helpLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + log.debug("Help label obtained focus."); + updateHelpLabelIcon(); + } + + @Override + public void focusLost(FocusEvent e) { + + updateHelpLabelIcon(); + } + + }); + helpLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + // This is a hidden label. When it gains focus, it hands over focus to + // the web browser + switchFocusDummyLabel = new JLabel(); + switchFocusDummyLabel.setText(""); + switchFocusDummyLabel.setName(SWITCH_FOCUS_DUMMY_LABEL_NAME); + switchFocusDummyLabel.setFocusable(true); + switchFocusDummyLabel.addFocusListener(switchFocusKeyListener); + + buttonSize = initButtonSize(); + baseButtonSize = buttonSize; + + titleLabel = new JLabel(); + msgTitleLabel = new JLabel(); + + if (renderHeaderPanel) { + headerPanel = new JPanel(); + headerPanel.setOpaque(false); + + titleLabel.setFocusable(true); + titleLabel.setFont(titleLabel.getFont().deriveFont( + titleLabel.getFont().getStyle() | java.awt.Font.BOLD, + titleLabel.getFont().getSize() + 2)); + + GroupLayout headerPanelLayout = new GroupLayout(headerPanel); + headerPanel.setLayout(headerPanelLayout); + + GroupLayout.SequentialGroup horizontalHeader = headerPanelLayout + .createSequentialGroup().addComponent(titleLabel, 0, + GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE); + + GroupLayout.ParallelGroup verticalHeader = headerPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(titleLabel, 0, GroupLayout.PREFERRED_SIZE, + Short.MAX_VALUE); + + if (helpListener.implementsListener()) { + horizontalHeader.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + verticalHeader.addComponent(helpLabel); + } + + horizontalHeader.addComponent(switchFocusDummyLabel); + verticalHeader.addComponent(switchFocusDummyLabel); + + headerPanelLayout.setHorizontalGroup(horizontalHeader); + headerPanelLayout.setVerticalGroup(verticalHeader); + } + + GroupLayout contentPanelLayout = new GroupLayout(contentPanel); + contentPanel.setLayout(contentPanelLayout); + + // align header, main and button to the right + GroupLayout.ParallelGroup horizontalContent = contentPanelLayout + .createParallelGroup(GroupLayout.Alignment.TRAILING); // LEADING); + GroupLayout.SequentialGroup verticalContent = contentPanelLayout + .createSequentialGroup(); + + if (renderHeaderPanel) { + horizontalContent.addComponent(headerPanel, 0, + GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE); + verticalContent.addComponent(headerPanel, 0, + GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); + + } + horizontalContent.addComponent(mainPanel, 0, GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE).addComponent(buttonPanel, 0, + GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); // Short.MAX_VALUE); + verticalContent.addComponent(mainPanel, 0, GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE).addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED).addComponent( + buttonPanel, 0, GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + + contentPanelLayout.setHorizontalGroup(horizontalContent); // Outer); + contentPanelLayout.setVerticalGroup(verticalContent); + + } + + /** + * BKUWorker inits signaturecard with locale + * + * @return + */ + @Override + public Locale getLocale() { + return messages.getLocale(); + } + + /** + * to be overridden by subclasses providing additional resource messages + * + * @param key + * @return + */ + protected String getMessage(String key) { + return messages.getString(key); + } + + /** + * to be overridden by subclasses providing additional resource messages + * + * @param key + * @return + */ + protected boolean hasMessage(String key) { + return messages.containsKey(key); + } @Override - public void showVerifyPINDialog(final PINSpec pinSpec, final int numRetries, + public void showVerifyPINDialog(final PinInfo pinSpec, final int numRetries, final ActionListener okListener, final String okCommand, final ActionListener cancelListener, final String cancelCommand) { - - log.debug("scheduling verify pin dialog"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("[" + Thread.currentThread().getName() + "] show verify pin dialog"); - - mainPanel.removeAll(); - buttonPanel.removeAll(); - - if (renderHeaderPanel) { - if (numRetries < 0) { - String verifyTitle = getMessage(TITLE_VERIFY_PIN); - titleLabel.setText(MessageFormat.format(verifyTitle, new Object[]{pinSpec.getLocalizedName()})); - } else { - titleLabel.setText(getMessage(TITLE_RETRY)); - } - } - - JButton okButton = new JButton(); - okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - okButton.setText(getMessage(BUTTON_OK)); - okButton.setEnabled(pinSpec.getMinLength() <= 0); - okButton.setActionCommand(okCommand); - okButton.addActionListener(okListener); - - JLabel cardPinLabel = new JLabel(); - cardPinLabel.setFont(cardPinLabel.getFont().deriveFont(cardPinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - String pinLabel = getMessage(LABEL_PIN); - cardPinLabel.setText(MessageFormat.format(pinLabel, new Object[]{pinSpec.getLocalizedName()})); - - pinField = new JPasswordField(); - pinField.setText(""); - pinField.setDocument(new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), okButton)); - pinField.setActionCommand(okCommand); - pinField.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (pinField.getPassword().length >= pinSpec.getMinLength()) { - okListener.actionPerformed(e); - } - } - }); - - JLabel infoLabel = new JLabel(); - if (numRetries < 0) { - infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - String infoPattern = getMessage(MESSAGE_ENTERPIN); - if (shortText) { - infoLabel.setText(MessageFormat.format(infoPattern, new Object[] {"PIN"})); - } else { - infoLabel.setText(MessageFormat.format(infoPattern, new Object[] {pinSpec.getLocalizedName()})); - } - helpMouseListener.setHelpTopic(HELP_VERIFY_PIN); - helpKeyListener.setHelpTopic(HELP_VERIFY_PIN); - } else { - String retryPattern; - if (numRetries < 2) { - retryPattern = getMessage(MESSAGE_LAST_RETRY); - } else { - retryPattern = getMessage(MESSAGE_RETRIES); - } - 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); - helpMouseListener.setHelpTopic(HELP_RETRY); - helpKeyListener.setHelpTopic(HELP_RETRY); - } - - 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())); - - GroupLayout mainPanelLayout = new GroupLayout(mainPanel); - mainPanel.setLayout(mainPanelLayout); - - GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup() - .addComponent(infoLabel); - GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(infoLabel); - - if (!renderHeaderPanel) { - infoHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - infoVertical - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - } - - // align pinfield and pinsize to the right - GroupLayout.ParallelGroup pinHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING); - GroupLayout.Group pinVertical; - - if (pinLabelPos == PinLabelPosition.ABOVE) { - pinHorizontal - .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(cardPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - pinVertical = mainPanelLayout.createSequentialGroup() - .addComponent(cardPinLabel) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - } else { - pinHorizontal - .addGroup(mainPanelLayout.createSequentialGroup() - .addComponent(cardPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - pinVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(cardPinLabel) - .addComponent(pinField); - } - - mainPanelLayout.setHorizontalGroup( - mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(infoHorizontal) - .addGroup(pinHorizontal)); - - mainPanelLayout.setVerticalGroup( - mainPanelLayout.createSequentialGroup() - .addGroup(infoVertical) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pinVertical) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinsizeLabel)); - - - GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); - buttonPanel.setLayout(buttonPanelLayout); - - GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout.createSequentialGroup() - .addComponent(okButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE); - GroupLayout.Group buttonVertical; - - if (renderCancelButton) { - JButton cancelButton = new JButton(); - cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - cancelButton.setText(getMessage(BUTTON_CANCEL)); - cancelButton.setActionCommand(cancelCommand); - cancelButton.addActionListener(cancelListener); - - buttonHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE); - buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(okButton) - .addComponent(cancelButton); - } else { - buttonVertical = buttonPanelLayout.createSequentialGroup() - .addComponent(okButton); - } - - buttonPanelLayout.setHorizontalGroup(buttonHorizontal); - buttonPanelLayout.setVerticalGroup(buttonVertical); - -// pinField.requestFocusInWindow(); -// helpLabel.requestFocus(); - pinField.requestFocus(); - contentPanel.validate(); - - } - }); - } - @Override - public void showEnterPINDirect(PINSpec pinSpec, int retries) { - if (retries < 0) { - showMessageDialog(TITLE_VERIFY_PINPAD, MESSAGE_ENTERPIN_PINPAD_DIRECT, new Object[] { - pinSpec.getLocalizedName(), pinSpec.getLocalizedLength() }); - } else { - showMessageDialog(TITLE_RETRY, MESSAGE_RETRIES, new Object[]{String.valueOf(retries) }); - } - } + log.debug("Scheduling verify pin dialog."); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("[{}] Show verify pin dialog.", Thread.currentThread() + .getName()); + + mainPanel.removeAll(); + buttonPanel.removeAll(); + + // avoid that dummy label gains focus during load + switchFocusDummyLabel.setFocusable(false); + + if (renderHeaderPanel) { + if (numRetries < 0) { + String verifyTitle = getMessage(TITLE_VERIFY_PIN); + titleLabel.setText(MessageFormat.format(verifyTitle, + new Object[] { pinSpec.getLocalizedName() })); + } else { + titleLabel.setText(getMessage(TITLE_RETRY)); + } + } + + okButton.setFont(okButton.getFont().deriveFont( + okButton.getFont().getStyle() & ~java.awt.Font.BOLD)); + okButton.setText(getMessage(BUTTON_OK)); + okButton.setEnabled(pinSpec.getMinLength() <= 0); + okButton.setActionCommand(okCommand); + okButton.addActionListener(okListener); + + cardPinLabel.setFont(cardPinLabel.getFont() + .deriveFont( + cardPinLabel.getFont().getStyle() + & ~java.awt.Font.BOLD)); + String pinLabel = getMessage(LABEL_PIN); + cardPinLabel.setText(MessageFormat.format(pinLabel, + new Object[] { pinSpec.getLocalizedName() })); + + pinField = new JPasswordField(); + pinField.setText(""); + pinField.setName("PINField"); + pinField.setDocument(new PINDocument(pinSpec.getMinLength(), + pinSpec.getMaxLength(), pinSpec.getRexepPattern(), + okButton)); + pinField.setActionCommand(okCommand); + pinField.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (pinField.getPassword().length >= pinSpec + .getMinLength()) { + okListener.actionPerformed(e); + } + } + }); + + pinField.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + // focus has been set accordingly - re-enable dummy + // label + switchFocusDummyLabel.setFocusable(true); + } + + }); + + infoLabel = new JLabel(); + if (numRetries < 0) { + infoLabel.setFont(infoLabel.getFont().deriveFont( + infoLabel.getFont().getStyle() + & ~java.awt.Font.BOLD)); + String infoPattern = getMessage(MESSAGE_ENTERPIN); + if (shortText) { + infoLabel.setText(MessageFormat.format(infoPattern, + new Object[] { "PIN" })); + } else { + infoLabel.setText(MessageFormat.format(infoPattern, + new Object[] { pinSpec.getLocalizedName() })); + } + helpListener.setHelpTopic(HELP_VERIFY_PIN); + } else { + String retryPattern; + if (numRetries < 2) { + retryPattern = getMessage(MESSAGE_LAST_RETRY); + } else { + retryPattern = getMessage(MESSAGE_RETRIES); + } + 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); + } + + 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())); + + pinField.getAccessibleContext().setAccessibleDescription( + cardPinLabel.getText() + pinsizeLabel.getText()); + + GroupLayout mainPanelLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + + GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout + .createSequentialGroup().addComponent(infoLabel); + GroupLayout.ParallelGroup infoVertical = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(infoLabel); + + if (!renderHeaderPanel) { + + if (helpListener.implementsListener()) { + infoHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + infoVertical.addComponent(helpLabel); + } + infoHorizontal.addComponent(switchFocusDummyLabel); + infoVertical.addComponent(switchFocusDummyLabel); + } + + // align pinfield and pinsize to the right + GroupLayout.ParallelGroup pinHorizontal = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.TRAILING); + GroupLayout.Group pinVertical; + + if (pinLabelPos == PinLabelPosition.ABOVE) { + pinHorizontal.addGroup( + mainPanelLayout.createParallelGroup( + GroupLayout.Alignment.LEADING) + .addComponent(cardPinLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addComponent(pinField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)).addComponent( + pinsizeLabel, GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + pinVertical = mainPanelLayout.createSequentialGroup() + .addComponent(cardPinLabel).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinField, GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + } else { + pinHorizontal + .addGroup( + mainPanelLayout + .createSequentialGroup() + .addComponent(cardPinLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)) + .addComponent(pinsizeLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + pinVertical = mainPanelLayout.createParallelGroup( + GroupLayout.Alignment.BASELINE).addComponent( + cardPinLabel).addComponent(pinField); + } + + mainPanelLayout.setHorizontalGroup(mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(infoHorizontal).addGroup(pinHorizontal)); + + mainPanelLayout + .setVerticalGroup(mainPanelLayout + .createSequentialGroup().addGroup(infoVertical) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pinVertical).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinsizeLabel)); + + if (renderCancelButton) { + cancelButton.setFont(cancelButton.getFont().deriveFont( + cancelButton.getFont().getStyle() + & ~java.awt.Font.BOLD)); + cancelButton.setText(getMessage(BUTTON_CANCEL)); + cancelButton.setActionCommand(cancelCommand); + cancelButton.addActionListener(cancelListener); + } + + renderVerifyPINDialogueButtonPanel(); + + updateMethodToRunAtResize("at.gv.egiz.bku.gui.BKUGUIImpl", + "renderVerifyPINDialogueButtonPanel"); + + if (windowCloseAdapter != null) { + windowCloseAdapter.registerListener(cancelListener, cancelCommand); + } - @Override - public void showEnterPIN(final PINSpec pinSpec, final int retries) { - showEnterPIN(pinSpec, retries, TITLE_VERIFY_PINPAD, MESSAGE_ENTERPIN_PINPAD, null); - } + primaryFocusHolder = pinField; + + pinField.requestFocus(); + contentPanel.validate(); + + resize(); - protected void showEnterPIN(final PINSpec pinSpec, final int retries, final String titleKey, final String messageKey, final Object[] messageParams) { - log.debug("scheduling pinpad dialog"); + } + }); + } - SwingUtilities.invokeLater(new Runnable() { + @SuppressWarnings("unchecked") + protected void updateMethodToRunAtResize(String className, String methodName) { + + try { + Class thisClass = (Class) Class + .forName(className); + Method m = thisClass.getMethod(methodName); + methodToRunAtResize = m; + } catch (SecurityException e1) { + log.error("Unable to store rendering method.", e1); + } catch (NoSuchMethodException e1) { + log.error("Unable to store rendering method.", e1); + } catch (ClassNotFoundException e) { + log.error("Unable to store rendering method.", e); + } - @Override - public void run() { + } - log.debug("[" + Thread.currentThread().getName() + "] show pinpad dialog"); + public void renderVerifyPINDialogueButtonPanel() { - mainPanel.removeAll(); - buttonPanel.removeAll(); + GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); + buttonPanel.setLayout(buttonPanelLayout); - if (renderHeaderPanel) { - if (retries < 0) { - titleLabel.setText(getMessage(titleKey)); - } else { - titleLabel.setText(getMessage(TITLE_RETRY)); - } - } + GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout + .createSequentialGroup().addComponent(okButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE); + GroupLayout.Group buttonVertical; - final JLabel infoLabel = new JLabel(); - if (retries < 0) { - infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - infoLabel.setText(MessageFormat.format(getMessage(messageKey), messageParams)); - helpMouseListener.setHelpTopic(HELP_PINPAD); - helpKeyListener.setHelpTopic(HELP_PINPAD); - } else { - String retryPattern; - if (retries == 1) { - retryPattern = getMessage(MESSAGE_LAST_RETRY); - } else { - retryPattern = getMessage(MESSAGE_RETRIES); - } - infoLabel.setText(MessageFormat.format(retryPattern, new Object[]{String.valueOf(retries)})); - infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() | java.awt.Font.BOLD)); - infoLabel.setForeground(ERROR_COLOR); - helpMouseListener.setHelpTopic(HELP_RETRY); - helpKeyListener.setHelpTopic(HELP_RETRY); - } + if (renderCancelButton) { - JLabel pinLabel = new JLabel(); - pinLabel.setFont(pinLabel.getFont().deriveFont(pinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - String pinName = getMessage(LABEL_PIN); - pinLabel.setText(MessageFormat.format(pinName, new Object[]{pinSpec.getLocalizedName()})); - - JPasswordField pinpadPINField = new JPasswordField(); - pinpadPINField.setText(""); - pinpadPINField.setEnabled(false); - pinpadPIN = pinpadPINField.getDocument(); - - 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())); - - GroupLayout mainPanelLayout = new GroupLayout(mainPanel); - mainPanel.setLayout(mainPanelLayout); - - GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup() - .addComponent(infoLabel); - GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(infoLabel); - - if (!renderHeaderPanel) { - infoHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - infoVertical - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - } + buttonHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED).addComponent( + cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE); + buttonVertical = buttonPanelLayout.createParallelGroup( + GroupLayout.Alignment.BASELINE).addComponent(okButton) + .addComponent(cancelButton); + } else { + buttonVertical = buttonPanelLayout.createSequentialGroup() + .addComponent(okButton); + } - // align pinfield and pinsize to the right - GroupLayout.Group pinHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING); - GroupLayout.SequentialGroup pinVertical = mainPanelLayout.createSequentialGroup(); - - if (pinLabelPos == PinLabelPosition.ABOVE) { - pinHorizontal - .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(pinpadPINField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - pinVertical - .addComponent(pinLabel) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinpadPINField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinsizeLabel); - } else { // PinLabelPosition.LEFT - pinHorizontal - .addGroup(mainPanelLayout.createSequentialGroup() - .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinpadPINField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - pinVertical - .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(pinLabel) - .addComponent(pinpadPINField)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinsizeLabel); - } + buttonPanelLayout.setHorizontalGroup(buttonHorizontal); + buttonPanelLayout.setVerticalGroup(buttonVertical); + + } + + @Override + public void showEnterPINDirect(PinInfo pinSpec, int retries) { + if (retries < 0) { + showMessageDialog(TITLE_VERIFY_PINPAD, + MESSAGE_ENTERPIN_PINPAD_DIRECT, new Object[] { + pinSpec.getLocalizedName(), + pinSpec.getLocalizedLength() }); + } else { + showMessageDialog(TITLE_RETRY, MESSAGE_RETRIES, + new Object[] { String.valueOf(retries) }); + } + } + + @Override + public void showEnterPIN(final PinInfo pinSpec, final int retries) { + showEnterPIN(pinSpec, retries, TITLE_VERIFY_PINPAD, + MESSAGE_ENTERPIN_PINPAD, null); + } + + protected void showEnterPIN(final PinInfo pinSpec, final int retries, + final String titleKey, final String messageKey, + final Object[] messageParams) { + log.debug("Scheduling pinpad dialog."); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("[{}] show pinpad dialog.", Thread.currentThread().getName()); + + mainPanel.removeAll(); + buttonPanel.removeAll(); + + // avoid that dummy label gains focus during load + switchFocusDummyLabel.setFocusable(false); + + if (renderHeaderPanel) { + if (retries < 0) { + titleLabel.setText(getMessage(titleKey)); + } else { + titleLabel.setText(getMessage(TITLE_RETRY)); + } + } + + infoLabel = new JLabel(); + if (retries < 0) { + infoLabel.setFont(infoLabel.getFont().deriveFont( + infoLabel.getFont().getStyle() + & ~java.awt.Font.BOLD)); + infoLabel.setText(MessageFormat.format( + getMessage(messageKey), messageParams)); + helpListener.setHelpTopic(HELP_PINPAD); + } else { + String retryPattern; + if (retries == 1) { + retryPattern = getMessage(MESSAGE_LAST_RETRY); + } else { + retryPattern = getMessage(MESSAGE_RETRIES); + } + infoLabel.setText(MessageFormat.format(retryPattern, + new Object[] { String.valueOf(retries) })); + infoLabel.getAccessibleContext().setAccessibleName( + infoLabel.getText()); + infoLabel.setFont(infoLabel.getFont() + .deriveFont( + infoLabel.getFont().getStyle() + | java.awt.Font.BOLD)); + infoLabel.setForeground(ERROR_COLOR); + helpListener.setHelpTopic(HELP_RETRY); + } + + pinLabel.setFont(pinLabel.getFont().deriveFont( + pinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); + String pinName = getMessage(LABEL_PIN); + pinLabel.setText(MessageFormat.format(pinName, + new Object[] { pinSpec.getLocalizedName() })); + + pinpadPINField.setText(""); + pinpadPINField.setEnabled(false); + pinpadPIN = pinpadPINField.getDocument(); + + 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())); + + GroupLayout mainPanelLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + + GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout + .createSequentialGroup().addComponent(infoLabel); + GroupLayout.ParallelGroup infoVertical = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(infoLabel); + + if (!renderHeaderPanel) { + + if (helpListener.implementsListener()) { + infoHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + infoVertical.addComponent(helpLabel); + } + infoHorizontal.addComponent(switchFocusDummyLabel); + infoVertical.addComponent(switchFocusDummyLabel); + + } + + // align pinfield and pinsize to the right + GroupLayout.Group pinHorizontal = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.TRAILING); + GroupLayout.SequentialGroup pinVertical = mainPanelLayout + .createSequentialGroup(); + + if (pinLabelPos == PinLabelPosition.ABOVE) { + pinHorizontal.addGroup( + mainPanelLayout.createParallelGroup( + GroupLayout.Alignment.LEADING) + .addComponent(pinLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addComponent(pinpadPINField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)).addComponent( + pinsizeLabel, GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + pinVertical.addComponent(pinLabel).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinpadPINField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinsizeLabel); + } else { // PinLabelPosition.LEFT + pinHorizontal + .addGroup( + mainPanelLayout + .createSequentialGroup() + .addComponent(pinLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinpadPINField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)) + .addComponent(pinsizeLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + pinVertical.addGroup( + mainPanelLayout.createParallelGroup( + GroupLayout.Alignment.BASELINE) + .addComponent(pinLabel).addComponent( + pinpadPINField)).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinsizeLabel); + } + + mainPanelLayout.setHorizontalGroup(mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(infoHorizontal).addGroup(pinHorizontal)); + + mainPanelLayout + .setVerticalGroup(mainPanelLayout + .createSequentialGroup().addGroup(infoVertical) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pinVertical)); + + infoLabel.setFocusable(true); + + infoLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + // focus has been set accordingly - re-enable dummy + // label + switchFocusDummyLabel.setFocusable(true); + } + + }); + + String accessibleData = cutOffHTMLTags(infoLabel.getText()) + + cutOffHTMLTags(pinLabel.getText()) + + cutOffHTMLTags(pinsizeLabel.getText()); + + infoLabel.getAccessibleContext().setAccessibleName( + accessibleData); + infoLabel.getAccessibleContext().setAccessibleDescription( + accessibleData); + + primaryFocusHolder = infoLabel; + + // delete potentially stored method to be run as nothing has to + // be re-rendered + methodToRunAtResize = null; + + infoLabel.requestFocus(); + + contentPanel.validate(); + + resize(); + } + }); + } + + // simple utility method to retrieve plain text from HTML + protected String cutOffHTMLTags(String str) { + + char[] arr = str.toCharArray(); + StringBuffer result = new StringBuffer(); + boolean inTag = false; - mainPanelLayout.setHorizontalGroup( - mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(infoHorizontal) - .addGroup(pinHorizontal)); + for (int i = 0; i < arr.length; i++) { - mainPanelLayout.setVerticalGroup( - mainPanelLayout.createSequentialGroup() - .addGroup(infoVertical) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pinVertical)); + char c = arr[i]; - contentPanel.validate(); - } - }); - } + if (c == '<') { + inTag = true; + } + + if (!inTag) { + + result.append(c); + } + + if (c == '>') { + + inTag = false; + } + } + + return result.toString(); + } @Override - public void showSignatureDataDialog(PINSpec spec, + public void showSignatureDataDialog(PinInfo spec, final ActionListener enterPINListener, final String enterPINCommand, final ActionListener cancelListener, final String cancelCommand, final ActionListener hashdataListener, final String hashdataCommand) { - log.debug("scheduling signature-data dialog"); + log.debug("Scheduling signature-data dialog."); - SwingUtilities.invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { + @Override + public void run() { - log.debug("[" + Thread.currentThread().getName() + "] show signature-data dialog"); + log.debug("[{}] show signature-data dialog.", + Thread.currentThread().getName()); - mainPanel.removeAll(); - buttonPanel.removeAll(); + mainPanel.removeAll(); + buttonPanel.removeAll(); - if (renderHeaderPanel) { - titleLabel.setText(getMessage(TITLE_SIGNATURE_DATA)); - } + // specify policy to ensure correct focus traversal + if (useFocusTraversalPolicy) { - final JLabel infoLabel = new JLabel(); - infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - if (shortText) { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY)); - } else { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); - } - infoLabel.setFocusable(true); - infoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - infoLabel.setForeground(HYPERLINK_COLOR); - infoLabel.addMouseListener(new MouseAdapter() { + contentPanel.setFocusCycleRoot(true); + contentPanel + .setFocusTraversalPolicy(new AdvancedShowSigDataGUIFocusTraversalPolicy()); + } - @Override - public void mouseClicked(MouseEvent me) { - ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand); - hashdataListener.actionPerformed(e); - } - }); + // avoid that dummy label gains focus during load + switchFocusDummyLabel.setFocusable(false); - infoLabel.addKeyListener(new KeyAdapter() { + if (renderHeaderPanel) { + titleLabel.setText(getMessage(TITLE_SIGNATURE_DATA)); + } - @Override - public void keyPressed(KeyEvent e) { + infoLabel = new JLabel(); + infoLabel.setFont(infoLabel.getFont().deriveFont( + infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); + if (shortText) { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY)); + } else { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); + } + infoLabel.getAccessibleContext().setAccessibleName( + infoLabel.getText()); + infoLabel.setFocusable(true); - if(e.getKeyCode() == KeyEvent.VK_ENTER) { - ActionEvent e1 = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand); - hashdataListener.actionPerformed(e1); - } - } + infoLabel.setToolTipText(getMessage(SIGDATA_TOOLTIPTEXT)); + infoLabel.getAccessibleContext().setAccessibleDescription( + getMessage(SIGDATA_TOOLTIPTEXT)); + infoLabel.getAccessibleContext().setAccessibleName( + getMessage(SIGDATA_TOOLTIPTEXT)); - }); + infoLabel.setCursor(Cursor + .getPredefinedCursor(Cursor.HAND_CURSOR)); + infoLabel.setForeground(HYPERLINK_COLOR); + infoLabel.addMouseListener(new MouseAdapter() { - infoLabel.addFocusListener(new FocusAdapter() { + @Override + public void mouseClicked(MouseEvent me) { + ActionEvent e = new ActionEvent(this, + ActionEvent.ACTION_PERFORMED, hashdataCommand); + hashdataListener.actionPerformed(e); + } + }); - @Override - public void focusGained(FocusEvent e) { + infoLabel.addKeyListener(new KeyAdapter() { - if (shortText) { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY_FOCUS)); - } else { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_FOCUS)); - } - } + @Override + public void keyPressed(KeyEvent e) { - @Override - public void focusLost(FocusEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + ActionEvent e1 = new ActionEvent(this, + ActionEvent.ACTION_PERFORMED, + hashdataCommand); + hashdataListener.actionPerformed(e1); + } + } - if (shortText) { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY)); - } else { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); - } + }); - } + infoLabel.addFocusListener(new FocusAdapter() { - }); + @Override + public void focusGained(FocusEvent e) { - helpMouseListener.setHelpTopic(HELP_SIGNPIN); - helpKeyListener.setHelpTopic(HELP_SIGNPIN); + infoLabel.setBorder(sigDataFocusBorder); + } - //TODO message panel + @Override + public void focusLost(FocusEvent e) { -// String msgPattern = getMessage(MESSAGE_ENTERPIN_PINPAD); -// String msg = MessageFormat.format(msgPattern, new Object[] { -// pinSpec.getLocalizedName(), pinSpec.getLocalizedLength() }); -// -// JLabel msgLabel = new JLabel(); -// msgLabel.setFont(msgLabel.getFont().deriveFont(msgLabel.getFont().getStyle() & ~Font.BOLD)); -// msgLabel.setText(msg); - - GroupLayout mainPanelLayout = new GroupLayout(mainPanel); - mainPanel.setLayout(mainPanelLayout); - - GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup() - .addComponent(infoLabel); - GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(infoLabel); - - if (!renderHeaderPanel) { - infoHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - infoVertical - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - } - - mainPanelLayout.setHorizontalGroup( - infoHorizontal); -// mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) -// .addGroup(infoHorizontal) -// .addComponent(msgLabel)); - - mainPanelLayout.setVerticalGroup( - infoVertical); -// mainPanelLayout.createSequentialGroup() -// .addGroup(infoVertical) -// .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) -// .addComponent(msgLabel)); - - - GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); - buttonPanel.setLayout(buttonPanelLayout); - - GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout.createSequentialGroup(); - GroupLayout.Group buttonVertical; - - JButton enterPINButton = new JButton(); - enterPINButton.setFont(enterPINButton.getFont().deriveFont(enterPINButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - enterPINButton.setText(getMessage(BUTTON_SIGN)); - enterPINButton.setActionCommand(enterPINCommand); - enterPINButton.addActionListener(enterPINListener); - - if (renderCancelButton) { - JButton cancelButton = new JButton(); - cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - cancelButton.setText(getMessage(BUTTON_CANCEL)); - cancelButton.setActionCommand(cancelCommand); - cancelButton.addActionListener(cancelListener); - - buttonHorizontal - .addComponent(enterPINButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) - ; - buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(enterPINButton) - .addComponent(cancelButton) - ; - } else { - buttonHorizontal - .addComponent(enterPINButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) - ; - buttonVertical = buttonPanelLayout.createSequentialGroup() - .addComponent(enterPINButton) - ; - } - - buttonPanelLayout.setHorizontalGroup(buttonHorizontal); - buttonPanelLayout.setVerticalGroup(buttonVertical); - - contentPanel.validate(); + infoLabel.setBorder(BorderFactory.createEmptyBorder()); + } + + }); + + helpListener.setHelpTopic(HELP_SIGNPIN); + + GroupLayout mainPanelLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + + GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout + .createSequentialGroup().addComponent(infoLabel); + GroupLayout.ParallelGroup infoVertical = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(infoLabel); + + if (!renderHeaderPanel) { + + if (helpListener.implementsListener()) { + infoHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + infoVertical.addComponent(helpLabel); + } + infoHorizontal.addComponent(switchFocusDummyLabel); + infoVertical.addComponent(switchFocusDummyLabel); + + } + + mainPanelLayout.setHorizontalGroup(infoHorizontal); + mainPanelLayout.setVerticalGroup(infoVertical); + + enterPINButton.setFont(enterPINButton.getFont().deriveFont( + enterPINButton.getFont().getStyle() + & ~java.awt.Font.BOLD)); + enterPINButton.setText(getMessage(BUTTON_SIGN)); + enterPINButton.setActionCommand(enterPINCommand); + enterPINButton.addActionListener(enterPINListener); + + enterPINButton.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + // focus has been set accordingly - re-enable dummy + // label + switchFocusDummyLabel.setFocusable(true); + } + + }); + + if (renderCancelButton) { + cancelButton.setFont(cancelButton.getFont().deriveFont( + cancelButton.getFont().getStyle() + & ~java.awt.Font.BOLD)); + cancelButton.setText(getMessage(BUTTON_CANCEL)); + cancelButton.setActionCommand(cancelCommand); + cancelButton.addActionListener(cancelListener); + } + + updateMethodToRunAtResize("at.gv.egiz.bku.gui.BKUGUIImpl", + "renderShowSignatureDataDialogButtonPanel"); + + renderShowSignatureDataDialogButtonPanel(); + + if (windowCloseAdapter != null) { + windowCloseAdapter.registerListener(cancelListener, cancelCommand); } - }); - } - @Override - public void correctionButtonPressed() { - log.debug("[" + Thread.currentThread().getName() + "] correction button pressed"); - - if (pinpadPIN != null) { - try { - pinpadPIN.remove(0, 1); - } catch (BadLocationException ex) { - } - } - } + primaryFocusHolder = enterPINButton; - @Override - public void allKeysCleared() { - log.debug("[" + Thread.currentThread().getName() + "] all keys cleared"); - - if (pinpadPIN != null) { - try { - pinpadPIN.remove(0, pinpadPIN.getLength()); - } catch (BadLocationException ex) { - } - } - } + enterPINButton.requestFocus(); - @Override - public void validKeyPressed() { - log.debug("[" + Thread.currentThread().getName() + "] valid key pressed"); - - if (pinpadPIN != null) { - try { - pinpadPIN.insertString(0, "*", null); - } catch (BadLocationException ex) { - } - } - } + contentPanel.validate(); - @Override - public void showSignaturePINDialog(final PINSpec pinSpec, final int numRetries, + resize(); + } + }); + } + + public void renderShowSignatureDataDialogButtonPanel() { + + GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); + buttonPanel.setLayout(buttonPanelLayout); + + GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout + .createSequentialGroup(); + GroupLayout.Group buttonVertical; + + if (renderCancelButton) { + + buttonHorizontal.addComponent(enterPINButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED).addComponent( + cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE); + buttonVertical = buttonPanelLayout.createParallelGroup( + GroupLayout.Alignment.BASELINE) + .addComponent(enterPINButton).addComponent(cancelButton); + } else { + buttonHorizontal.addComponent(enterPINButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE); + buttonVertical = buttonPanelLayout.createSequentialGroup() + .addComponent(enterPINButton); + } + + buttonPanelLayout.setHorizontalGroup(buttonHorizontal); + buttonPanelLayout.setVerticalGroup(buttonVertical); + + } + + @Override + public void correctionButtonPressed() { + log.debug("[{}] Correction button pressed.", Thread.currentThread().getName()); + + if (pinpadPIN != null) { + try { + pinpadPIN.remove(0, 1); + } catch (BadLocationException ex) { + } + } + } + + @Override + public void allKeysCleared() { + log.debug("[{}] All keys cleared.", Thread.currentThread().getName()); + + if (pinpadPIN != null) { + try { + pinpadPIN.remove(0, pinpadPIN.getLength()); + } catch (BadLocationException ex) { + } + } + } + + @Override + public void validKeyPressed() { + log.debug("[{}] Valid key pressed.", Thread.currentThread().getName()); + + if (pinpadPIN != null) { + try { + pinpadPIN.insertString(0, "*", null); + } catch (BadLocationException ex) { + } + } + } + + @Override + public void showSignaturePINDialog(final PinInfo pinSpec, final int numRetries, final ActionListener signListener, final String signCommand, final ActionListener cancelListener, final String cancelCommand, final ActionListener hashdataListener, final String hashdataCommand) { - log.debug("scheduling signature-pin dialog"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("[" + Thread.currentThread().getName() + "] show signature-pin dialog"); - - mainPanel.removeAll(); - buttonPanel.removeAll(); - - if (renderHeaderPanel) { - if (numRetries < 0) { - titleLabel.setText(getMessage(TITLE_SIGN)); - } else { - titleLabel.setText(getMessage(TITLE_RETRY)); - } - } - - final JLabel infoLabel = new JLabel(); - if (numRetries < 0) { - infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - if (shortText) { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY)); - } else { - infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); - } - infoLabel.setFocusable(true); - infoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - infoLabel.setForeground(HYPERLINK_COLOR); - infoLabel.addMouseListener(new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent me) { - ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand); - hashdataListener.actionPerformed(e); - } - }); - - 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) { - retryPattern = getMessage(MESSAGE_LAST_RETRY); - } 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); - helpMouseListener.setHelpTopic(HELP_RETRY); - helpKeyListener.setHelpTopic(HELP_RETRY); - } - - JButton signButton = new JButton(); - signButton.setFont(signButton.getFont().deriveFont(signButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - signButton.setText(getMessage(BUTTON_SIGN)); - signButton.setEnabled(pinSpec.getMinLength() <= 0); - signButton.setActionCommand(signCommand); - signButton.addActionListener(signListener); - - JLabel signPinLabel = new JLabel(); - signPinLabel.setFont(signPinLabel.getFont().deriveFont(signPinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - String pinLabel = getMessage(LABEL_PIN); - signPinLabel.setText(MessageFormat.format(pinLabel, new Object[]{pinSpec.getLocalizedName()})); - - pinField = new JPasswordField(); - pinField.setText(""); - pinField.setDocument(new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), signButton)); - pinField.setActionCommand(signCommand); - pinField.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (pinField.getPassword().length >= pinSpec.getMinLength()) { - signListener.actionPerformed(e); - } - } - }); - - - 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())); - - GroupLayout mainPanelLayout = new GroupLayout(mainPanel); - mainPanel.setLayout(mainPanelLayout); - - GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup() - .addComponent(infoLabel); - GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(infoLabel); - - if (!renderHeaderPanel) { - infoHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - infoVertical - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - } - - // align pinfield and pinsize to the right - GroupLayout.Group pinHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING); - GroupLayout.SequentialGroup pinVertical = mainPanelLayout.createSequentialGroup(); - - if (pinLabelPos == PinLabelPosition.ABOVE) { - pinHorizontal - .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(signPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - pinVertical - .addComponent(signPinLabel) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinsizeLabel); - } else { // PinLabelPosition.LEFT - pinHorizontal - .addGroup(mainPanelLayout.createSequentialGroup() - .addComponent(signPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE); - pinVertical - .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(signPinLabel) - .addComponent(pinField)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pinsizeLabel); - } - - mainPanelLayout.setHorizontalGroup( - mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(infoHorizontal) - .addGroup(pinHorizontal)); - - mainPanelLayout.setVerticalGroup( - mainPanelLayout.createSequentialGroup() - .addGroup(infoVertical) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pinVertical)); - - GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); - buttonPanel.setLayout(buttonPanelLayout); - - GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout.createSequentialGroup(); - GroupLayout.Group buttonVertical; - - if (renderCancelButton) { - JButton cancelButton = new JButton(); - cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - cancelButton.setText(getMessage(BUTTON_CANCEL)); - cancelButton.setActionCommand(cancelCommand); - cancelButton.addActionListener(cancelListener); - - buttonHorizontal - .addComponent(signButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) - ; - buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(signButton) - .addComponent(cancelButton) - ; - } else { - buttonHorizontal - .addComponent(signButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE) - ; - buttonVertical = buttonPanelLayout.createSequentialGroup() - .addComponent(signButton) - ; - } - - buttonPanelLayout.setHorizontalGroup(buttonHorizontal); - buttonPanelLayout.setVerticalGroup(buttonVertical); - -// pinField.requestFocusInWindow(); -// helpLabel.requestFocus(); - pinField.requestFocus(); - contentPanel.validate(); - - } - }); - } + log.debug("Scheduling signature-pin dialog."); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("[{}] Show signature-pin dialog.", Thread.currentThread().getName()); + + mainPanel.removeAll(); + buttonPanel.removeAll(); + + // specify policy to ensure correct focus traversal + if (useFocusTraversalPolicy) { + + contentPanel.setFocusCycleRoot(true); + contentPanel + .setFocusTraversalPolicy(new AdvancedSigPinGUIFocusTraversalPolicy()); + } + + // avoid that dummy label gains focus during load + switchFocusDummyLabel.setFocusable(false); + + if (renderHeaderPanel) { + if (numRetries < 0) { + titleLabel.setText(getMessage(TITLE_SIGN)); + } else { + titleLabel.setText(getMessage(TITLE_RETRY)); + } + } + + infoLabel = new JLabel(); + if (numRetries < 0) { + infoLabel.setFont(infoLabel.getFont().deriveFont( + infoLabel.getFont().getStyle() + & ~java.awt.Font.BOLD)); + if (shortText) { + infoLabel + .setText(getMessage(MESSAGE_HASHDATALINK_TINY)); + } else { + infoLabel.setText(getMessage(MESSAGE_HASHDATALINK)); + } + + infoLabel.setToolTipText(getMessage(SIGDATA_TOOLTIPTEXT)); + infoLabel.getAccessibleContext().setAccessibleDescription( + getMessage(SIGDATA_TOOLTIPTEXT)); + infoLabel.getAccessibleContext().setAccessibleName( + getMessage(SIGDATA_TOOLTIPTEXT)); + + infoLabel.setFocusable(true); + infoLabel.setCursor(Cursor + .getPredefinedCursor(Cursor.HAND_CURSOR)); + infoLabel.setForeground(HYPERLINK_COLOR); + infoLabel.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent me) { + ActionEvent e = new ActionEvent(this, + ActionEvent.ACTION_PERFORMED, + hashdataCommand); + hashdataListener.actionPerformed(e); + } + }); + + 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) { + + infoLabel.setBorder(sigDataFocusBorder); + } + + @Override + public void focusLost(FocusEvent e) { + + infoLabel.setBorder(BorderFactory + .createEmptyBorder()); + } + + }); + + helpListener.setHelpTopic(HELP_SIGNPIN); + } else { + String retryPattern; + if (numRetries < 2) { + retryPattern = getMessage(MESSAGE_LAST_RETRY); + } else { + retryPattern = getMessage(MESSAGE_RETRIES); + } + infoLabel.setFocusable(true); + infoLabel.setText(MessageFormat.format(retryPattern, + new Object[] { String.valueOf(numRetries) })); + + infoLabel.setToolTipText(getMessage(SIGDATA_TOOLTIPTEXT)); + infoLabel.getAccessibleContext().setAccessibleDescription( + getMessage(SIGDATA_TOOLTIPTEXT)); + infoLabel.getAccessibleContext().setAccessibleName( + getMessage(SIGDATA_TOOLTIPTEXT)); + + infoLabel.setFont(infoLabel.getFont() + .deriveFont( + infoLabel.getFont().getStyle() + | java.awt.Font.BOLD)); + infoLabel.setForeground(ERROR_COLOR); + helpListener.setHelpTopic(HELP_RETRY); + } + + signButton.setFont(signButton.getFont().deriveFont( + signButton.getFont().getStyle() & ~java.awt.Font.BOLD)); + signButton.setText(getMessage(BUTTON_SIGN)); + signButton.setEnabled(pinSpec.getMinLength() <= 0); + signButton.setActionCommand(signCommand); + signButton.addActionListener(signListener); + + signPinLabel.setFont(signPinLabel.getFont() + .deriveFont( + signPinLabel.getFont().getStyle() + & ~java.awt.Font.BOLD)); + String pinLabel = getMessage(LABEL_PIN); + signPinLabel.setText(MessageFormat.format(pinLabel, + new Object[] { pinSpec.getLocalizedName() })); + + pinField = new JPasswordField(); + pinField.setText(""); + pinField.setName("PINField"); + pinField.setDocument(new PINDocument(pinSpec.getMinLength(), + pinSpec.getMaxLength(), pinSpec.getRexepPattern(), + signButton)); + pinField.setActionCommand(signCommand); + pinField.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (pinField.getPassword().length >= pinSpec + .getMinLength()) { + signListener.actionPerformed(e); + } + } + }); + + // FIXME: For some reason, the switchFocusDummyLabel obtains the + // focus even + // if the pinField requests the focus. Therefore, the + // switchFocusDummyLabel is + // deactivated first and enabled only after the pinField has + // obtained the focus + pinField.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + // focus has been set accordingly - re-enable dummy + // label + switchFocusDummyLabel.setFocusable(true); + } + + }); + + 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())); + + pinField.getAccessibleContext().setAccessibleDescription( + infoLabel.getText() + signPinLabel.getText() + + pinsizeLabel.getText()); + + GroupLayout mainPanelLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + + GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout + .createSequentialGroup().addComponent(infoLabel); + GroupLayout.ParallelGroup infoVertical = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(infoLabel); + + if (!renderHeaderPanel) { + + if (helpListener.implementsListener()) { + infoHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + infoVertical.addComponent(helpLabel); + } + infoHorizontal.addComponent(switchFocusDummyLabel); + infoVertical.addComponent(switchFocusDummyLabel); + + } + + // align pinfield and pinsize to the right + GroupLayout.Group pinHorizontal = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.TRAILING); + GroupLayout.SequentialGroup pinVertical = mainPanelLayout + .createSequentialGroup(); + + if (pinLabelPos == PinLabelPosition.ABOVE) { + pinHorizontal.addGroup( + mainPanelLayout.createParallelGroup( + GroupLayout.Alignment.LEADING) + .addComponent(signPinLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addComponent(pinField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)).addComponent( + pinsizeLabel, GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + pinVertical.addComponent(signPinLabel).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinField, GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinsizeLabel); + } else { // PinLabelPosition.LEFT + pinHorizontal + .addGroup( + mainPanelLayout + .createSequentialGroup() + .addComponent(signPinLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinField, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + Short.MAX_VALUE)) + .addComponent(pinsizeLabel, + GroupLayout.PREFERRED_SIZE, + GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE); + pinVertical.addGroup( + mainPanelLayout.createParallelGroup( + GroupLayout.Alignment.BASELINE) + .addComponent(signPinLabel).addComponent( + pinField)).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pinsizeLabel); + } + + mainPanelLayout.setHorizontalGroup(mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(infoHorizontal).addGroup(pinHorizontal)); + + mainPanelLayout + .setVerticalGroup(mainPanelLayout + .createSequentialGroup().addGroup(infoVertical) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pinVertical)); + + if (renderCancelButton) { + cancelButton.setFont(cancelButton.getFont().deriveFont( + cancelButton.getFont().getStyle() + & ~java.awt.Font.BOLD)); + cancelButton.setText(getMessage(BUTTON_CANCEL)); + cancelButton.setActionCommand(cancelCommand); + cancelButton.addActionListener(cancelListener); + } + + updateMethodToRunAtResize("at.gv.egiz.bku.gui.BKUGUIImpl", + "renderSignaturePINDialogueButtonPanel"); + + renderSignaturePINDialogueButtonPanel(); + + if (windowCloseAdapter != null) { + windowCloseAdapter.registerListener(cancelListener, cancelCommand); + } - @Override - public void showErrorDialog( - final String errorMsgKey, final Object[] errorMsgParams, - final ActionListener okListener, final String okCommand) { - - showMessageDialog(TITLE_ERROR, ERROR_COLOR, - errorMsgKey, errorMsgParams, BUTTON_OK, okListener, okCommand); - } + primaryFocusHolder = pinField; - @Override - public void showErrorDialog( - final String errorMsgKey, final Object[] errorMsgParams) { + pinField.requestFocus(); - showMessageDialog(TITLE_ERROR, ERROR_COLOR, - errorMsgKey, errorMsgParams, null, null, null); - } + contentPanel.validate(); - @Override - public void showMessageDialog( - final String titleKey, - final String msgKey, final Object[] msgParams, - final String buttonKey, - final ActionListener okListener, final String okCommand) { - - showMessageDialog(titleKey, null, - msgKey, msgParams, buttonKey, okListener, okCommand); - } + resize(); + } + }); + } - @Override - public void showMessageDialog( - final String titleKey, - final String msgKey, final Object[] msgParams) { + public void renderSignaturePINDialogueButtonPanel() { + + GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); + buttonPanel.setLayout(buttonPanelLayout); + + GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout + .createSequentialGroup(); + GroupLayout.Group buttonVertical; + + if (renderCancelButton) { + + buttonHorizontal.addComponent(signButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE).addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED).addComponent( + cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE); + buttonVertical = buttonPanelLayout.createParallelGroup( + GroupLayout.Alignment.BASELINE).addComponent(signButton) + .addComponent(cancelButton); + } else { + buttonHorizontal.addComponent(signButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE); + buttonVertical = buttonPanelLayout.createSequentialGroup() + .addComponent(signButton); + } + + buttonPanelLayout.setHorizontalGroup(buttonHorizontal); + buttonPanelLayout.setVerticalGroup(buttonVertical); - showMessageDialog(titleKey, null, - msgKey, msgParams, null, null, null); - } + } - @Override - public void showMessageDialog( - final String titleKey, final String msgKey) { + @Override + public void showErrorDialog(final String errorMsgKey, + final Object[] errorMsgParams, final ActionListener okListener, + final String okCommand) { - showMessageDialog(titleKey, null, - msgKey, null, null, null, null); - } + showMessageDialog(TITLE_ERROR, ERROR_COLOR, errorMsgKey, + errorMsgParams, BUTTON_OK, okListener, okCommand); + } - /** - * - * @param buttonKey if null defaults to BUTTON_OK - */ - private void showMessageDialog( - final String titleKey, final Color titleColor, - final String msgKey, final Object[] msgParams, - final String buttonKey, - final ActionListener okListener, final String okCommand) { - - log.debug("scheduling message dialog"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("[" + Thread.currentThread().getName() + "] show message dialog"); - - mainPanel.removeAll(); - buttonPanel.removeAll(); - - if (renderHeaderPanel) { - titleLabel.setText(getMessage(titleKey)); - } - - helpMouseListener.setHelpTopic(msgKey); - helpKeyListener.setHelpTopic(msgKey); - - String msgPattern = getMessage(msgKey); - String msg = MessageFormat.format(msgPattern, msgParams); - - JLabel msgLabel = new JLabel(); - msgLabel.setFont(msgLabel.getFont().deriveFont(msgLabel.getFont().getStyle() & ~Font.BOLD)); - msgLabel.setText(msg); - - GroupLayout mainPanelLayout = new GroupLayout(mainPanel); - mainPanel.setLayout(mainPanelLayout); - - 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)); - titleLabel.setText(getMessage(titleKey)); - if (titleColor != null) { - titleLabel.setForeground(titleColor); - } - - mainHorizontal - .addGroup(mainPanelLayout.createSequentialGroup() - .addComponent(titleLabel) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ); - mainVertical - .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(titleLabel) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ); - - log.debug("focus to helpLabel"); - helpLabel.requestFocus(); - } - - mainPanelLayout.setHorizontalGroup(mainHorizontal - .addComponent(msgLabel)); - mainPanelLayout.setVerticalGroup(mainVertical - .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)); - okButton.setActionCommand(okCommand); - okButton.addActionListener(okListener); - - GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); - buttonPanel.setLayout(buttonPanelLayout); - - buttonPanelLayout.setHorizontalGroup( - buttonPanelLayout.createSequentialGroup() - .addComponent(okButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)); - buttonPanelLayout.setVerticalGroup( - buttonPanelLayout.createSequentialGroup() - .addComponent(okButton)); - - log.debug("focus to ok-button"); - okButton.requestFocus(); - } - - contentPanel.validate(); - } - }); - } + @Override + public void showErrorDialog(final String errorMsgKey, + final Object[] errorMsgParams) { + showMessageDialog(TITLE_ERROR, ERROR_COLOR, errorMsgKey, + errorMsgParams, null, null, null); + } - @Override - public char[] getPin() { - if (pinField != null) { - char[] pin = pinField.getPassword(); //returns a copy - pinField = null; //garbage collect original pin (make sure to clear char[] after use) - return pin; - } - return null; - } + @Override + public void showMessageDialog(final String titleKey, final String msgKey, + final Object[] msgParams, final String buttonKey, + final ActionListener okListener, final String okCommand) { + showMessageDialog(titleKey, null, msgKey, msgParams, buttonKey, + okListener, okCommand); + } - //////////////////////////////////////////////////////////////////////////// - // SECURE VIEWER - //////////////////////////////////////////////////////////////////////////// + @Override + public void showMessageDialog(final String titleKey, final String msgKey, + final Object[] msgParams) { - - /** - * @param signedReferences - * @param backListener gets notified if pin-dialog has to be redrawn - * (signedRefencesList returns via BACK button) - * @param okCommand - */ - @Override - public void showSecureViewer(final List dataToBeSigned, - final ActionListener backListener, final String backCommand) { - - if (dataToBeSigned == null) { - showErrorDialog(getMessage(ERR_NO_HASHDATA), - new Object[] {"no signature data provided"}, - backListener, backCommand); - } else if (dataToBeSigned.size() == 1) { - //TODO pull out (see also SignedReferencesSelectionListener) - if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(dataToBeSigned.get(0).getMimeType())) { - try { - log.debug("[" + Thread.currentThread().getName() + "] scheduling secure viewer"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - try { - showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_HASHDATA_VIEWER); - showSecureViewer(dataToBeSigned.get(0), backListener, backCommand); - } catch (FontProviderException ex) { - log.error("failed to display secure viewer", ex); - showErrorDialog(ERR_VIEWER, new Object[] {ex.getMessage()}, backListener, backCommand); - } - } - }); - - } catch (Exception ex) { //InterruptedException InvocationTargetException - log.error("Failed to display secure viewer: " + ex.getMessage()); - log.trace(ex); - showErrorDialog(ERR_UNKNOWN, null, backListener, backCommand); - } - } else { - log.debug("[" + Thread.currentThread().getName() + "] mime-type not supported by secure viewer, scheduling save dialog"); - showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_UNSUPPORTED_MIMETYPE); - SecureViewerSaveDialog.showSaveDialog(dataToBeSigned.get(0), messages, backListener, backCommand); - } - } else { - showSignedReferencesListDialog(dataToBeSigned, backListener, backCommand); - } - } - - /** - * has to be called from event dispatcher thread - */ - private void showSecureViewer(HashDataInput dataToBeSigned, ActionListener closeListener, String closeCommand) throws FontProviderException { - - log.debug("[" + Thread.currentThread().getName() + "] show secure viewer"); - SecureViewerDialog secureViewer = new SecureViewerDialog(null, messages, - closeListener, closeCommand, - fontProvider, 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. - Window window = SwingUtilities.getWindowAncestor(contentPane); - if (window != null && window.isAlwaysOnTop()) { - log.debug("make secureViewer alwaysOnTop"); - secureViewer.setAlwaysOnTop(true); - } - secureViewer.setContent(dataToBeSigned); - log.trace("viewer setContent returned"); - } - - - - private void showSignedReferencesListDialog(final List signedReferences, - final ActionListener backListener, final String backCommand) { - - log.debug("[" + Thread.currentThread().getName() + "] scheduling signed references list dialog"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("[" + Thread.currentThread().getName() + "] show signed references list dialog"); - - mainPanel.removeAll(); - buttonPanel.removeAll(); - - if (renderHeaderPanel) { - titleLabel.setText(getMessage(TITLE_SIGNATURE_DATA)); - } - - helpMouseListener.setHelpTopic(HELP_HASHDATALIST); - helpKeyListener.setHelpTopic(HELP_HASHDATALIST); - - JLabel refIdLabel = new JLabel(); - refIdLabel.setFont(refIdLabel.getFont().deriveFont(refIdLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); - String refIdLabelPattern = getMessage(MESSAGE_HASHDATALIST); - refIdLabel.setText(MessageFormat.format(refIdLabelPattern, new Object[]{signedReferences.size()})); - - HashDataTableModel tableModel = new HashDataTableModel(signedReferences, renderRefId); - final JTable hashDataTable = new JTable(tableModel); - hashDataTable.setDefaultRenderer(HashDataInput.class, new HyperlinkRenderer(renderRefId)); - hashDataTable.setTableHeader(null); - - hashDataTable.addMouseMotionListener(new SignedReferencesMouseMotionListener(hashDataTable)); - - hashDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - hashDataTable.getSelectionModel().addListSelectionListener(new SignedReferencesSelectionListener(signedReferences, backListener, backCommand)); - - JScrollPane hashDataScrollPane = new JScrollPane(hashDataTable); - - GroupLayout mainPanelLayout = new GroupLayout(mainPanel); - mainPanel.setLayout(mainPanelLayout); - - GroupLayout.SequentialGroup messageHorizontal = mainPanelLayout.createSequentialGroup() - .addComponent(refIdLabel); - - GroupLayout.ParallelGroup messageVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(refIdLabel); - - if (!renderHeaderPanel) { - messageHorizontal - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - messageVertical - .addComponent(switchFocusDummyLabel) - .addComponent(helpLabel) - ; - } - - mainPanelLayout.setHorizontalGroup( - mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(messageHorizontal) - .addComponent(hashDataScrollPane, 0, 0, Short.MAX_VALUE)); - - mainPanelLayout.setVerticalGroup( - mainPanelLayout.createSequentialGroup() - .addGroup(messageVertical) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(hashDataScrollPane, 0, 0, hashDataTable.getPreferredSize().height+3)); - - JButton backButton = new JButton(); - backButton.setFont(backButton.getFont().deriveFont(backButton.getFont().getStyle() & ~java.awt.Font.BOLD)); - backButton.setText(getMessage(BUTTON_BACK)); - backButton.setActionCommand(backCommand); - backButton.addActionListener(backListener); - - GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); - buttonPanel.setLayout(buttonPanelLayout); - - buttonPanelLayout.setHorizontalGroup(buttonPanelLayout.createSequentialGroup() - .addComponent(backButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)); - buttonPanelLayout.setVerticalGroup(buttonPanelLayout.createSequentialGroup() - .addComponent(backButton)); - - contentPanel.validate(); - } - }); - } - - - - /** - * not possible to add mouse listener to TableCellRenderer - * to change cursor on specific columns only, use table.columnAtPoint(e.getPoint()) - * - */ - private class SignedReferencesMouseMotionListener extends MouseMotionAdapter { - - JTable hashDataTable; - - public SignedReferencesMouseMotionListener(JTable table) { - this.hashDataTable = table; - } - - @Override - public void mouseMoved(MouseEvent e) { -// if (hashDataTable.columnAtPoint(e.getPoint()) == 0) { - hashDataTable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - } - - /////////// - // SignedReferencesList (TODO pull out) - - public class SignedReferencesSelectionListener implements ListSelectionListener { - - List signedReferences; - ActionListener backListener; - String backCommand; - - public SignedReferencesSelectionListener(List signedReferences, ActionListener backListener, String backCommand) { - this.signedReferences = signedReferences; - this.backListener = backListener; - this.backCommand = backCommand; - } - - @Override - public void valueChanged(ListSelectionEvent event) { - - if (event.getValueIsAdjusting()) { - return; - } - - ListSelectionModel lsm = (ListSelectionModel) event.getSource(); - int selectionIdx = lsm.getMinSelectionIndex(); - - log.debug("[" + Thread.currentThread().getName() + "] reference " + selectionIdx + " selected"); - - if (selectionIdx >= 0) { - final HashDataInput selection = signedReferences.get(selectionIdx); - final SignedReferencesListDisplayer backToListListener = new SignedReferencesListDisplayer(signedReferences, backListener, backCommand); - - if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(selection.getMimeType())) { - log.debug("[" + Thread.currentThread().getName() + "] scheduling secure viewer dialog"); - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - try { - showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_HASHDATA_VIEWER); - showSecureViewer(selection, backToListListener, null); -// SecureViewerDialog.showSecureViewer(selection, messages, fontProvider, helpMouseListener.getActionListener(), false); - } catch (FontProviderException ex) { - log.error("failed to display secure viewer", ex); - showErrorDialog(BKUGUIFacade.ERR_VIEWER, new Object[] {ex.getMessage()}, backToListListener, null); - } - - } - }); - } else { - log.debug("[" + Thread.currentThread().getName() + "] mime-type not supported by secure viewer, scheduling save dialog"); - showMessageDialog(BKUGUIFacade.TITLE_SIGNATURE_DATA, BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE); - SecureViewerSaveDialog.showSaveDialog(selection, messages, backToListListener, null); - } - } - } - - /** - * ActionListener that returns to signed references list - */ - private class SignedReferencesListDisplayer implements ActionListener { - List sr; - ActionListener bl; - String bc; - - public SignedReferencesListDisplayer(List signedReferences, ActionListener backListener, String backCommand) { - sr = signedReferences; - bl = backListener; - bc = backCommand; - } - - @Override - public void actionPerformed(ActionEvent e) { -// log.debug("[" + Thread.currentThread().getName() + "] displaying signed references list"); - showSignedReferencesListDialog(sr, bl, bc); - } - } - } + showMessageDialog(titleKey, null, msgKey, msgParams, null, null, null); + } + @Override + public void showMessageDialog(final String titleKey, final String msgKey) { - //////////////////////////////////////////////////////////////////////////// - // UTILITY METHODS - //////////////////////////////////////////////////////////////////////////// - - private void registerHelpListener(ActionListener helpListener) { - if (helpListener != null) { - 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.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() + ")"); - } - }); - } - } + showMessageDialog(titleKey, null, msgKey, null, null, null, null); + } + + /** + * + * @param buttonKey + * if null defaults to BUTTON_OK + */ + private void showMessageDialog(final String titleKey, + final Color titleColor, final String msgKey, + final Object[] msgParams, final String buttonKey, + final ActionListener okListener, final String okCommand) { + + log.debug("Scheduling message dialog."); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("[{}] Show message dialog.", Thread.currentThread().getName()); + + log.debug("ButtonKey: {}.", buttonKey); + + mainPanel.removeAll(); + buttonPanel.removeAll(); + + // avoid that dummy label gains focus during load + switchFocusDummyLabel.setFocusable(false); + + if (renderHeaderPanel) { + titleLabel.setText(getMessage(titleKey)); + } - 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"); - } - }); + helpListener.setHelpTopic(msgKey); + + String msgPattern = getMessage(msgKey); + String msg = MessageFormat.format(msgPattern, msgParams); + + // we need to create a new JLabel object every time in order to + // ensure + // that screen reading software will read each updated label + msgLabel = new JLabel(); + + msgLabel.setFocusable(true); + + msgLabel.setFont(msgLabel.getFont().deriveFont( + msgLabel.getFont().getStyle() & ~Font.BOLD)); + msgLabel.setText(msg); + + GroupLayout mainPanelLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + + GroupLayout.ParallelGroup mainHorizontal = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING); + GroupLayout.SequentialGroup mainVertical = mainPanelLayout + .createSequentialGroup(); + + String accessibleData = ""; + + if (!renderHeaderPanel) { + msgTitleLabel = new JLabel(); + msgTitleLabel.setFont(msgTitleLabel.getFont().deriveFont( + msgTitleLabel.getFont().getStyle() | Font.BOLD)); + msgTitleLabel.setText(getMessage(titleKey)); + + if (titleColor != null) { + msgTitleLabel.setForeground(titleColor); + } + + accessibleData = accessibleData + getMessage(titleKey); + + GroupLayout.SequentialGroup titleHorizontal = mainPanelLayout + .createSequentialGroup() + .addComponent(msgTitleLabel); + + GroupLayout.ParallelGroup titleVertical = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(msgTitleLabel); + + if (helpListener.implementsListener()) { + titleHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + titleVertical.addComponent(helpLabel); + } + titleHorizontal.addComponent(switchFocusDummyLabel); + titleVertical.addComponent(switchFocusDummyLabel); + + mainHorizontal.addGroup(titleHorizontal); + mainVertical.addGroup(titleVertical); + + } else { + + accessibleData = accessibleData + titleLabel.getText(); + } + + msgLabel.getAccessibleContext().setAccessibleName( + accessibleData + msgLabel.getText()); + msgLabel.getAccessibleContext().setAccessibleDescription( + accessibleData + msgLabel.getText()); + + msgLabel.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(FocusEvent e) { + + // focus has been set accordingly - re-enable dummy + // label + switchFocusDummyLabel.setFocusable(true); + } + + }); + + mainPanelLayout.setHorizontalGroup(mainHorizontal + .addComponent(msgLabel)); + mainPanelLayout.setVerticalGroup(mainVertical + .addComponent(msgLabel)); + + if (okListener != null) { + + showMessageOKButton = true; + + okButton.setFont(okButton.getFont() + .deriveFont( + okButton.getFont().getStyle() + & ~java.awt.Font.BOLD)); + okButton.setText(getMessage((buttonKey != null) ? buttonKey + : BUTTON_OK)); + okButton.setActionCommand(okCommand); + okButton.addActionListener(okListener); + + renderShowMessageDialogueButtonPanel(); + + primaryFocusHolder = msgLabel; + + } else { + log.debug("No okListener configured."); + showMessageOKButton = false; + } + + // okListener might be null (up to windowCloseAdapter what to do) + if (windowCloseAdapter != null) { + windowCloseAdapter.registerListener(okListener, okCommand); } - } - - //////////////////////////////////////////////////////////////////////////// - // INITIALIZERS (MAY BE OVERRIDDEN BY SUBCLASSES) - //////////////////////////////////////////////////////////////////////////// - - /** - * Load applet messages bundle. Note that getBundle looks for classes based - * on the default Locale before it selects the base class! - * - * Called from constructor. - * Subclasses may override this method to ensure the message bundle is loaded - * once initButtonSize (called from constructor as well) is called. - * (Only relevant if initButtonSize is overridden as well) - * @param locale - */ - protected void loadMessageBundle(Locale locale) { - if (locale != null) { - // see [#378] Ignoring post parameter 'locale': bundle resolve-order not correct?! - Locale lang = new Locale(locale.getLanguage().substring(0, 2)); - log.debug("loading applet resources for language: " + lang.toString()); - messages = ResourceBundle.getBundle(MESSAGES_BUNDLE, lang); - } else { - log.debug("loading default language applet resources"); - messages = ResourceBundle.getBundle(MESSAGES_BUNDLE); - } - // how the f*** you know the default Messages.properties is de?! - log.debug("applet messages loaded: " + messages.getLocale()); - } - protected int initButtonSize() { - int bs = 0; - - JButton b = new JButton(); - b.setText(getMessage(BUTTON_OK)); - if (b.getPreferredSize().width > bs) { - bs = b.getPreferredSize().width; - } - // need cancel button for message dialog, - // even if renderCancelButton == false - b.setText(getMessage(BUTTON_CANCEL)); - if (b.getPreferredSize().width > bs) { - bs = b.getPreferredSize().width; - } - b.setText(getMessage(BUTTON_SIGN)); - if (b.getPreferredSize().width > bs) { - bs = b.getPreferredSize().width; - } - b.setText(getMessage(BUTTON_BACK)); - if (b.getPreferredSize().width > bs) { - bs = b.getPreferredSize().width; - } - b.setText(getMessage(BUTTON_SAVE)); - if (b.getPreferredSize().width > bs) { - bs = b.getPreferredSize().width; - } - return bs; - } + updateMethodToRunAtResize("at.gv.egiz.bku.gui.BKUGUIImpl", + "renderShowMessageDialogueButtonPanel"); + + // put focus to msgLabel to guarantee that label is read by + // screen reader upon loading + msgLabel.requestFocus(); + + contentPanel.validate(); + + resize(); + } + }); + } + + public void renderShowMessageDialogueButtonPanel() { + + if (showMessageOKButton) { + GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); + buttonPanel.setLayout(buttonPanelLayout); + + buttonPanelLayout.setHorizontalGroup(buttonPanelLayout + .createSequentialGroup().addComponent(okButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE)); + buttonPanelLayout.setVerticalGroup(buttonPanelLayout + .createSequentialGroup().addComponent(okButton)); + } + } + + @Override + public char[] getPin() { + if (pinField != null) { + char[] pin = pinField.getPassword(); // returns a copy + pinField = null; // garbage collect original pin (make sure to clear + // char[] after use) + return pin; + } + return null; + } + + // ////////////////////////////////////////////////////////////////////////// + // SECURE VIEWER + // ////////////////////////////////////////////////////////////////////////// + + /** + * @param signedReferences + * @param backListener + * gets notified if pin-dialog has to be redrawn + * (signedRefencesList returns via BACK button) + * @param okCommand + */ + @Override + public void showSecureViewer(final List dataToBeSigned, + final ActionListener backListener, final String backCommand) { + + if (dataToBeSigned == null) { + showErrorDialog(getMessage(ERR_NO_HASHDATA), + new Object[] { "no signature data provided" }, + backListener, backCommand); + } else if (dataToBeSigned.size() == 1) { + // TODO pull out (see also SignedReferencesSelectionListener) + if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(dataToBeSigned + .get(0).getMimeType())) { + try { + log.debug("[{}] Scheduling secure viewer.", Thread.currentThread().getName()); + + showMessageDialog(TITLE_SIGNATURE_DATA, + MESSAGE_HASHDATA_VIEWER); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + try { + showSecureViewer(dataToBeSigned.get(0), + backListener, backCommand); + } catch (FontProviderException ex) { + log.error("Failed to display secure viewer.", ex); + showErrorDialog(ERR_VIEWER, new Object[] { ex + .getMessage() }, backListener, + backCommand); + } + } + }); + + } catch (Exception ex) { // InterruptedException + // InvocationTargetException + log.error("Failed to display secure viewer. ", ex); + showErrorDialog(ERR_UNKNOWN, null, backListener, + backCommand); + } + } else { + log.debug("[{}] mime-type not supported by secure viewer, " + + "scheduling save dialog.", Thread.currentThread().getName()); + showMessageDialog(TITLE_SIGNATURE_DATA, + MESSAGE_UNSUPPORTED_MIMETYPE, + new Object[] { dataToBeSigned.get(0).getMimeType() }); + SecureViewerSaveDialog.showSaveDialog(dataToBeSigned.get(0), + messages, backListener, backCommand, + (int) (baseFontSize * getResizeFactor())); + } + } else { + showSignedReferencesListDialog(dataToBeSigned, backListener, + backCommand); + } + } + + /** + * has to be called from event dispatcher thread + */ + private void showSecureViewer(HashDataInput dataToBeSigned, + ActionListener closeListener, String closeCommand) + throws FontProviderException { + + log.debug("[{}] Show secure viewer."); + secureViewer = new SecureViewerDialog(null, messages, closeListener, + closeCommand, fontProvider, helpListener, getResizeFactor()); + + // workaround for [#439] + // avoid AlwaysOnTop at least in applet, otherwise make secureViewer + // AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) + // is always on top. + Window window = SwingUtilities.getWindowAncestor(contentPane); + if (window != null && window.isAlwaysOnTop()) { + log.debug("Make secureViewer alwaysOnTop."); + secureViewer.setAlwaysOnTop(true); + } + + secureViewer.setContent(dataToBeSigned); + log.trace("Viewer setContent returned."); + } + + private void openSecureViewerDialog() { + + final HashDataInput storedSelection = signedReferences.get(referenceIndex); + + if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(storedSelection + .getMimeType())) { + log.debug("[{}] Scheduling secure viewer dialog.", Thread.currentThread().getName()); + + showMessageDialog(TITLE_SIGNATURE_DATA, + MESSAGE_HASHDATA_VIEWER); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + try { + showSecureViewer(storedSelection, storedBackToListListener, + null); + // SecureViewerDialog.showSecureViewer(selection, + // messages, fontProvider, + // helpMouseListener.getActionListener(), + // false); + } catch (FontProviderException ex) { + log.error("Failed to display secure viewer.", ex); + showErrorDialog(BKUGUIFacade.ERR_VIEWER, + new Object[] { ex.getMessage() }, + storedBackToListListener, null); + } + + } + }); + } else { + log.debug("[{}] Mime-type not supported by secure viewer, " + + "scheduling save dialog.", Thread.currentThread().getName()); + showMessageDialog(BKUGUIFacade.TITLE_SIGNATURE_DATA, + BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE, + new Object[] { storedSelection.getMimeType() }); + SecureViewerSaveDialog.showSaveDialog(storedSelection, messages, + storedBackToListListener, null, + (int) (baseFontSize * getResizeFactor())); + } + + + } + + private void showSignedReferencesListDialog( + final List signedReferences, + final ActionListener backListener, final String backCommand) { + + log.debug("[{}] Scheduling signed references list dialog.", Thread.currentThread().getName()); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("[{}] Show signed references list dialog.", Thread.currentThread().getName()); + + mainPanel.removeAll(); + buttonPanel.removeAll(); + + if (renderHeaderPanel) { + titleLabel.setText(getMessage(TITLE_SIGNATURE_DATA)); + } + + helpListener.setHelpTopic(HELP_HASHDATALIST); + + refIdLabel = new JLabel(); + refIdLabel.setFont(refIdLabel.getFont().deriveFont( + refIdLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); + String refIdLabelPattern = getMessage(MESSAGE_HASHDATALIST); + refIdLabel.setText(MessageFormat.format(refIdLabelPattern, + new Object[] { signedReferences.size() })); + + HashDataTableModel tableModel = new HashDataTableModel( + signedReferences, renderRefId); + hashDataTable = new JTable(tableModel); + + hyperlinkRenderer = new HyperlinkRenderer(renderRefId); + + hashDataTable.setDefaultRenderer(HashDataInput.class, + hyperlinkRenderer); + hashDataTable.setTableHeader(null); + + hashDataTable + .addMouseMotionListener(new SignedReferencesMouseMotionListener( + hashDataTable)); + + hashDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + hashDataTable + .setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + hashDataTable.getSelectionModel().addListSelectionListener( + new SignedReferencesSelectionListener(signedReferences, + backListener, backCommand)); + + + hashDataTable.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + + openSecureViewerDialog(); + } + + }); + + hashDataTable.addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + + if(e.getKeyCode() == KeyEvent.VK_ENTER) { + + log.debug("Detected Enter Key."); + + openSecureViewerDialog(); + } + + } + + }); + + hashDataScrollPane = new JScrollPane(hashDataTable); + + backButton.setFont(backButton.getFont().deriveFont( + backButton.getFont().getStyle() & ~java.awt.Font.BOLD)); + backButton.setText(getMessage(BUTTON_BACK)); + backButton.setActionCommand(backCommand); + backButton.addActionListener(backListener); + + primaryFocusHolder = hashDataTable; + + updateMethodToRunAtResize("at.gv.egiz.bku.gui.BKUGUIImpl", "renderSignedReferenceListButtonandTable"); + + renderSignedReferenceListButtonandTable(); + + hashDataTable.requestFocus(); + + contentPanel.validate(); + + resize(); + } + }); + } + + public void renderSignedReferenceListButtonandTable() { + + GroupLayout mainPanelLayout = new GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + + GroupLayout.SequentialGroup messageHorizontal = mainPanelLayout + .createSequentialGroup().addComponent(refIdLabel); + + GroupLayout.ParallelGroup messageVertical = mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(refIdLabel); + + if (!renderHeaderPanel) { + + if (helpListener.implementsListener()) { + messageHorizontal.addPreferredGap( + LayoutStyle.ComponentPlacement.UNRELATED, 0, + Short.MAX_VALUE).addComponent(helpLabel); + messageVertical.addComponent(helpLabel); + } + messageHorizontal.addComponent(switchFocusDummyLabel); + messageVertical.addComponent(switchFocusDummyLabel); + } + + mainPanelLayout.setHorizontalGroup(mainPanelLayout + .createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(messageHorizontal).addComponent( + hashDataScrollPane, 0, 0, Short.MAX_VALUE)); + + mainPanelLayout + .setVerticalGroup(mainPanelLayout + .createSequentialGroup() + .addGroup(messageVertical) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED) + .addComponent( + hashDataScrollPane, + 0, + 0, + hashDataTable.getPreferredSize().height + 3)); + + + + GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); + buttonPanel.setLayout(buttonPanelLayout); + + buttonPanelLayout.setHorizontalGroup(buttonPanelLayout + .createSequentialGroup().addComponent(backButton, + GroupLayout.PREFERRED_SIZE, buttonSize, + GroupLayout.PREFERRED_SIZE)); + buttonPanelLayout.setVerticalGroup(buttonPanelLayout + .createSequentialGroup().addComponent(backButton)); + + } + + /** + * not possible to add mouse listener to TableCellRenderer to change cursor + * on specific columns only, use table.columnAtPoint(e.getPoint()) + * + */ + private class SignedReferencesMouseMotionListener extends + MouseMotionAdapter { + + JTable hashDataTable; + + public SignedReferencesMouseMotionListener(JTable table) { + this.hashDataTable = table; + } + + @Override + public void mouseMoved(MouseEvent e) { + // if (hashDataTable.columnAtPoint(e.getPoint()) == 0) { + hashDataTable.setCursor(Cursor + .getPredefinedCursor(Cursor.HAND_CURSOR)); + } + } + + // ///////// + // SignedReferencesList (TODO pull out) + + public class SignedReferencesSelectionListener implements + ListSelectionListener { + +// List signedReferences; + ActionListener backListener; + String backCommand; + + public SignedReferencesSelectionListener( + List signedReferences, + ActionListener backListener, String backCommand) { +// this.signedReferences = signedReferences; + BKUGUIImpl.this.signedReferences = signedReferences; + this.backListener = backListener; + this.backCommand = backCommand; + } + + @Override + public void valueChanged(ListSelectionEvent event) { + + if (event.getValueIsAdjusting()) { + return; + } + + ListSelectionModel lsm = (ListSelectionModel) event.getSource(); + int selectionIdx = lsm.getMinSelectionIndex(); + + log.debug("[{}] Reference {} selected.", + Thread.currentThread().getName(), selectionIdx); + + if (selectionIdx >= 0) { +// final HashDataInput selection = signedReferences +// .get(selectionIdx); +// final SignedReferencesListDisplayer backToListListener = new SignedReferencesListDisplayer( +// signedReferences, backListener, backCommand); + + referenceIndex = selectionIdx; + storedBackToListListener = new SignedReferencesListDisplayer( + signedReferences, backListener, backCommand); + +// if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(selection +// .getMimeType())) { +// log.debug("[" + Thread.currentThread().getName() +// + "] scheduling secure viewer dialog"); +// +// showMessageDialog(TITLE_SIGNATURE_DATA, +// MESSAGE_HASHDATA_VIEWER); +// +// SwingUtilities.invokeLater(new Runnable() { +// +// @Override +// public void run() { +// try { +// showSecureViewer(selection, backToListListener, +// null); +// // SecureViewerDialog.showSecureViewer(selection, +// // messages, fontProvider, +// // helpMouseListener.getActionListener(), +// // false); +// } catch (FontProviderException ex) { +// log +// .error( +// "failed to display secure viewer", +// ex); +// showErrorDialog(BKUGUIFacade.ERR_VIEWER, +// new Object[] { ex.getMessage() }, +// backToListListener, null); +// } +// +// } +// }); +// } else { +// log +// .debug("[" +// + Thread.currentThread().getName() +// + "] mime-type not supported by secure viewer, scheduling save dialog"); +// showMessageDialog(BKUGUIFacade.TITLE_SIGNATURE_DATA, +// BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE, +// new Object[] { selection.getMimeType() }); +// SecureViewerSaveDialog.showSaveDialog(selection, messages, +// backToListListener, null, +// (int) (baseFontSize * getResizeFactor())); +// } + } + } + + /** + * ActionListener that returns to signed references list + */ + private class SignedReferencesListDisplayer implements ActionListener { + List sr; + ActionListener bl; + String bc; + + public SignedReferencesListDisplayer( + List signedReferences, + ActionListener backListener, String backCommand) { + sr = signedReferences; + bl = backListener; + bc = backCommand; + } + + @Override + public void actionPerformed(ActionEvent e) { + // log.debug("[" + Thread.currentThread().getName() + + // "] displaying signed references list"); + showSignedReferencesListDialog(sr, bl, bc); + } + } + } + + // ////////////////////////////////////////////////////////////////////////// + // UTILITY METHODS + // ////////////////////////////////////////////////////////////////////////// + + 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) + // ////////////////////////////////////////////////////////////////////////// + + /** + * Load applet messages bundle. Note that getBundle looks for classes based + * on the default Locale before it selects the base class! + * + * Called from constructor. Subclasses may override this method to ensure + * the message bundle is loaded once initButtonSize (called from constructor + * as well) is called. (Only relevant if initButtonSize is overridden as + * well) + * + * @param locale + */ + protected void loadMessageBundle(Locale locale) { + if (locale != null) { + // see [#378] Ignoring post parameter 'locale': bundle resolve-order + // not correct?! + Locale lang = new Locale(locale.getLanguage().substring(0, 2)); + log.debug("Loading message bundle for language: {}.", lang.toString()); + messages = ResourceBundle.getBundle(MESSAGES_BUNDLE, lang); + } else { + log.debug("Loading default language message bundle."); + messages = ResourceBundle.getBundle(MESSAGES_BUNDLE); + } + + if (log.isDebugEnabled()) { + if (messages.getLocale() == null + || "".equals(messages.getLocale().getLanguage())) { + log.info("Fallback to default locale message bundle."); + } else { + log.info("Applet message bundle loaded for {}.", + messages.getLocale()); + } + } + } + + protected int initButtonSize() { + int bs = 0; + + JButton b = new JButton(); + b.setText(getMessage(BUTTON_OK)); + if (b.getPreferredSize().width > bs) { + bs = b.getPreferredSize().width; + } + // need cancel button for message dialog, + // even if renderCancelButton == false + b.setText(getMessage(BUTTON_CANCEL)); + if (b.getPreferredSize().width > bs) { + bs = b.getPreferredSize().width; + } + b.setText(getMessage(BUTTON_SIGN)); + if (b.getPreferredSize().width > bs) { + bs = b.getPreferredSize().width; + } + b.setText(getMessage(BUTTON_BACK)); + if (b.getPreferredSize().width > bs) { + bs = b.getPreferredSize().width; + } + b.setText(getMessage(BUTTON_SAVE)); + if (b.getPreferredSize().width > bs) { + bs = b.getPreferredSize().width; + } + return bs; + } @Override public void getFocusFromBrowser() { + + log.debug("Try setting focus to current component ..."); + if (primaryFocusHolder == null) { + log.debug("No stored component - set focus to contentPanel ..."); + + primaryFocusHolder = contentPanel; + + } + log.debug("Component to obtain focus: {}.", primaryFocusHolder.getName()); + primaryFocusHolder.requestFocus(); + + } + + protected void updateHelpLabelIcon() { + + if (helpListener.implementsListener()) { + + helpLabel.setIcon(new ImageIcon(getClass().getResource( + getHelpLabelResourceName()))); + + helpLabel.setBorder(helpLabel.hasFocus() ? helpFocusBorder + : BorderFactory.createEmptyBorder()); + } + + } + + protected String getHelpLabelResourceName() { + + double contentPanelWidth = contentPanel.getSize().getWidth(); + String resourceName = HELP_IMG; + + if (contentPanelWidth > 300) { + + resourceName = HELP_IMG_L; + } + + if (contentPanelWidth > 470) { + + resourceName = HELP_IMG_XL; + } + + if (contentPanelWidth > 600) { + + resourceName = HELP_IMG_XXL; + } + + return resourceName; + } + + protected float getResizeFactor() { + + if (baseWidth == null || baseHeight == null || baseWidth == 0 + || baseHeight == 0) { + + // first call - determine base width and height + baseWidth = contentPanel.getWidth(); + baseHeight = contentPanel.getHeight(); + } + + float factor = (float) contentPanel.getSize().getWidth() + / (float) baseWidth; + + return factor; + } + + public void resize() { + + log.debug("Resizing ..."); + updateHelpLabelIcon(); + + float factor = getResizeFactor(); + + this.sigDataFocusBorder.setBorderWidthFactor(factor); + this.helpFocusBorder.setBorderWidthFactor(factor); + + buttonSize = (int) ((float) baseButtonSize * factor); + + if (renderHeaderPanel) { + + titleLabel.setFont(titleLabel.getFont().deriveFont( + (float) ((baseFontSize + 2) * factor))); + } + + if (cancelButton != null) { + + cancelButton.setFont(cancelButton.getFont().deriveFont( + (float) (baseFontSize * factor))); + } + + if (pinField != null) { + pinField.setFont(pinField.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (infoLabel != null) { + infoLabel.setFont(infoLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + } + + if (pinsizeLabel != null) { + pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont( + (float) ((baseFontSize * factor) - 2))); + + } + + if (signPinLabel != null) { + + signPinLabel.setFont(signPinLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (signButton != null) { + + signButton.setFont(signButton.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (cardPinLabel != null) { + + cardPinLabel.setFont(cardPinLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (okButton != null) { + + okButton.setFont(okButton.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (pinLabel != null) { + + pinLabel.setFont(pinLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (pinpadPINField != null) { + + pinpadPINField.setFont(pinpadPINField.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (msgTitleLabel != null) { + + msgTitleLabel.setFont(msgTitleLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (msgLabel != null) { + + msgLabel.setFont(msgLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (enterPINButton != null) { + + enterPINButton.setFont(enterPINButton.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } - // This method puts the focus to the helpLabel as this - // element is supposed to appear in each dialogue. - helpLabel.requestFocus(); + if (refIdLabel != null) { + + refIdLabel.setFont(refIdLabel.getFont().deriveFont( + (float) (baseFontSize * factor))); + } + + + if (backButton != null) { + + backButton.setFont(backButton.getFont().deriveFont( + (float) (baseFontSize * factor))); + + } + + if (hyperlinkRenderer != null) { + + hyperlinkRenderer.setFontSize((int) (baseFontSize * factor)); + } + + if (hashDataTable != null) { + + hashDataTable.setRowHeight((int) (baseTableRowHeight * factor)); + + } + if (secureViewer != null && secureViewer.isVisible()) { + + secureViewer.resize(factor); + } + + try { + + if (methodToRunAtResize != null) { + log.debug("Running required button panel renderer ..."); + methodToRunAtResize.invoke(this); + } else { + log.debug("No MethodToRun stored."); + } + + } catch (IllegalArgumentException e) { + log.error("Cannot invoke rendering method.", e); + } catch (IllegalAccessException e) { + log.error("Cannot invoke rendering method.", e); + } catch (InvocationTargetException e) { + log.error("Cannot invoke rendering method.", e); + } + + contentPanel.validate(); + + log.debug("Resize done."); + + } + + // TODO: Define FocusTraversalPolicies for other GUIs as well, even if + // focus order is currently correct by chance for other GUIs + public class AdvancedSigPinGUIFocusTraversalPolicy extends + FocusTraversalPolicy { + + @Override + public Component getComponentAfter(Container container, + Component component) { + + if (component.equals(pinField)) { + + if (signButton.isEnabled()) { + + return signButton; + } else { + + return cancelButton; + } + } + + if (component.equals(signButton)) { + + return cancelButton; + } + + if (component.equals(cancelButton)) { + + return infoLabel; + } + if (component.equals(infoLabel)) { + + if (helpLabel != null && helpLabel.isVisible()) { + + return helpLabel; + } else { + + return switchFocusDummyLabel; + } + } + + if (component.equals(helpLabel)) { + + return switchFocusDummyLabel; + } + + // should never be the case + if (component.equals(switchFocusDummyLabel)) { + + return pinField; + } + + // default + return pinField; + } + + @Override + public Component getComponentBefore(Container container, + Component component) { + + if (component.equals(pinField)) { + + return switchFocusDummyLabel; + } + + if (component.equals(signButton)) { + + return pinField; + } + + if (component.equals(cancelButton)) { + + if (signButton != null && signButton.isVisible() + && signButton.isEnabled()) { + + return signButton; + + } else { + + return pinField; + } + } + + if (component.equals(infoLabel)) { + + return cancelButton; + } + + if (component.equals(helpLabel)) { + + return infoLabel; + } + + // should never be the case + if (component.equals(switchFocusDummyLabel)) { + + if (helpLabel != null && helpLabel.isVisible()) { + + return helpLabel; + } else { + + return infoLabel; + } + } + + // default + return pinField; + } + + @Override + public Component getDefaultComponent(Container container) { + + return pinField; + } + + @Override + public Component getFirstComponent(Container container) { + + return pinField; + } + + @Override + public Component getLastComponent(Container container) { + + return switchFocusDummyLabel; + } + } + + public class AdvancedShowSigDataGUIFocusTraversalPolicy extends + FocusTraversalPolicy { + + @Override + public Component getComponentAfter(Container container, + Component component) { + + if (component.equals(enterPINButton)) { + + return cancelButton; + } + + if (component.equals(cancelButton)) { + + return infoLabel; + } + if (component.equals(infoLabel)) { + + if (helpLabel != null && helpLabel.isVisible()) { + + return helpLabel; + } else { + + return switchFocusDummyLabel; + } + } + + if (component.equals(helpLabel)) { + + return switchFocusDummyLabel; + } + + // should never be the case + if (component.equals(switchFocusDummyLabel)) { + + return enterPINButton; + } + + // default + return enterPINButton; + } + + @Override + public Component getComponentBefore(Container container, + Component component) { + + if (component.equals(enterPINButton)) { + + return switchFocusDummyLabel; + } + + if (component.equals(cancelButton)) { + + return enterPINButton; + } + + if (component.equals(infoLabel)) { + + return cancelButton; + } + + if (component.equals(helpLabel)) { + + return infoLabel; + } + + // should never be the case + if (component.equals(switchFocusDummyLabel)) { + + if (helpLabel != null && helpLabel.isVisible()) { + + return helpLabel; + } else { + + return infoLabel; + } + } + + // default + return enterPINButton; + } + + @Override + public Component getDefaultComponent(Container container) { + + return enterPINButton; + } + + @Override + public Component getFirstComponent(Container container) { + + return enterPINButton; + } + + @Override + public Component getLastComponent(Container container) { + + return switchFocusDummyLabel; + } } } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUIcons.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUIcons.java index 92d6897b..b0e43291 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUIcons.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUIcons.java @@ -22,8 +22,8 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; import javax.imageio.ImageIO; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -31,24 +31,23 @@ import org.apache.commons.logging.LogFactory; */ public class BKUIcons { - protected static final Log log = LogFactory.getLog(BKUIcons.class); - - /** 16x16, 24x24, 32x32, 48x48, 128x128 pixels */ + /** 128x128, 48x48, 32x32, 24x24, 16x16 pixels */ public static final ArrayList icons = new ArrayList(); static { String[] iconResources = new String[] { - "/at/gv/egiz/bku/gui/chip16.png", - "/at/gv/egiz/bku/gui/chip24.png", - "/at/gv/egiz/bku/gui/chip32.png", + "/at/gv/egiz/bku/gui/chip128.png", "/at/gv/egiz/bku/gui/chip48.png", - "/at/gv/egiz/bku/gui/chip128.png" }; + "/at/gv/egiz/bku/gui/chip32.png", + "/at/gv/egiz/bku/gui/chip24.png", + "/at/gv/egiz/bku/gui/chip16.png"}; for (String ir : iconResources) { URL resource = BKUIcons.class.getResource(ir); if (ir != null) { try { icons.add(ImageIO.read(resource)); } catch (IOException ex) { + Logger log = LoggerFactory.getLogger(BKUIcons.class); log.warn("failed to load mocca icon " + ir, ex); } } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DeafHelpListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DeafHelpListener.java new file mode 100644 index 00000000..a4ce79b0 --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DeafHelpListener.java @@ -0,0 +1,67 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.gui; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.util.Locale; + +public class DeafHelpListener extends HelpListener { + + // localization in helpListener (pass message bundle, getLocale, add language to helpContext) or outside? + public DeafHelpListener(String helpURL, Locale locale) { + super(helpURL, locale); + } + + @Override + public boolean implementsListener() { + return false; + } + + @Override + public void mouseClicked(MouseEvent arg0) { + } + + @Override + public void keyPressed(KeyEvent arg0) { + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + } + +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DefaultHelpListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DefaultHelpListener.java deleted file mode 100644 index 032c8fe5..00000000 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/DefaultHelpListener.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package at.gv.egiz.bku.gui; - -import java.applet.AppletContext; -import java.net.URL; -import java.util.Locale; -import javax.swing.SwingUtilities; - -/** - * - * @author Clemens Orthacker - */ -public class DefaultHelpListener extends AbstractHelpListener { - - /** - * applet context to open external links in help pages, - * if null, no external links will be opened - */ - protected AppletContext ctx; - - /** - * - * @param ctx open external links via applet context - * @param helpURL - * @param locale - */ - public DefaultHelpListener(AppletContext ctx, URL helpURL, Locale locale) { - super(helpURL, locale); - this.ctx = ctx; - } - - /** - * external links in help document are not opened - * @param helpURL - * @param locale - */ - public DefaultHelpListener(URL helpURL, Locale locale) { - super(helpURL, locale); - this.ctx = null; - } - - /** - * blocks until help viewer returns (is closed) - * @param helpURL - * @param helpTopic ignored - */ - @Override - public void showDocument(final URL helpURL, final String helpTopic) { - log.debug("schedule help dialog"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("show help dialog"); - - if (ctx == null) { - HelpViewer.showHelpDialog(helpURL, messages); - } else { - HelpViewer.showHelpDialog(ctx, helpURL, messages); - } - } - }); - } -} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/FocusBorder.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/FocusBorder.java new file mode 100644 index 00000000..2c25d46b --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/FocusBorder.java @@ -0,0 +1,69 @@ +package at.gv.egiz.bku.gui; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.geom.Rectangle2D; + +import javax.swing.border.Border; + + +public class FocusBorder implements Border { + + private static final Color DEFAULT_COLOR = Color.BLACK; + + private Color color; + private float borderWidthFactor; + + public FocusBorder() { + + this.color = DEFAULT_COLOR; + this.borderWidthFactor = 1.0f; + } + + public FocusBorder(Color borderColor) { + + this.color = borderColor; + this.borderWidthFactor = 1.0f; + } + + @Override + public Insets getBorderInsets(Component c) { + + return new Insets(3, 3, 6, 6); + } + + @Override + public boolean isBorderOpaque() { + + return true; + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, + int height) { + Graphics2D g2 = (Graphics2D) g; + + g2.setPaint(color); + float[] dash1 = { 2.0f }; + + g2.setStroke(new BasicStroke(1.0f * borderWidthFactor, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f)); + + g2.draw(new Rectangle2D.Double(x + 1, y + 1, width - 6, height - 6)); + + } + + public void setColor(Color color) { + this.color = color; + } + + public void setBorderWidthFactor(float borderWidthFactor) { + + this.borderWidthFactor = borderWidthFactor; + } + +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HashDataTableModel.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HashDataTableModel.java index 70842102..320c92a9 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HashDataTableModel.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HashDataTableModel.java @@ -19,8 +19,6 @@ package at.gv.egiz.bku.gui; import at.gv.egiz.stal.HashDataInput; import java.util.List; import javax.swing.table.DefaultTableModel; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * @@ -28,10 +26,10 @@ import org.apache.commons.logging.LogFactory; */ class HashDataTableModel extends DefaultTableModel { - protected static final Log log = LogFactory.getLog(HashDataTableModel.class); - + private static final long serialVersionUID = 1L; + /** HashDataInput in first column, register hyperlinkrenderer only here */ - protected Class[] types; + protected Class[] types; protected List hashDataInputs; public HashDataTableModel(List hashDataInputs, boolean twoColLayout) { @@ -52,7 +50,7 @@ class HashDataTableModel extends DefaultTableModel { } @Override - public Class getColumnClass(int columnIndex) { + public Class getColumnClass(int columnIndex) { return types[columnIndex]; } @@ -60,4 +58,4 @@ class HashDataTableModel extends DefaultTableModel { public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } -} \ No newline at end of file +} 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 deleted file mode 100644 index 4ca20f7e..00000000 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpKeyListener.java +++ /dev/null @@ -1,46 +0,0 @@ -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 - */ -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/HelpListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpListener.java new file mode 100644 index 00000000..dc597656 --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpListener.java @@ -0,0 +1,84 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.gui; + +import java.awt.event.KeyListener; +import java.awt.event.MouseListener; +import java.util.Locale; +import java.util.ResourceBundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class HelpListener implements MouseListener, KeyListener, HelpURLProvider { + + public static final String MESSAGE_BUNDLE = "at/gv/egiz/bku/gui/Messages"; + + private final Logger log = LoggerFactory.getLogger(HelpListener.class); + private String helpURL; + protected String helpTopic; + protected ResourceBundle messageBundle; + + // localization in helpListener (pass message bundle, getLocale, add language to helpContext) or outside? + public HelpListener(String helpURL, Locale locale) { +// this.codebase = codebase; + this.helpURL = helpURL; + + if (locale != null) { + log.trace("Check for support of requested help locale {}.", locale.getLanguage().substring(0,2)); + messageBundle = ResourceBundle.getBundle(MESSAGE_BUNDLE, + new Locale(locale.getLanguage().substring(0, 2))); + } else { + messageBundle = ResourceBundle.getBundle(MESSAGE_BUNDLE); + } + if (!"".equals(messageBundle.getLocale().getLanguage())) { + log.trace("Using help locale '{}'.", messageBundle.getLocale().getLanguage().substring(0,2)); + helpURL += messageBundle.getLocale().getLanguage().substring(0,2) + '/'; + } else { + log.trace("Using help locale 'default'."); + } + + log.debug("Setting help context to {}.", helpURL); + } + + @Override + public synchronized void setHelpTopic(String topic) { + log.trace("Setting help topic: {}.", topic); + helpTopic = topic; + } + + @Override + public synchronized String getHelpURL() { + if (helpTopic == null) { + log.debug("No help topic set, return index."); + return helpURL + "index.html"; + } + String url = helpURL + helpTopic + ".html"; + log.debug("Return help topic: {}.", url); + return url; + } + + /** + * By default, HelpListener cannot handle action events and acts as (deaf) help context only. + * Subclasses may add listener functionality. + * + * Whether a listener is available so that GUI elements may be included to provide context help. + * (whether a help icon shall be included) + * @return true if this HelpListener implements the Mouse/KeyListeners + */ + public abstract boolean implementsListener(); + +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpMouseListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpMouseListener.java deleted file mode 100644 index b7bbe971..00000000 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpMouseListener.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package at.gv.egiz.bku.gui; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class HelpMouseListener extends MouseAdapter { - - protected static final Log log = LogFactory.getLog(HelpMouseListener.class); - - protected ActionListener helpListener; - protected String locale; - protected String topic; - - public HelpMouseListener(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 mouseClicked(MouseEvent arg0) { - ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, topic); - helpListener.actionPerformed(e); - } -} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpURLProvider.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpURLProvider.java new file mode 100644 index 00000000..f310705c --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HelpURLProvider.java @@ -0,0 +1,33 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package at.gv.egiz.bku.gui; + +/** + * Make current context dependent help topic available (outside the applet). + * Updated by the GUI whenever the current help topic changes. + * + * @author Clemens Orthacker + */ +public interface HelpURLProvider { + + void setHelpTopic(String helpTopic); + + String getHelpURL(); + +} 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 0f887f78..bfd797e8 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 @@ -39,8 +39,8 @@ import javax.swing.LayoutStyle; import javax.swing.SwingUtilities; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -49,7 +49,10 @@ import org.apache.commons.logging.LogFactory; public class HelpViewer extends JDialog implements ActionListener { - protected static final Log log = LogFactory.getLog(HelpViewer.class); + private static final long serialVersionUID = 1L; + + private final Logger log = LoggerFactory.getLogger(HelpViewer.class); + private static HelpViewer dialog; protected ResourceBundle messages; protected AppletContext ctx; @@ -128,7 +131,7 @@ public class HelpViewer extends JDialog } private JPanel createViewerPanel(URL helpURL) { //String viewerLabelText, - log.debug("viewer dialog: " + helpURL.toString()); + log.debug("Viewer dialog: {}.", helpURL.toString()); final JEditorPane viewer = new JEditorPane(); viewer.setEditable(false); @@ -146,7 +149,7 @@ public class HelpViewer extends JDialog final URL url = e.getURL(); if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (ctx != null) { - log.debug("open external link in help viewer: " + url); + log.debug("Open external link in help viewer: {}.", url); ctx.showDocument(url, "_blank"); } else { SwingUtilities.invokeLater(new Runnable() { diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java index 6af22815..9552bdde 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java @@ -26,10 +26,14 @@ import javax.swing.table.DefaultTableCellRenderer; */ public class HyperlinkRenderer extends DefaultTableCellRenderer { + private static final long serialVersionUID = 1L; + protected boolean renderReferenceId; + protected int fontSize; public HyperlinkRenderer(boolean renderReferenceId) { this.renderReferenceId = renderReferenceId; + this.fontSize = super.getFont().getSize(); } /** @@ -49,6 +53,13 @@ public class HyperlinkRenderer extends DefaultTableCellRenderer { } } super.setText("" + hrefText + ""); + super.setFont(super.getFont().deriveFont((float) (fontSize))); setForeground(BKUGUIFacade.HYPERLINK_COLOR); } + + public void setFontSize(int fontSize) { + + this.fontSize = fontSize; + } + } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ImagePanel.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ImagePanel.java index 6a738acb..f18bef6b 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ImagePanel.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ImagePanel.java @@ -30,6 +30,8 @@ import javax.swing.JPanel; */ public class ImagePanel extends JPanel { + private static final long serialVersionUID = 1L; + protected Image backgroundImg; public ImagePanel(URL background) { 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 b0c8ecd4..f4942a61 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 @@ -28,10 +28,6 @@ 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.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; @@ -56,8 +52,8 @@ import javax.swing.text.Document; import javax.swing.text.EditorKit; import javax.swing.text.StyledEditorKit; import javax.swing.text.html.HTMLEditorKit; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -65,7 +61,9 @@ import org.apache.commons.logging.LogFactory; */ public class SecureViewerDialog extends JDialog { - /** don't import BKUFonts in order not to load BKUFonts.jar + private static final long serialVersionUID = 1L; + +/** don't import BKUFonts in order not to load BKUFonts.jar * BKUApplet includes BKUFonts as runtime dependency only, the jar is copied to the applet dir in BKUOnline with dependency-plugin * BKUViewer has compile dependency BKUFonts, transitive in BKUOnline and BKULocal */ @@ -77,14 +75,25 @@ public class SecureViewerDialog extends JDialog { SUPPORTED_MIME_TYPES.add("application/xhtml+xml"); SUPPORTED_MIME_TYPES.add("text/html"); } - protected static final Log log = LogFactory.getLog(SecureViewerDialog.class); -// private static SecureViewerDialog dialog; + private final Logger log = LoggerFactory.getLogger(SecureViewerDialog.class); protected ResourceBundle messages; protected JEditorPane viewer; protected JLabel viewerLabel; protected JScrollPane scrollPane; - protected HashDataInput content; //remember for save dialog + protected HashDataInput content; //remember for save dialog and for resizing protected FontProvider fontProvider; + protected HelpListener helpListener; + + protected JButton closeButton; + protected JButton saveButton; + + protected int baseFontSize; + protected int baseButtonSize; + + protected float resizeFactor; + + protected ActionListener closeListener; + protected String closeCommand; /** * Create and display a modal SecureViewer dialog. @@ -95,14 +104,25 @@ public class SecureViewerDialog extends JDialog { */ public SecureViewerDialog(Frame owner, ResourceBundle messages, ActionListener closeListener, String closeCommand, - FontProvider fontProvider, ActionListener helpListener) { - super(owner, messages.getString(BKUGUIFacade.WINDOWTITLE_VIEWER), true); + FontProvider fontProvider, + HelpListener helpListener, float resizeFactor) { + super(owner, messages.getString(BKUGUIFacade.WINDOWTITLE_VIEWER), false); this.setIconImages(BKUIcons.icons); this.messages = messages; this.fontProvider = fontProvider; - + this.helpListener = helpListener; + + this.baseFontSize = new JLabel().getFont().getSize(); + + this.resizeFactor = 1.0f; + this.closeListener = closeListener; + this.closeCommand = closeCommand; + + this.resizeFactor = resizeFactor; + + initContentPane(VIEWER_DIMENSION, - createViewerPanel(helpListener), + createViewerPanel(), createButtonPanel(closeListener, closeCommand)); // also leave defaultWindowClosing HIDE_ON_CLOSE @@ -115,8 +135,28 @@ public class SecureViewerDialog extends JDialog { } else { setLocationByPlatform(true); } + + } + public void resize(float resizeFactor) { + + log.debug("Resizing secure viewer ..."); + this.resizeFactor = resizeFactor; + + getContentPane().removeAll(); + + initContentPane(VIEWER_DIMENSION, + createViewerPanel(), + createButtonPanel(closeListener, closeCommand)); + + this.setContent(content); + + getContentPane().validate(); + + + } + private void initContentPane(Dimension preferredSize, JPanel viewerPanel, JPanel buttonPanel) { Container contentPane = getContentPane(); @@ -135,9 +175,10 @@ public class SecureViewerDialog extends JDialog { /** * @param helpListener may be null */ - private JPanel createViewerPanel(final ActionListener helpListener) { + private JPanel createViewerPanel() { viewer = new JEditorPane(); viewer.setEditable(false); + viewer.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); scrollPane = new JScrollPane(); @@ -156,30 +197,13 @@ public class SecureViewerDialog extends JDialog { infoHorizontal.addComponent(viewerLabel); infoVertical.addComponent(viewerLabel); - if (helpListener != null) { + if (helpListener.implementsListener()) { 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() { - - @Override - public void mouseClicked(MouseEvent arg0) { - ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, BKUGUIFacade.HELP_HASHDATAVIEWER); - 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.addMouseListener(helpListener); + helpLabel.addKeyListener(helpListener); helpLabel.addFocusListener(new FocusAdapter() { @@ -220,7 +244,9 @@ public class SecureViewerDialog extends JDialog { */ public void setContent(HashDataInput hashDataInput) { //throws FontProviderException { - log.debug("[" + Thread.currentThread().getName() + "] set viewer content"); + log.debug("[{}] set viewer content.", Thread.currentThread().getName()); + + helpListener.setHelpTopic(BKUGUIFacade.HELP_HASHDATAVIEWER); this.content = null; viewer.setText(null); @@ -229,7 +255,7 @@ public class SecureViewerDialog extends JDialog { if (mimeType == null) { mimeType = "text/plain"; } - log.debug("secure viewer mime type: " + mimeType); + log.debug("Secure viewer mime type: {}.", mimeType); // loads editorkit for text/plain if unrecognized viewer.setContentType(mimeType); @@ -237,11 +263,11 @@ public class SecureViewerDialog extends JDialog { if ("text/plain".equals(mimeType)) { viewer.setEditorKit(new StyledEditorKit()); - viewer.setFont(fontProvider.getFont().deriveFont(Font.PLAIN, viewer.getFont().getSize())); + viewer.setFont(fontProvider.getFont().deriveFont(Font.PLAIN, viewer.getFont().getSize() * resizeFactor)); } else if ("application/xhtml+xml".equals(mimeType)) { viewer.setEditorKit(new HTMLEditorKit()); //reset font if fontprovider font was set before (TODO also html font from fontprovider) - viewer.setFont(new Font("Dialog", Font.PLAIN, viewer.getFont().getSize())); //UIManager.getFont("Label.font")); + viewer.setFont(new Font("Dialog", Font.PLAIN, (int)(viewer.getFont().getSize() * resizeFactor))); //UIManager.getFont("Label.font")); } EditorKit editorKit = viewer.getEditorKit(); @@ -249,7 +275,7 @@ public class SecureViewerDialog extends JDialog { // document.putProperty("IgnoreCharsetDirective", new Boolean(true)); Charset cs = (hashDataInput.getEncoding() == null) ? Charset.forName("UTF-8") : Charset.forName(hashDataInput.getEncoding()); - log.debug("secure viewer encoding: " + cs.toString()); + log.debug("Secure viewer encoding: {}.", cs.toString()); InputStreamReader isr = new InputStreamReader(hashDataInput.getHashDataInput(), cs); Reader contentReader = new BufferedReader(isr); @@ -270,6 +296,11 @@ public class SecureViewerDialog extends JDialog { } viewer.setCaretPosition(0); + if (viewer.getText() != null) { + viewer.getAccessibleContext().setAccessibleDescription( + viewer.getText()); + } + scrollPane.setViewportView(viewer); scrollPane.setPreferredSize(viewer.getPreferredSize()); scrollPane.setAlignmentX(LEFT_ALIGNMENT); @@ -280,21 +311,33 @@ public class SecureViewerDialog extends JDialog { viewerLabel.setText(""); } - log.debug("VIEWER FONT: " + viewer.getFont()); + viewer.setFocusable(Boolean.TRUE); + + log.debug("VIEWER FONT: {}.", viewer.getFont()); setVisible(true); toFront(); + + viewer.requestFocus(); + } private JPanel createButtonPanel(ActionListener closeListener, String closeCommand) { - JButton closeButton = new JButton(); + + closeButton = new JButton(); + closeButton.setText(messages.getString(BKUGUIFacade.BUTTON_CLOSE)); closeButton.setActionCommand(closeCommand); closeButton.addActionListener(new CloseButtonListener(closeListener)); - - JButton saveButton = new JButton(); + closeButton.setFont(closeButton.getFont().deriveFont( + (float) (baseFontSize * resizeFactor))); + + saveButton = new JButton(); saveButton.setText(messages.getString(BKUGUIFacade.BUTTON_SAVE)); saveButton.addActionListener(new SaveButtonListener()); + saveButton.setFont(saveButton.getFont().deriveFont( + (float) (baseFontSize * resizeFactor))); + int buttonSize = closeButton.getPreferredSize().width; if (saveButton.getPreferredSize().width > buttonSize) { buttonSize = saveButton.getPreferredSize().width; @@ -324,7 +367,7 @@ public class SecureViewerDialog extends JDialog { @Override public void windowClosing(WindowEvent e) { - log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer"); + log.trace("[{}] closing secure viewer.", Thread.currentThread().getName()); setVisible(false); if (closeListener != null) { closeListener.actionPerformed(new ActionEvent(e.getSource(), e.getID(), closeCommand)); @@ -342,7 +385,7 @@ public class SecureViewerDialog extends JDialog { @Override public void actionPerformed(ActionEvent e) { - log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer"); + log.trace("[{}] closing secure viewer.", Thread.currentThread().getName()); setVisible(false); if (closeListener != null) { closeListener.actionPerformed(e); @@ -354,8 +397,8 @@ public class SecureViewerDialog extends JDialog { @Override public void actionPerformed(ActionEvent e) { - log.trace("[" + Thread.currentThread().getName() + "] display secure viewer save dialog"); - SecureViewerSaveDialog.showSaveDialog(content, messages, null, null); + log.trace("[{}] display secure viewer save dialog.", Thread.currentThread().getName()); + SecureViewerSaveDialog.showSaveDialog(content, messages, null, null, closeButton.getFont().getSize()); } } } 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 index 06e37a89..66679291 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusFocusListener.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusFocusListener.java @@ -1,38 +1,44 @@ -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 - */ -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); - } - - -} +package at.gv.egiz.bku.gui; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Thomas Zefferer + */ +public class SwitchFocusFocusListener extends FocusAdapter { + + private final Logger log = LoggerFactory.getLogger(SwitchFocusFocusListener.class); + + protected ActionListener swichFocusListener; + + public SwitchFocusFocusListener(ActionListener externalSwitchFocusListener) { + super(); + this.swichFocusListener = externalSwitchFocusListener; + } + + public ActionListener getActionListener() { + return swichFocusListener; + } + + @Override + public void focusGained(FocusEvent arg0) { + + log.debug("SwitchFocusFocusListener detected focusGained event!"); + Component comp = arg0.getComponent(); + log.debug("Component that caused event: {}.", comp.getName()); + comp.transferFocus(); + + 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 index 48b641e2..171d24b8 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusListener.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SwitchFocusListener.java @@ -1,44 +1,54 @@ -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 - */ -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); - } - - - } - -} +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Thomas Zefferer + */ +public class SwitchFocusListener implements ActionListener { + + private final Logger log = LoggerFactory.getLogger(SwitchFocusListener.class); + + protected String functionName; + protected AppletContext ctx; + protected String javascriptFunction; + + public SwitchFocusListener(AppletContext ctx, String javascriptFunctionName) { + + this.ctx = ctx; + this.functionName = javascriptFunctionName; + buildJSFunction(); + } + + @Override + public void actionPerformed(ActionEvent e) { + + log.debug("SwitchFocusListener fires!"); + + try { + ctx.showDocument + (new URL("javascript:" + javascriptFunction)); + } + catch (MalformedURLException me) { + + log.warn("Unable to call external javascript function.", me); + } + + + } + + protected void buildJSFunction() { + + this.javascriptFunction = functionName + "()"; + + } + +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ViewerHelpListener.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ViewerHelpListener.java new file mode 100644 index 00000000..4860756d --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/ViewerHelpListener.java @@ -0,0 +1,101 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.gui; + +import java.applet.AppletContext; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Locale; +import javax.swing.SwingUtilities; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ViewerHelpListener extends HelpListener { + + private final Logger log = LoggerFactory.getLogger(ViewerHelpListener.class); + + protected AppletContext appletCtx; + + public ViewerHelpListener(String helpURL, Locale locale) { + super(helpURL, locale); + } + + public ViewerHelpListener(AppletContext ctx, String helpURL, Locale locale) { + super(helpURL, locale); + this.appletCtx = ctx; + } + + protected void displayHelpViewer(final String helpURL) { + log.debug("Schedule help viewer."); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log.debug("Show help viewer for {}.", helpURL); + try { + HelpViewer.showHelpDialog(appletCtx, new URL(helpURL), messageBundle); + } catch (MalformedURLException ex) { + log.error("Failed to construct help context URL.", ex); + } + } + }); + } + + @Override + public boolean implementsListener() { + return true; + } + + @Override + public void mouseClicked(MouseEvent arg0) { + displayHelpViewer(getHelpURL()); + } + + @Override + public void keyPressed(KeyEvent arg0) { + displayHelpViewer(getHelpURL()); + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + } +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/WindowCloseAdapter.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/WindowCloseAdapter.java new file mode 100644 index 00000000..ad798aed --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/WindowCloseAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.gui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Clemens Orthacker + */ +public class WindowCloseAdapter extends WindowAdapter { + + private final Logger log = LoggerFactory.getLogger(WindowCloseAdapter.class); + + protected ActionListener closeListener; + protected String closeCommand; + + void registerListener(ActionListener closeListener, String closeCommand) { + log.debug("Register close listener for action command {}.", closeCommand); + this.closeListener = closeListener; + this.closeCommand = closeCommand; + } + + @Override + public void windowClosing(WindowEvent e) { + log.debug("Received window closing event: {}.", e.paramString()); + + if (closeListener != null) { + log.debug("Notifying closeListener ..."); + closeListener.actionPerformed(new ActionEvent(e.getSource(), e.getID(), closeCommand)); + } + } + + +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/html/RestrictedHTMLEditorKit.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/html/RestrictedHTMLEditorKit.java index 680bf1a4..2ae8f87e 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/html/RestrictedHTMLEditorKit.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/html/RestrictedHTMLEditorKit.java @@ -29,7 +29,8 @@ import javax.swing.text.html.HTMLEditorKit; */ public class RestrictedHTMLEditorKit extends HTMLEditorKit { - + private static final long serialVersionUID = 1L; + public static class RestrictedHTMLFactory extends HTMLFactory { @Override diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/FontProviderException.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/FontProviderException.java index 5a6a277e..ee9b05de 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/FontProviderException.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/FontProviderException.java @@ -23,6 +23,8 @@ package at.gv.egiz.bku.gui.viewer; */ public class FontProviderException extends Exception { + private static final long serialVersionUID = 1L; + public FontProviderException(String msg, Throwable cause) { super(msg, cause); } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java index 3303d4ef..335a8599 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java @@ -1,5 +1,8 @@ package at.gv.egiz.bku.gui.viewer; +import java.awt.Component; +import java.awt.Container; +import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedOutputStream; @@ -8,39 +11,51 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.MessageFormat; -import java.util.Locale; import java.util.ResourceBundle; import javax.swing.JFileChooser; +import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; +import javax.swing.UIManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.gui.BKUGUIFacade; import at.gv.egiz.stal.HashDataInput; public class SecureViewerSaveDialog { - protected static final Log log = LogFactory.getLog(SecureViewerSaveDialog.class); - + private static void setFileChooserFont(Component[] comp, Font font) { + for (int i = 0; i < comp.length; i++) { + if (comp[i] instanceof Container) + setFileChooserFont(((Container) comp[i]).getComponents(), font); + try { + comp[i].setFont(font); + } catch (Exception e) { + Logger log = LoggerFactory.getLogger(SecureViewerSaveDialog.class); + log.warn("FileChooser component font could not be set"); + } + } + } + public static void showSaveDialog(final HashDataInput hashDataInput, final ResourceBundle messages, - final ActionListener okListener, final String okCommand) { - - log.debug("[" + Thread.currentThread().getName() - + "] scheduling save dialog"); + final ActionListener okListener, final String okCommand, final int fontSize) { + + final Logger log = LoggerFactory.getLogger(SecureViewerSaveDialog.class); + log.debug("[{}] Scheduling save dialog.", Thread.currentThread().getName()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - log - .debug("[" + Thread.currentThread().getName() - + "] show save dialog"); + log.debug("[{}] Show save dialog.", Thread.currentThread().getName()); String userHome = System.getProperty("user.home"); + + UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); JFileChooser fileDialog = new JFileChooser(userHome); fileDialog.setMultiSelectionEnabled(false); @@ -58,6 +73,9 @@ public class SecureViewerSaveDialog { + MimeFilter.getExtension(mimeType); fileDialog.setSelectedFile(new File(userHome, filename)); + setFileChooserFont(fileDialog.getComponents(), new JLabel() + .getFont().deriveFont((float) fontSize)); + // parent contentPane -> placed over applet switch (fileDialog.showSaveDialog(fileDialog)) { case JFileChooser.APPROVE_OPTION: @@ -75,8 +93,8 @@ public class SecureViewerSaveDialog { } } if (log.isDebugEnabled()) { - log.debug("writing hashdata input " + id + " (" + mimeType - + ") to file " + file); + Object[] args = {id, mimeType, file}; + log.debug("Writing hashdata input {} ({}) to file {}.", args); } FileOutputStream fos = null; try { @@ -90,8 +108,7 @@ public class SecureViewerSaveDialog { bos.flush(); bos.close(); } catch (IOException ex) { - log.error("Failed to write " + file + ": " + ex.getMessage()); - log.debug(ex); + log.error("Failed to write.", ex); String errPattern = messages .getString(BKUGUIFacade.ERR_WRITE_HASHDATA); JOptionPane.showMessageDialog(fileDialog, MessageFormat.format( @@ -108,7 +125,7 @@ public class SecureViewerSaveDialog { } break; case JFileChooser.CANCEL_OPTION: - log.debug("cancelled save dialog"); + log.debug("Cancelled save dialog."); break; } if (okListener != null) { diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java b/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java index b9416845..7f76619f 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java @@ -21,8 +21,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -30,7 +30,7 @@ import org.apache.commons.logging.LogFactory; */ public class ByteArrayHashDataInput implements HashDataInput { - private static final Log log = LogFactory.getLog(ByteArrayHashDataInput.class); + private final Logger log = LoggerFactory.getLogger(ByteArrayHashDataInput.class); protected byte[] hashData; protected String id; @@ -66,7 +66,7 @@ public class ByteArrayHashDataInput implements HashDataInput { } this.hashData = baos.toByteArray(); } catch (IOException ex) { - log.error("Failed to cache provided HashDataInput: " + ex.getMessage(), ex); + log.error("Failed to cache provided HashDataInput: {}.", ex.getMessage(), ex); this.hashData = new byte[0]; } this.id = hdi.getReferenceId(); 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 c09433de..ac8b2777 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 @@ -49,7 +49,7 @@ hashdatalink.tiny.focus=[Signaturdaten] #verwenden sie bitte die von ihrem System zur Verf\u00FCgung gestellte {0} Anwendung. hashdatalist={0} Signaturdaten: hashdata.viewer=Signaturdaten werden im Betrachter angezeigt -unsupported.mimetype=Signaturdaten k\u00F6nnen nicht angezeigt werden +unsupported.mimetype=Signaturdaten speichern und mit einem geeigneten {0} Betrachter \u00F6ffnen. retries.last=Letzter Versuch! retries=Noch {0} Versuche retries.pinpad.last=Eingabe wiederholen, letzter Versuch! @@ -76,6 +76,7 @@ mimetype.desc.doc=Microsoft Word-Dateien (.doc) mimetype.desc.unknown=Alle Dateien (.*) save.hashdatainput.prefix=Signaturdaten alt.help=Hilfe +dialog.sigpin.infolabel.sigdata.tooltiptext=Signaturdaten in neuem Fenster anzeigen # Error Messages error.no.hashdata=Keine Signaturdaten verf\u00FCgbar: {0} 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 4d86d21b..6381bdf9 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 @@ -47,7 +47,7 @@ hashdatalink.tiny.focus=[signature data] #message.hashdata=Remark: This is a preview of the data to-be signed. For standards compliant display see help. hashdatalist={0} signature data objects: hashdata.viewer=Signature data is being displayed in viewer -unsupported.mimetype=Signature data cannot be displayed +unsupported.mimetype=Save and open signature data with appropriate {0} viewer. retries.last=Last try! retries={0} tries left retries.pinpad.last=Re-enter pin, last try! @@ -74,6 +74,8 @@ mimetype.desc.doc=Microsoft Word-files (.doc) mimetype.desc.unknown=All files (.*) save.hashdatainput.prefix=signaturedata alt.help=help +dialog.sigpin.infolabel.sigdata.tooltiptext=Show signature data in new window + # Error Messages error.no.hashdata=No signature data available: {0} -- cgit v1.2.3