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;
}
}
} |
Partager