View Javadoc
1   package fr.ifremer.quadrige3.ui.swing.plaf;
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  import org.jdesktop.jxlayer.JXLayer;
27  import org.jdesktop.jxlayer.plaf.AbstractLayerUI;
28  
29  import javax.swing.JComponent;
30  import javax.swing.Timer;
31  import java.awt.*;
32  import java.awt.event.ActionEvent;
33  import java.awt.event.ActionListener;
34  import java.awt.event.MouseEvent;
35  
36  /**
37   * A JXLayer ui implementation that permits to block a component
38   *
39   * @author Ludovic - ludovic.pecquot@e-is.pro
40   */
41  public class ComponentBlockingLayerUI extends AbstractLayerUI<JComponent> implements ActionListener {
42  
43      /** Constant <code>BLOCK_PROPERTY="block"</code> */
44      public static final String BLOCK_PROPERTY = "block";
45  
46      /**
47       * Optional color to put fill background when blocking
48       */
49      private Color blockingColor = Color.BLACK;
50  
51      /**
52       * Internal state when should block event and paint layer
53       */
54      private boolean block;
55      boolean running;
56      boolean started;
57      private boolean fadingOut;
58  
59      private Timer timer;
60      private float fadeCount;
61      /** Constant <code>FPS=24</code> */
62      private static final int FPS = 24;
63      /** Constant <code>FADE_LIMIT=5f</code> */
64      private static final float FADE_LIMIT = 5f;
65      /** Constant <code>DELAY=100</code> */
66      private static final int DELAY = 100;
67  
68      /**
69       * <p>Constructor for ComponentBlockingLayerUI.</p>
70       */
71      public ComponentBlockingLayerUI() {
72      }
73  
74      /**
75       * <p>Setter for the field <code>block</code>.</p>
76       *
77       * @param block a boolean.
78       */
79      public void setBlock(boolean block) {
80          boolean oldValue = this.block;
81          this.block = block;
82          firePropertyChange(BLOCK_PROPERTY, oldValue, block);
83          if (oldValue != block) {
84              setDirty(true);
85              if (block) {
86                  start();
87              } else {
88                  stop();
89              }
90          }
91      }
92  
93      /**
94       * <p>Setter for the field <code>blockingColor</code>.</p>
95       *
96       * @param blockingColor a {@link Color} object.
97       */
98      public void setBlockingColor(Color blockingColor) {
99          this.blockingColor = blockingColor;
100     }
101 
102     /** {@inheritDoc} */
103     @Override
104     protected void paintLayer(Graphics2D g2, JXLayer<? extends JComponent> l) {
105         super.paintLayer(g2, l);
106         if (!running || !started) {
107             return;
108         }
109 
110         // Gray it out.
111         Composite urComposite = g2.getComposite();
112         g2.setColor(blockingColor);
113         float alpha = .25f * getFade();
114         g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
115         g2.fillRect(0, 0, l.getWidth(), l.getHeight());
116         g2.setComposite(urComposite);
117 
118     }
119 
120     protected float getFade() {
121         return fadeCount / FADE_LIMIT;
122     }
123 
124     /** {@inheritDoc} */
125     @Override
126     public void actionPerformed(ActionEvent e) {
127         if (running) {
128             started = true;
129             setDirty(true);
130             if (fadingOut) {
131                 if (--fadeCount <= 0) {
132                     running = false;
133                     started = false;
134                     timer.stop();
135                 }
136             } else if (fadeCount < FADE_LIMIT) {
137                 fadeCount++;
138             }
139         }
140     }
141 
142     /**
143      * <p>start.</p>
144      */
145     public void start() {
146         if (running) {
147             return;
148         }
149 
150         // Run a thread for animation.
151         running = true;
152         started = false;
153         fadingOut = false;
154         fadeCount = 0;
155         int tick = FPS / 1000;
156         timer = new Timer(tick, this);
157         timer.setInitialDelay(DELAY);
158         timer.start();
159     }
160 
161     /**
162      * <p>stop.</p>
163      */
164     public void stop() {
165         if (started) {
166             fadingOut = true;
167         } else {
168             running = false;
169             timer.stop();
170         }
171     }
172 
173     /** {@inheritDoc} */
174     @Override
175     protected void processMouseEvent(MouseEvent e, JXLayer<? extends JComponent> l) {
176         if (running) {
177             e.consume();
178             return;
179         }
180         super.processMouseEvent(e, l);
181     }
182 }
183