View Javadoc
1   package fr.ifremer.quadrige3.ui.swing.synchro;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 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.quadrige3.synchro.vo.SynchroProgressionStatus;
28  import fr.ifremer.quadrige3.ui.swing.ApplicationUI;
29  import fr.ifremer.quadrige3.ui.swing.ApplicationUIContext;
30  import fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil;
31  import jaxx.runtime.SwingUtil;
32  import jaxx.runtime.swing.ComponentMover;
33  import org.jdesktop.swingx.JXTitledPanel;
34  
35  import javax.swing.*;
36  import java.awt.Component;
37  import java.awt.Dimension;
38  import java.awt.Point;
39  import java.awt.event.*;
40  
41  import static org.nuiton.i18n.I18n.t;
42  
43  /**
44   * <p>SynchroWidget class.</p>
45   *
46   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
47   */
48  public class SynchroWidget extends JToggleButton {
49  
50      protected final ApplicationUIContext context;
51  
52      protected JDialog popup; // = new JDialog();
53      private Point popupPosition = null;
54      private Point parentPosition = null;
55      /** Constant <code>CLOSE_DIALOG_ACTION="closeDialog"</code> */
56      public static final String CLOSE_DIALOG_ACTION = "closeDialog";
57  
58      /**
59       * <p>Constructor for SynchroWidget.</p>
60       *
61       * @param parentUI a {@link ApplicationUI} object.
62       */
63      public SynchroWidget(ApplicationUI parentUI) {
64          super(SwingUtil.createActionIcon("update-referential"));
65          setToolTipText(t("quadrige3.synchroWidget.alert.none"));
66  
67          context = ApplicationUIContext.getInstance();
68  
69          setEnabled(context.isAuthenticated());
70  
71          context.addPropertyChangeListener(ApplicationUIContext.PROPERTY_AUTHENTICATED, evt -> setEnabled(context.isAuthenticated()));
72  
73          SynchroUI synchroUI = new SynchroUI(parentUI);
74  
75          // register the ui in context
76          context.setSynchroUI(synchroUI);
77  
78          synchroUI.getModel().addPropertyChangeListener(evt -> {
79              if (null != evt.getPropertyName()) {
80                  switch (evt.getPropertyName()) {
81                      case SynchroUIContext.PROPERTY_PROGRESSION_STATUS:
82                          // change icon
83                          SynchroProgressionStatus status = (SynchroProgressionStatus) evt.getNewValue();
84                          switch (status) {
85                              case RUNNING:
86                                  setIcon(SwingUtil.createImageIcon("loading.gif"));
87                                  setToolTipText(t("quadrige3.synchroWidget.alert.running"));
88                                  break;
89                              case SUCCESS:
90                                  setIcon(SwingUtil.createImageIcon("flash-green.gif"));
91                                  setToolTipText(t("quadrige3.synchroWidget.alert.success"));
92                                  break;
93                              case FAILED:
94                                  setIcon(SwingUtil.createImageIcon("flash-red.gif"));
95                                  setToolTipText(t("quadrige3.synchroWidget.alert.failed"));
96                                  break;
97                              case NOT_STARTED:
98                              case STOPPED:
99                              default:
100                                 setIcon(SwingUtil.createActionIcon("update-referential"));
101                                 setToolTipText(t("quadrige3.synchroWidget.alert.none"));
102                                 break;
103                         }
104                         break;
105                     case SynchroUIContext.PROPERTY_SYNCHRO_TITLE:
106                         // change popup title
107                         String title = (String) evt.getNewValue();
108                         if (title != null) {
109                             popup.setTitle(title);
110                         }
111                         else {
112                             popup.setTitle(t("quadrige3.synchroWidget.title"));
113                         }
114                         break;
115                 }
116             }
117         });
118 
119         Dimension size = new Dimension(500, 120);
120         synchroUI.setPreferredSize(size);
121         
122         popup = new JDialog() {
123 
124             @Override
125             public void setVisible(boolean b) {
126                 if (!SynchroWidget.this.isShowing()) {
127                     return;
128                 }
129 
130                 super.setVisible(b);
131 
132                 if (popupPosition == null) {
133                     // init first time position
134                     popupPosition = new Point(SynchroWidget.this.getLocationOnScreen().x + SynchroWidget.this.getWidth() - getWidth(),
135                         SynchroWidget.this.getLocationOnScreen().y - getHeight());
136                     setLocation(popupPosition);
137                 }
138                 
139                 // position correction
140                 ApplicationUIUtil.setComponentLocationOnScreen(this, popupPosition);
141                 
142                 toFront();
143             }
144         };
145         final JXTitledPanel titledPanel = new JXTitledPanel(t("quadrige3.synchroWidget.title"), synchroUI); //scrollPanel);
146         popup.add(titledPanel);
147         popup.setTitle(t("quadrige3.synchroWidget.title"));
148         popup.setSize(size);
149         popup.setPreferredSize(size);
150         popup.setAlwaysOnTop(true);
151         popup.setUndecorated(true);
152         
153 
154         popup.addPropertyChangeListener("title", evt -> titledPanel.setTitle((String) evt.getNewValue()));
155         
156         ComponentMover cm = new ComponentMover();
157         cm.registerComponent(popup);
158 
159         popup.addWindowListener(new WindowAdapter() {
160 
161             @Override
162             public void windowClosing(WindowEvent e) {
163                 setSelected(false);
164             }
165 
166         });
167 
168         popup.addComponentListener(new ComponentAdapter() {
169 
170             @Override
171             public void componentMoved(ComponentEvent e) {
172                 Component component = e.getComponent();
173                 if (component.isShowing()) {
174                     popupPosition = component.getLocationOnScreen();
175                 }
176             }
177 
178         });
179 
180         addActionListener(e -> {
181             if (isSelected()) {
182                 popup.setVisible(true);
183             }
184             else {
185                 popup.dispose();
186             }
187         });
188 
189         addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
190 
191             @Override
192             public void ancestorMoved(HierarchyEvent e) {
193                 if (e.getID() == HierarchyEvent.ANCESTOR_MOVED) {
194                     if (parentPosition == null && isShowing()) {
195                         parentPosition = getLocationOnScreen();
196                     }
197                     if (popupPosition != null && isShowing() && popup.isShowing()) {
198                         Point newParentPosition = getLocationOnScreen();
199                         popupPosition.translate(newParentPosition.x - parentPosition.x, newParentPosition.y - parentPosition.y);
200                         parentPosition = newParentPosition;
201                         ApplicationUIUtil.setComponentLocationOnScreen(popup, popupPosition);
202                     }
203                 }
204             }
205         });
206 
207         // add a auto-close action
208         JRootPane rootPane = popup.getRootPane();
209 
210         KeyStroke shortcutClosePopup = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
211         rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcutClosePopup, CLOSE_DIALOG_ACTION);
212 
213         Action closeAction = new AbstractAction() {
214             private static final long serialVersionUID = 1L;
215 
216             @Override
217             public void actionPerformed(ActionEvent e) {
218                 popup.dispose();
219                 setSelected(false);
220             }
221         };
222 
223         ImageIcon actionIcon = SwingUtil.createActionIcon("close-dialog");
224         closeAction.putValue(Action.SMALL_ICON, actionIcon);
225         closeAction.putValue(Action.LARGE_ICON_KEY, actionIcon);
226         closeAction.putValue(Action.ACTION_COMMAND_KEY, "close");
227         closeAction.putValue(Action.NAME, "close");
228         closeAction.putValue(Action.SHORT_DESCRIPTION, t("validator.messageWidget.closeDialog.tip"));
229 
230         rootPane.getActionMap().put(CLOSE_DIALOG_ACTION, closeAction);
231 
232         JButton closeButton = new JButton(closeAction);
233         closeButton.setText(null);
234         closeButton.setFocusPainted(false);
235         closeButton.setRequestFocusEnabled(false);
236         closeButton.setFocusable(false);
237 
238         JToolBar jToolBar = new JToolBar();
239         jToolBar.setOpaque(false);
240         jToolBar.add(closeAction);
241         jToolBar.setBorderPainted(false);
242         jToolBar.setFloatable(false);
243         titledPanel.setRightDecoration(jToolBar);
244 
245     }
246 
247     /** {@inheritDoc} */
248     @Override
249     public void setIcon(Icon defaultIcon) {
250         super.setIcon(defaultIcon);
251         setPressedIcon(defaultIcon);
252         setSelectedIcon(defaultIcon);
253         setRolloverIcon(defaultIcon);
254         setRolloverSelectedIcon(defaultIcon);
255     }
256 
257     /**
258      * <p>showPopup.</p>
259      */
260     public void showPopup() {
261         popup.setVisible(true);
262         setSelected(true);
263     }
264 
265     /**
266      * <p>hidePopup.</p>
267      */
268     public void hidePopup() {
269         popup.dispose();
270         setSelected(false);
271     }
272 
273     /**
274      * <p>pack.</p>
275      */
276     public void pack() {
277         popup.pack();
278     }
279 }