Précédent   Forum du club des développeurs et IT Pro > Java > Communauté Java > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, et autres ressources pour la rubrique Java.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 08/06/2008, 00h59   #1
divxdede
Membre expérimenté
 
Avatar de divxdede
 
Sébastien André
Inscription : avril 2004
Messages : 496
Détails du profil
Informations personnelles :
Nom : Sébastien André
Âge : 35
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2004
Messages : 496
Points : 552
Points : 552
Envoyer un message via ICQ à divxdede
Par défaut [SwingX] Utilitaire pour afficher un état "Occupé"

Bonjour,
Pour un petit programme, j'ai écrit une classe permettant facilement d'indiquer qu'un composant est indisponible le temps qu'une tâche de fonds s'éxecute.

Cette classe utilise en interne une JXBusyLabel de SwingX (requis pour fonctionner).

L'objectif premier est de pouvoir rendre "occupé" n'importe quel composant sans trop d'effort. Mon besoin était de pouvoir le faire sur une JTable (le temps qu'elle charge les données à afficher).

Créer un gestionnaire:

Code :
1
2
3
4
5
 
/** Create an handler for managing the "busy" state
 *  This handler can be used on the controller or model layer
 */
BusyHandler handler = BusyFactory.create( monComposant );
Indiquer que le composant est occupé:

Code :
1
2
3
4
 
/** Go on a busy state
 */
handler.busy();
Indiquer que le composant n'est plus occupé:

Code :
1
2
3
4
 
/** Return to a normal state
 */
handler.done();
ce qui donne sur une JTable (avec une animation)



Voici le code:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package org.divxdede.filemanager.ui.busy;
 
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.Window;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.JXBusyLabel;
import org.jdesktop.swingx.JXPanel;
 
/**
 * Utilitaire pour rendre "occupé" un composant swing.
 * <p>
 * Les méthodes <strong>create</strong> modifie le rendu d'un composant afin 
 * d'indiquer à l'utilisateur que ce dernier est occupé.
 * <p>
 * Un <code>BusyHandler</code> est retourné afin de permettre à l'appelant 
 * d'indiquer que la tâche occupant le composant est terminée.
 * 
 * @author André Sébastien
 */
public abstract class BusyFactory {
 
    /** Busy a specified component
     *  @param comp Component to create
     *  @return BusyHandler Handler for complete the task and stop the create state
     */
    public static BusyHandler create( JComponent comp )  {
        return create( comp , Color.GRAY );
    }
 
    /** Busy a specified component
     *  @param comp Component to create
     *  @param shadowColor Shadowing color used over the component while it is create
     *  @return BusyHandler Handler for complete the task and stop the create state
     */
    public static BusyHandler create( JComponent comp  , Color shadowColor ) {
        return new BusyHandlerImpl(comp, shadowColor );
    }
 
    /** Create a component used as a glasspane
     */
    private static JComponent createGlassPane() {
        JXPanel panel = new JXPanel();
        panel.setLayout(null);
        panel.setOpaque(false);
        panel.setName("busy-glasspane");
        return panel;
    }
 
    /** Duplicate a layout component (location & size) on another component.
     */
    private static void layout( JComponent source , JComponent dest ) {
 
        Point point     = source.getLocation();
        Point rootPoint = SwingUtilities.convertPoint( source.getParent(), point , dest.getParent() );
 
        dest.setLocation(rootPoint);
        dest.setSize( source.getSize() );
    }
 
    /** BusyHandler implementation
     */
    static class BusyHandlerImpl implements BusyHandler {
 
        private JComponent  comp        = null;
        private Color       shadowColor = null;
 
        private JComponent  glassPane   = null;
        private Component[] comps       = null;
 
        public BusyHandlerImpl( JComponent comp , Color shadowColor ) {
            this.comp        = comp;
            this.shadowColor = shadowColor;
        }
 
        public synchronized void busy() {
            if( this.glassPane != null ) return;
 
            synchronized( comp.getTreeLock() ) 
            {
                Window w = SwingUtilities.getWindowAncestor(comp);
                if( w instanceof JFrame ) {
                    JFrame frame  = (JFrame)w;
 
                    /** Get a glasspane component
                     */
                    this.glassPane = (JComponent)frame.getGlassPane();
                    if( this.glassPane.getName() == null || !glassPane.getName().equals("busy-glasspane") ) {
                        this.glassPane = createGlassPane();
                        frame.setGlassPane( this.glassPane );
                    }
 
                    synchronized( this.glassPane.getTreeLock() ) 
                    {
                        /** Create a Busy Label 
                         */
                        JXBusyLabel label = new JXBusyLabel();
                        label.setHorizontalAlignment( label.CENTER );
 
                        /** Create a white-shadow
                         */
                        JLabel shadow = null;
                        if( shadowColor != null ) {
                            shadow = new JLabel();
                            shadow.setBackground( new Color(shadowColor.getRed(),shadowColor.getGreen(),shadowColor.getBlue(),100) );
                            shadow.setOpaque(true);
                        }
 
                        /** Add the Busy label to the glasspane
                         */
                        if( shadow != null ) this.glassPane.add( shadow );
                        this.glassPane.add( label );
                        if( shadow != null ) layout( comp , shadow );
                        layout( comp , label );
 
 
                        if( shadow != null ) {
                            this.comps = new Component[]{ shadow , label };
                        }
                        else
                            this.comps = new Component[]{ label };
 
                        /** Show the GlassPane if it's not the case
                         */
                        this.glassPane.setVisible(true);
 
                        /** Start animation
                         */
                        label.setBusy(true);
                    }
                }
                else {
                    throw new IllegalStateException("Component don't have a JFrame ancestor");
                }
            }
        }
 
        public synchronized void done() {
            if( comps == null || glassPane == null ) return;
 
            if( ! SwingUtilities.isEventDispatchThread() ) {
                SwingUtilities.invokeLater( new Runnable() {
 
                    public void run() {
                        done();
                    }
                } );
                return;
            }
 
            synchronized( glassPane.getTreeLock() ) {
                for(Component c : comps) {
                    if( c instanceof JXBusyLabel ) {
                        ((JXBusyLabel)c).setBusy(false);
                    }
                    glassPane.remove(c);
                }
            }
            glassPane = null;
            comps = null;
        }
    }
}
et

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.divxdede.filemanager.ui.busy;
 
/**
 * BusyHandler allow to notify that the busy task is completed and that
 * we can stop to render the component as a busy component.
 * 
 * @author André Sébastien
 */
public interface BusyHandler {
 
    /** Set the underlying task as busy.
     *  
     */
    public void busy(); 
 
    /** Done the underlying task.
     */
    public void done();
}
Cette classe n'est pas parfaite ( le rendu est peu configurable, etc...) mais ca peut être un point de départ pour implémenter une version plus "générale".

En esperant que ca peut re-servir.

Sébastien.
__________________
JBusyComponent, une API pour rendre occupé un composant swing.
SCJP Java 6.0 (90% pass score)
divxdede est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 06h14.


 
 
 
 
Partenaires

Hébergement Web