View Javadoc
1   package fr.ifremer.quadrige2.ui.swing.common.synchro;
2   
3   /*-
4    * #%L
5    * Quadrige2 Core :: Quadrige2 UI Common
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  
27  import fr.ifremer.quadrige2.synchro.vo.SynchroProgressionStatus;
28  import fr.ifremer.quadrige2.ui.swing.common.ApplicationUI;
29  import fr.ifremer.quadrige2.ui.swing.common.ApplicationUIContext;
30  import fr.ifremer.quadrige2.ui.swing.common.ApplicationUIUtil;
31  import jaxx.runtime.SwingUtil;
32  import jaxx.runtime.swing.ComponentMover;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.jdesktop.swingx.JXTitledPanel;
36  
37  import javax.swing.*;
38  import java.awt.Component;
39  import java.awt.Dimension;
40  import java.awt.Point;
41  import java.awt.event.*;
42  import java.beans.PropertyChangeEvent;
43  import java.beans.PropertyChangeListener;
44  
45  import static org.nuiton.i18n.I18n.t;
46  
47  /**
48   * <p>SynchroWidget class.</p>
49   *
50   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
51   */
52  public class SynchroWidget extends JToggleButton {
53  
54      private static final Log log = LogFactory.getLog(SynchroWidget.class);
55  
56      protected final ApplicationUIContext context;
57      protected final SynchroUI synchroUI;
58  
59      protected JDialog popup; // = new JDialog();
60      protected Point popupPosition = null;
61      protected Point parentPosition = null;
62      /** Constant <code>CLOSE_DIALOG_ACTION="closeDialog"</code> */
63      public static final String CLOSE_DIALOG_ACTION = "closeDialog";
64  
65      /**
66       * <p>Constructor for SynchroWidget.</p>
67       *
68       * @param parentUI a {@link fr.ifremer.quadrige2.ui.swing.common.ApplicationUI} object.
69       */
70      public SynchroWidget(ApplicationUI parentUI) {
71          super(SwingUtil.createActionIcon("update-referential"));
72          setToolTipText(t("quadrige2.synchroWidget.alert.none"));
73  
74          context = ApplicationUIContext.getInstance();
75  
76          setEnabled(context.isAuthenticated());
77  
78          context.addPropertyChangeListener(ApplicationUIContext.PROPERTY_AUTHENTICATED, new PropertyChangeListener() {
79  
80              @Override
81              public void propertyChange(PropertyChangeEvent evt) {
82                  setEnabled(context.isAuthenticated());
83              }
84          });
85  
86          synchroUI = new SynchroUI(parentUI);
87  
88          // register the ui in context
89          context.setSynchroUI(synchroUI);
90  
91          synchroUI.getModel().addPropertyChangeListener(new PropertyChangeListener() {
92  
93              @Override
94              public void propertyChange(PropertyChangeEvent evt) {
95                  if (null != evt.getPropertyName()) {
96                      switch (evt.getPropertyName()) {
97                          case SynchroUIContext.PROPERTY_PROGRESSION_STATUS:
98                              // change icon
99                              SynchroProgressionStatus status = (SynchroProgressionStatus) evt.getNewValue();
100                             switch (status) {
101                                 case RUNNING:
102                                     setIcon(SwingUtil.createImageIcon("loading.gif"));
103                                     setToolTipText(t("quadrige2.synchroWidget.alert.running"));
104                                     break;
105                                 case SUCCESS:
106                                     setIcon(SwingUtil.createImageIcon("flash-green.gif"));
107                                     setToolTipText(t("quadrige2.synchroWidget.alert.success"));
108                                     break;
109                                 case FAILED:
110                                     setIcon(SwingUtil.createImageIcon("flash-red.gif"));
111                                     setToolTipText(t("quadrige2.synchroWidget.alert.failed"));
112                                     break;
113                                 case NOT_STARTED:
114                                 case STOPPED:
115                                 default:
116                                     setIcon(SwingUtil.createActionIcon("update-referential"));
117                                     setToolTipText(t("quadrige2.synchroWidget.alert.none"));
118                                     break;
119                             }
120                             break;
121                         case SynchroUIContext.PROPERTY_SYNCHRO_TITLE:
122                             // change popup title
123                             String title = (String) evt.getNewValue();
124                             if (title != null) {
125                                 popup.setTitle(title);
126                             }
127                             else {
128                                 popup.setTitle(t("quadrige2.synchroWidget.title"));
129                             }
130                             break;
131                     }
132                 }
133             }
134         });
135 
136         Dimension size = new Dimension(500, 120);
137         synchroUI.setPreferredSize(size);
138         
139         popup = new JDialog() {
140 
141             @Override
142             public void setVisible(boolean b) {
143                 if (!SynchroWidget.this.isShowing()) {
144                     return;
145                 }
146 
147                 super.setVisible(b);
148 
149                 if (popupPosition == null) {
150                     // init first time position
151                     popupPosition = new Point(SynchroWidget.this.getLocationOnScreen().x + SynchroWidget.this.getWidth() - getWidth(),
152                         SynchroWidget.this.getLocationOnScreen().y - getHeight());
153                     setLocation(popupPosition);
154                 }
155                 
156                 // position correction
157                 ApplicationUIUtil.setComponentLocationOnScreen(this, popupPosition);
158                 
159                 toFront();
160             }
161         };
162         final JXTitledPanel titledPanel = new JXTitledPanel(t("quadrige2.synchroWidget.title"), synchroUI); //scrollPanel);
163         popup.add(titledPanel);
164         popup.setTitle(t("quadrige2.synchroWidget.title"));
165         popup.setSize(size);
166         popup.setPreferredSize(size);
167         popup.setAlwaysOnTop(true);
168         popup.setUndecorated(true);
169         
170 
171         popup.addPropertyChangeListener("title", new PropertyChangeListener() {
172 
173             @Override
174             public void propertyChange(PropertyChangeEvent evt) {
175                 titledPanel.setTitle((String) evt.getNewValue());
176             }
177         });
178         
179         ComponentMover cm = new ComponentMover();
180         cm.registerComponent(popup);
181 
182         popup.addWindowListener(new WindowAdapter() {
183 
184             @Override
185             public void windowClosing(WindowEvent e) {
186                 setSelected(false);
187             }
188 
189         });
190 
191         popup.addComponentListener(new ComponentAdapter() {
192 
193             @Override
194             public void componentMoved(ComponentEvent e) {
195                 Component component = e.getComponent();
196                 if (component.isShowing()) {
197                     popupPosition = component.getLocationOnScreen();
198                 }
199             }
200 
201         });
202 
203         addActionListener(new ActionListener() {
204 
205             @Override
206             public void actionPerformed(ActionEvent e) {
207                 if (isSelected()) {
208                     popup.setVisible(true);
209                 }
210                 else {
211                     popup.dispose();
212                 }
213             }
214         });
215 
216         addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
217 
218             @Override
219             public void ancestorMoved(HierarchyEvent e) {
220                 if (e.getID() == HierarchyEvent.ANCESTOR_MOVED) {
221                     if (parentPosition == null && isShowing()) {
222                         parentPosition = getLocationOnScreen();
223                     }
224                     if (popupPosition != null && isShowing() && popup.isShowing()) {
225                         Point newParentPosition = getLocationOnScreen();
226                         popupPosition.translate(newParentPosition.x - parentPosition.x, newParentPosition.y - parentPosition.y);
227                         parentPosition = newParentPosition;
228                         ApplicationUIUtil.setComponentLocationOnScreen(popup, popupPosition);
229                     }
230                 }
231             }
232         });
233 
234         // add a auto-close action
235         JRootPane rootPane = popup.getRootPane();
236 
237         KeyStroke shortcutClosePopup = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
238         rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcutClosePopup, CLOSE_DIALOG_ACTION);
239 
240         Action closeAction = new AbstractAction() {
241             private static final long serialVersionUID = 1L;
242 
243             @Override
244             public void actionPerformed(ActionEvent e) {
245                 popup.dispose();
246                 setSelected(false);
247             }
248         };
249 
250         ImageIcon actionIcon = SwingUtil.createActionIcon("close-dialog");
251         closeAction.putValue(Action.SMALL_ICON, actionIcon);
252         closeAction.putValue(Action.LARGE_ICON_KEY, actionIcon);
253         closeAction.putValue(Action.ACTION_COMMAND_KEY, "close");
254         closeAction.putValue(Action.NAME, "close");
255         closeAction.putValue(Action.SHORT_DESCRIPTION, t("validator.messageWidget.closeDialog.tip"));
256 
257         rootPane.getActionMap().put(CLOSE_DIALOG_ACTION, closeAction);
258 
259         JButton closeButton = new JButton(closeAction);
260         closeButton.setText(null);
261         closeButton.setFocusPainted(false);
262         closeButton.setRequestFocusEnabled(false);
263         closeButton.setFocusable(false);
264 
265         JToolBar jToolBar = new JToolBar();
266         jToolBar.setOpaque(false);
267         jToolBar.add(closeAction);
268         jToolBar.setBorderPainted(false);
269         jToolBar.setFloatable(false);
270         titledPanel.setRightDecoration(jToolBar);
271 
272     }
273 
274     /** {@inheritDoc} */
275     @Override
276     public void setIcon(Icon defaultIcon) {
277         super.setIcon(defaultIcon);
278         setPressedIcon(defaultIcon);
279         setSelectedIcon(defaultIcon);
280         setRolloverIcon(defaultIcon);
281         setRolloverSelectedIcon(defaultIcon);
282     }
283 
284     /**
285      * <p>showPopup.</p>
286      */
287     public void showPopup() {
288         popup.setVisible(true);
289         setSelected(true);
290     }
291 
292     /**
293      * <p>hidePopup.</p>
294      */
295     public void hidePopup() {
296         popup.dispose();
297         setSelected(false);
298     }
299 
300     /**
301      * <p>pack.</p>
302      */
303     public void pack() {
304         popup.pack();
305     }
306 }