| 
      
      
      From: <bma...@us...> - 2008-06-24 13:20:38
      
     | 
| Revision: 3656
          http://fudaa.svn.sourceforge.net/fudaa/?rev=3656&view=rev
Author:   bmarchan
Date:     2008-06-24 06:20:43 -0700 (Tue, 24 Jun 2008)
Log Message:
-----------
Le composant est totalement modifi?\195?\169 pour ?\195?\170tre visuellement plus parlant.
Modified Paths:
--------------
    branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/com/memoire/bu/BuCheckBox3States.java
Modified: branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/com/memoire/bu/BuCheckBox3States.java
===================================================================
--- branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/com/memoire/bu/BuCheckBox3States.java	2008-06-20 14:53:29 UTC (rev 3655)
+++ branches/Br_FudaaModeleur_TF/fudaa_devel/ctulu/src/com/memoire/bu/BuCheckBox3States.java	2008-06-24 13:20:43 UTC (rev 3656)
@@ -1,236 +1,302 @@
-/**
- * @modification $Date: 2006-09-19 14:35:04 $
- * @statut       unstable
- * @file         BuCheckBox3States.java
- * @version      0.43
- * @author       Bertrand Marchand
- * @email        gui...@de...
- * @license      GNU General Public License 2 (GPL2)
- * @copyright    1998-2005 Guillaume Desnoix
- * (c)1998-2001 Bertrand Marchand
- */
-
-package com.memoire.bu;
-
-/**
- * @creation     15/12/98
- * @modification 05/01/99
- * @statut       instable
- */
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.util.Vector;
-
-import javax.swing.Icon;
-
-/**
- * Un checkbox permettant 3 \xE9tats (activ\xE9, d\xE9sactiv\xE9, mixte). Dans ce dernier
- * cas, le bouton appara\xEEt en gris\xE9
- * @version 0.02, 05/01/99
- * @author Bertrand Marchand
- */
-public class BuCheckBox3States extends BuCheckBox
-{
-  public static final int STATE_MIXED      = 0;                    // On reprend les status Item pour rester compatible avec la m\xE9thode
-  public static final int STATE_SELECTED   = ItemEvent.SELECTED;   // ItemEvent.getStateChanged(). On rajoute un \xE9tat BuCheckBox3States.STATE_MIXED.
-  public static final int STATE_DESELECTED = ItemEvent.DESELECTED;
-
-  private int state_;                      // Etat (SELECTED, DESELECTED, MIXED)
-  private Icon iconStateMixed = null;      // L'icon de status mixte (pourrait par la suite \xEAtre issu de iconDefault).
-  private Icon iconDefault = null;         // L'icon donn\xE9 par le programmeur
-  private Vector itemListenerList = null;  // Les items listener du composant
-  private boolean defaultEvent_;           // Definit si l'\xE9venement ItemEvent provient d'une des classes m\xE8res
-
-
-  /**
-   * Creates an initially deselected checkbox button with no text, no icon.
-   */
-  public BuCheckBox3States () {
-    this(null, null, STATE_DESELECTED);
-  }
-
-  /**
-   * Creates an initially deselected checkbox with an icon.
-   *
-   * @param icon  the Icon image to display
-   */
-  public BuCheckBox3States(Icon icon) {
-    this(null, icon, STATE_DESELECTED);
-  }
-
-  /**
-   * Creates a checkbox with an icon and specifies its state.
-   *
-   * @param icon  the Icon image to display
-   * @param state an int value indicating the initial selection
-   *        state. The possible values are STATE_DESELECTED,
-   *        STATE_SELECTED, STATE_MIXED.
-   */
-  public BuCheckBox3States(Icon icon, int state) {
-    this(null, icon, state);
-  }
-
-  /**
-   * Creates an initially deselected checkbox with text.
-   *
-   * @param text the text of the checkbox.
-   */
-  public BuCheckBox3States (String text) {
-    this(text, null, STATE_DESELECTED);
-  }
-
-  /**
-   * Creates a checkbox with text and specifies its state.
-   *
-   * @param text the text of the checkbox.
-   * @param state an int value indicating the initial selection
-   *        state. The possible values are STATE_DESELECTED,
-   *        STATE_SELECTED, STATE_MIXED.
-   */
-  public BuCheckBox3States (String text, int state) {
-    this(text, null, state);
-  }
-
-  /**
-   * Creates an initially deselected checkbox with
-   * the specified text and icon.
-   *
-   * @param text the text of the checkbox.
-   * @param icon  the Icon image to display
-   */
-  public BuCheckBox3States(String text, Icon icon) {
-    this(text, icon, STATE_DESELECTED);
-  }
-
-  /**
-   * Creates a checkbox with the specified text and icon and specifies its state.
-   *
-   * @param text the text of the checkbox.
-   * @param icon  the Icon image to display
-   * @param state an int value indicating the initial selection
-   *        state. The possible values are STATE_DESELECTED,
-   *        STATE_SELECTED, STATE_MIXED.
-   */
-  public BuCheckBox3States(String text, Icon icon, int state) {
-    setText(text);
-    setIcon(icon);
-    iconDefault = icon;
-    iconStateMixed = new IconStateMixed();
-    itemListenerList = new Vector();
-    defaultEvent_ = true;
-    this.setState(state);
-  }
-
-  /**
-   * Affectation du status (SELECTED, DESELECTED, MIXED)
-   */
-  public void setState(int state) {
-    defaultEvent_ = false;
-    //int vp = state_;
-    state_ = state;
-    switch (state) {
-     case STATE_SELECTED:
-      setIcon(iconDefault);
-      setSelected(true);
-      break;
-     case STATE_DESELECTED:
-      setIcon(iconDefault);
-      setSelected(false);
-      break;
-     case STATE_MIXED:
-      setIcon(iconStateMixed);
-      fireItemStateChanged(new ItemEvent(this,ItemEvent.ITEM_STATE_CHANGED,this,
-                           state));
-      fireStateChanged();
-      break;
-    }
-    defaultEvent_ = true;
-  }
-
-  /**
-   * Retourne le status (SELECTED, DESELECTED, MIXED)
-   */
-  public int getState() {
-    return state_;
-  }
-
-  /**
-   * adds an ItemListener to the checkbox
-   */
-  public void addItemListener(ItemListener l) {
-    itemListenerList.addElement(l);
-  }
-
-  /**
-   * removes an ItemListener from the button
-   */
-  public void removeItemListener(ItemListener l) {
-    itemListenerList.removeElement(l);
-  }
-
-  protected void fireItemStateChanged(ItemEvent event) {
-    // Evenement en provenance des classes m\xE8res => On ne notifie pas les listeners, mais
-    // on remodifie l'\xE9tat du bouton.
-    if (defaultEvent_) {
-      setState((state_+1)%3);
-      return;
-    }
-    ItemEvent evt = new ItemEvent(this,event.getID(),event.getItem(),event.getStateChange());
-    if (itemListenerList != null)
-    for (int i=0; i<itemListenerList.size(); i++) {
-      ((ItemListener) itemListenerList.elementAt(i)).itemStateChanged(evt);
-    }
-  }
-  /**
-   * Doit \xEAtre remplac\xE9 par <I>setState</I>
-   */
-//  public void setSelected(boolean state) {
-//    throw new RuntimeException("BuCheckBox3States : utilisez 'setState' a la place de 'setSelected'");
-//  }
-
-  /**
-   * Doit \xEAtre remplac\xE9 par <I>getState</I>
-   */
-//  public boolean isSelected() {
-//    throw new RuntimeException("BuCheckBox3States : utilisez 'getState' a la place de 'isSelected'");
-//  }
-
-  // Classe de trace de l'icon pour un status STATE_MIXED
-
-  public  static final class IconStateMixed implements Icon {
-
-    public int getIconHeight() {
-      return 13;
-    }
-
-    public int getIconWidth() {
-      return 13;
-    }
-
-    public void paintIcon(Component _c, Graphics _g, int _x, int _y) {
-      int w=getIconWidth();
-      int h=getIconHeight();
-
-      _g.setColor(Color.lightGray);
-      _g.fillRect(_x,_y,w-2,h-1);
-      _g.setColor(Color.gray);
-      _g.drawLine(_x+w-1,_y,_x,_y);
-      _g.drawLine(_x,_y,_x,_y+h-1);
-      _g.setColor(Color.white);
-      _g.drawLine(_x,_y+h-1,_x+w-1,_y+h-1);
-      _g.drawLine(_x+w-1,_y+h-1,_x+w-1,_y);
-
-      _g.setColor(Color.gray);
-      _g.drawLine(_x+3,_y+3,_x+w-5,_y+h-5);
-      _g.drawLine(_x+4,_y+3,_x+w-5,_y+h-6);
-      _g.drawLine(_x+3,_y+4,_x+w-6,_y+h-5);
-      _g.drawLine(_x+3,_y+h-5,_x+w-5,_y+3);
-      _g.drawLine(_x+3,_y+h-6,_x+w-6,_y+3);
-      _g.drawLine(_x+4,_y+h-5,_x+w-5,_y+4);
-    }
-  }
-}
+/*
+ * @creation     23 juin 2008
+ * @modification $Date:$
+ * @license      GNU General Public License 2
+ * @copyright    (c)1998-2008 CETMEF 2 bd Gambetta F-60231 Compiegne
+ * @mail         fud...@li...
+ */
+package com.memoire.bu;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ActionMapUIResource;
+
+import java.awt.GridLayout;
+import java.awt.event.*;
+
+/**
+ * Un checkbox permettant 3 \xE9tats (activ\xE9, d\xE9sactiv\xE9, mixte). Dans ce dernier
+ * cas, le bouton appara\xEEt en gris\xE9.
+ * Le code est repris d'un composant ThreeStateCheckBox
+ * <p>
+ * Important : Ce composant n'envoie pas d'\xE9venement ActionEvent. Seuls les
+ * evenements ItemEvent sont g\xE9r\xE9s.<br>
+ * Dans le cas ou l'\xE9tat est "mixed", un evenement ItemEvent avec l'etat
+ * correspondant STATE_MIXED est envoy\xE9.
+ *<p>
+ * Maintenance tip - There were some tricks to getting this code
+ * working:
+ *
+ * 1. You have to overwite addMouseListener() to do nothing
+ * 2. You have to add a mouse event on mousePressed by calling
+ * super.addMouseListener()
+ * 3. You have to replace the UIActionMap for the keyboard event
+ * "pressed" with your own one.
+ * 4. You have to remove the UIActionMap for the keyboard event
+ * "released".
+ * 5. You have to grab focus when the next state is entered,
+ * otherwise clicking on the component won't get the focus.
+ * 6. You have to make a BuCheckBox3StatesDecorator as a button model that
+ * wraps the original button model and does state management.
+ * 
+ * @author Bertrand Marchand
+ */
+public class BuCheckBox3States extends JCheckBox {
+  /** Etat Mixte du checkbox */
+  public static final int STATE_MIXED      = 0;
+  /** Etat Selected du checkbox */
+  public static final int STATE_SELECTED   = ItemEvent.SELECTED;
+  /** Etat Deselected du checkbox */
+  public static final int STATE_DESELECTED = ItemEvent.DESELECTED;
+
+  private final BuCheckbox3StatesDecorator model;
+
+  public BuCheckBox3States(String text, Icon icon, int initial){
+    super(text, icon);
+    // Add a listener for when the mouse is pressed
+    super.addMouseListener(new MouseAdapter() {
+      public void mousePressed(MouseEvent e) {
+        grabFocus();
+        model.nextState();
+      }
+    });
+    // Reset the keyboard action map
+    ActionMap map = new ActionMapUIResource();
+    map.put("pressed", new AbstractAction() {
+      public void actionPerformed(ActionEvent e) {
+        grabFocus();
+        model.nextState();
+      }
+    });
+    map.put("released", null);
+    SwingUtilities.replaceUIActionMap(this, map);
+    // set the model to the adapted model
+    model = new BuCheckbox3StatesDecorator(getModel());
+    setModel(model);
+    setState(initial);
+  }
+  public BuCheckBox3States(String text, int initial) {
+    this(text, null, initial);
+  }
+  public BuCheckBox3States(String text) {
+    this(text, STATE_MIXED);
+  }
+  public BuCheckBox3States() {
+    this(null);
+  }
+
+  /** No one may add mouse listeners, not even Swing! */
+  public void addMouseListener(MouseListener l) { }
+  /**
+   * Set the new state to either SELECTED, NOT_SELECTED or
+   * DONT_CARE.  If state == null, it is treated as DONT_CARE.
+   */
+  public void setState(int state) { model.setState(state); }
+  /** Return the current state, which is determined by the
+   * selection status of the model. */
+  public int getState() { return model.getState(); }
+  public void setSelected(boolean b) {
+    if (b) {
+      setState(STATE_SELECTED);
+    } else {
+      setState(STATE_DESELECTED);
+    }
+  }
+  
+  /**
+   * The button accept only 2 states when clicked : SELECTED, or NOT_SELECTED
+   * @param _b true : Only 2 states. 3 otherwise.
+   */
+  public void acceptOnly2StatesWhenClicked(boolean _b) {
+    model.acceptOnly2StatesWhenClicked(_b);
+  }
+  
+  /**
+   * Exactly which Design Pattern is this?  Is it an Adapter,
+   * a Proxy or a Decorator?  In this case, my vote lies with the
+   * Decorator, because we are extending functionality and
+   * "decorating" the original model with a more powerful model.
+   */
+  private class BuCheckbox3StatesDecorator implements ButtonModel {
+    private final ButtonModel other;
+    private boolean only2States_=false;
+    private BuCheckbox3StatesDecorator(ButtonModel other) {
+      this.other = other;
+    }
+    private void setState(int state) {
+      if (state == STATE_DESELECTED) {
+        other.setArmed(false);
+        setPressed(false);
+        setSelected(false);
+      } else if (state == STATE_SELECTED) {
+        other.setArmed(false);
+        setPressed(false);
+        setSelected(true);
+      } else { // either "null" or DONT_CARE
+        other.setArmed(true);
+        setPressed(true);
+        setSelected(true);
+        fireItemStateChanged(new ItemEvent(this,ItemEvent.ITEM_STATE_CHANGED,this,STATE_MIXED));
+      }
+    }
+    /**
+     * The current state is embedded in the selection / armed
+     * state of the model.
+     *
+     * We return the SELECTED state when the checkbox is selected
+     * but not armed, DONT_CARE state when the checkbox is
+     * selected and armed (grey) and NOT_SELECTED when the
+     * checkbox is deselected.
+     */
+    private int getState() {
+      if (isSelected() && !isArmed()) {
+        // normal black tick
+        return STATE_SELECTED;
+      } else if (isSelected() && isArmed()) {
+        // don't care grey tick
+        return STATE_MIXED;
+      } else {
+        // normal deselected
+        return STATE_DESELECTED;
+      }
+    }
+    /** We rotate between NOT_SELECTED, SELECTED and DONT_CARE.*/
+    private void nextState() {
+      int current = getState();
+      if (current == STATE_DESELECTED) {
+        setState(STATE_SELECTED);
+      } else if (current == STATE_SELECTED) {
+        if (only2States_)
+          setState(STATE_DESELECTED);
+        else
+          setState(STATE_MIXED);
+      } else if (current == STATE_MIXED) {
+        setState(STATE_DESELECTED);
+      }
+    }
+    /** Filter: No one may change the armed status except us. */
+    public void setArmed(boolean b) {
+    }
+    /** We disable focusing on the component when it is not
+     * enabled. */
+    public void setEnabled(boolean b) {
+      setFocusable(b);
+      other.setEnabled(b);
+    }
+    /** All these methods simply delegate to the "other" model
+     * that is being decorated. */
+    public boolean isArmed() { return other.isArmed(); }
+    public boolean isSelected() { return other.isSelected(); }
+    public boolean isEnabled() { return other.isEnabled(); }
+    public boolean isPressed() { return other.isPressed(); }
+    public boolean isRollover() { return other.isRollover(); }
+    public void setSelected(boolean b) { other.setSelected(b); }
+    public void setPressed(boolean b) { other.setPressed(b); }
+    public void setRollover(boolean b) { other.setRollover(b); }
+    public void setMnemonic(int key) { other.setMnemonic(key); }
+    public int getMnemonic() { return other.getMnemonic(); }
+    public void setActionCommand(String s) {
+      other.setActionCommand(s);
+    }
+    public String getActionCommand() {
+      return other.getActionCommand();
+    }
+    public void setGroup(ButtonGroup group) {
+      other.setGroup(group);
+    }
+    public void addActionListener(ActionListener l) {
+      other.addActionListener(l);
+    }
+    public void removeActionListener(ActionListener l) {
+      other.removeActionListener(l);
+    }
+    public void addItemListener(ItemListener l) {
+      other.addItemListener(l);
+    }
+    public void removeItemListener(ItemListener l) {
+      other.removeItemListener(l);
+    }
+    public void addChangeListener(ChangeListener l) {
+      other.addChangeListener(l);
+    }
+    public void removeChangeListener(ChangeListener l) {
+      other.removeChangeListener(l);
+    }
+    public Object[] getSelectedObjects() {
+      return other.getSelectedObjects();
+    }
+    public void acceptOnly2StatesWhenClicked(boolean _b) {
+      only2States_=_b;
+    }
+  }
+  
+  public static void main(String args[]) throws Exception {
+    JFrame frame = new JFrame("BuCheckBox3States");
+    frame.getContentPane().setLayout(new GridLayout(0, 1, 5, 5));
+    final BuCheckBox3States swingBox = new BuCheckBox3States(
+        "Testing the 3states checkbox");
+//    swingBox.acceptOnly2StatesWhenClicked(true);
+    swingBox.setState(BuCheckBox3States.STATE_MIXED);
+
+    swingBox.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        System.out.println("3states actionPerformed");
+      }
+    });
+    swingBox.addChangeListener(new ChangeListener() {
+      public void stateChanged(ChangeEvent e) {
+        System.out.println("3states stateChanged");
+      }
+    });
+    swingBox.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        System.out.println("3states itemStateChanged");
+      }
+    });
+    swingBox.setMnemonic('T');
+    frame.getContentPane().add(swingBox);
+
+    JCheckBox normal=new JCheckBox("The normal checkbox");
+    normal.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        System.out.println("normal actionPerformed");
+      }
+    });
+    normal.addChangeListener(new ChangeListener() {
+      public void stateChanged(ChangeEvent e) {
+        System.out.println("normal stateChanged");
+      }
+    });
+    normal.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        System.out.println("normal itemStateChanged");
+      }
+    });
+
+    frame.getContentPane().add(normal);
+    UIManager.setLookAndFeel(
+        UIManager.getSystemLookAndFeelClassName());
+    final BuCheckBox3States winBox = new BuCheckBox3States(
+        "Testing the 3states checkbox");
+    frame.getContentPane().add(winBox);
+    final JCheckBox winNormal = new JCheckBox(
+        "The normal checkbox");
+    frame.getContentPane().add(winNormal);
+    // wait for 3 seconds, then enable all check boxes
+    new Thread() { {start();}
+      public void run() {
+        try {
+          winBox.setEnabled(false);
+          winNormal.setEnabled(false);
+          Thread.sleep(3000);
+          winBox.setEnabled(true);
+          winNormal.setEnabled(true);
+        } catch (InterruptedException ex) { }
+      }
+    };
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    frame.pack();
+    frame.setVisible(true);
+  }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
 |