/* * codjo.net * * Common Apache License 2.0 */ package net.codjo.gui; import java.awt.Component; import java.awt.Toolkit; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.beans.VetoableChangeListener; import javax.swing.JInternalFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; /** * Classe utilitaire permettant de simuler le mode Modal pour une JInternalFrame. * * @version $Revision: 1.4 $ * * */ public class Modal { private JPanel glassPanel = new JPanel(); private ModalKeyFeedback keyFeedback = new ModalKeyFeedback(); private JInternalFrame modalFrame; private ModalMouseFeedback mouseFeedback = new ModalMouseFeedback(); private Component oldGlassPane = null; private JInternalFrame parentFrame; private ParentVetoListener parentVeto = new ParentVetoListener(); private boolean parentWasClosable; /** * Constructeur de Modal. * * @param parentFrame Fenetre parente a la fenetre modal * @param modalFrame La fenetre modal */ public Modal(JInternalFrame parentFrame, JInternalFrame modalFrame) { this.parentFrame = parentFrame; this.modalFrame = modalFrame; modalFrame.addInternalFrameListener(new ModalStateUpdater()); if (modalFrame.isShowing()) { addModalRestriction(); } glassPanel.setOpaque(false); glassPanel.addKeyListener(keyFeedback); glassPanel.addMouseListener(mouseFeedback); } /** * Ajoute une restriction Modal */ private void addModalRestriction() { oldGlassPane = parentFrame.getGlassPane(); parentFrame.setGlassPane(glassPanel); parentFrame.addVetoableChangeListener(parentVeto); modalFrame.setLayer(JLayeredPane.MODAL_LAYER); parentWasClosable = parentFrame.isClosable(); parentFrame.setClosable(false); } /** * Enleve la restriction modal */ private void removeModalRestriction() { parentFrame.remove(glassPanel); parentFrame.setGlassPane(oldGlassPane); parentFrame.removeVetoableChangeListener(parentVeto); parentFrame.setClosable(parentWasClosable); } /** * Realise un retour auditif de l'echec d'un evt clavier sur la fenetre parente. * * @author $Author: acharif $ * @version $Revision: 1.4 $ */ private static class ModalKeyFeedback extends KeyAdapter { public void keyTyped(KeyEvent e) { Toolkit.getDefaultToolkit().beep(); } } /** * Realise un retour auditif de l'echec d'un click sur la fenetre parente. * * @author $Author: acharif $ * @version $Revision: 1.4 $ */ private static class ModalMouseFeedback extends MouseAdapter { public void mouseClicked(MouseEvent e) { Toolkit.getDefaultToolkit().beep(); } } /** * Listener mettant a jours la modalite en fonction de l'etat d'ouverture de la * fenetre modal. * * @author $Author: acharif $ * @version $Revision: 1.4 $ */ private class ModalStateUpdater extends InternalFrameAdapter { public void internalFrameClosed(InternalFrameEvent evt) { removeModalRestriction(); try { parentFrame.setSelected(true); } catch (PropertyVetoException ex) {} } // TEMP public void internalFrameClosing(InternalFrameEvent evt) { internalFrameClosed(evt); } // END TEMP public void internalFrameOpened(InternalFrameEvent evt) { addModalRestriction(); } } /** * Empeche la fenetre parente d'etre selectionner. * * @author $Author: acharif $ * @version $Revision: 1.4 $ */ private class ParentVetoListener implements VetoableChangeListener { public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { if ("selected".equals(evt.getPropertyName()) && Boolean.TRUE.equals(evt.getNewValue())) { modalFrame.setSelected(true); throw new PropertyVetoException("En cours d'edition", evt); } if ("icon".equals(evt.getPropertyName())) { // modalFrame.setIcon(Boolean.TRUE.equals(evt.getNewValue())); modalFrame.setVisible(Boolean.FALSE.equals(evt.getNewValue())); } } } }