• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /barrelfish-2018-10-04/usr/eclipseclp/Visualisation/src/com/parctechnologies/eclipse/visualisation/
1// BEGIN LICENSE BLOCK
2// Version: CMPL 1.1
3//
4// The contents of this file are subject to the Cisco-style Mozilla Public
5// License Version 1.1 (the "License"); you may not use this file except
6// in compliance with the License.  You may obtain a copy of the License
7// at www.eclipse-clp.org/license.
8//
9// Software distributed under the License is distributed on an "AS IS"
10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11// the License for the specific language governing rights and limitations
12// under the License.
13//
14// The Original Code is  The ECLiPSe Constraint Logic Programming System.
15// The Initial Developer of the Original Code is  Cisco Systems, Inc.
16// Portions created by the Initial Developer are
17// Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18//
19// Contributor(s):
20//
21// END LICENSE BLOCK
22
23package com.parctechnologies.eclipse.visualisation;
24
25import javax.swing.*;
26import java.beans.*;
27import java.lang.reflect.*;
28
29/**
30 * This is a "bridging" class between some java beans classes
31 * (PropertyChangeSupport, PropertyDescriptor etc) and the swing JToggleButton
32 * class. The idea is to have a clean way of providing toggle buttons that
33 * accurately control and reflect the state of a named boolean property of some
34 * object.<p>
35 * The way it works is that the "propertyHolder" has a boolean property such
36 * that:
37 * <ul>
38 * <li> The property has a name propertyName (such as "autoResume")
39 * <li> The propertyHolder has public get/set methods which obey the conventional
40 * get/set naming pattern e.g. (public boolean getAutoResume(); public void
41 * setAutoResume(boolean)).
42 * <li> There is a PropertyChangeSupport object which "observes" the boolean
43 * property, in that a PropertyChangeEvent is sent to all its listeners when
44 * the boolean property changes value.
45 * </ul>
46 * We can then construct a BooleanPropertyModel given the property's name, and
47 * references to the propertyHolder and the observing PropertyChangeSupport.
48 * This BooleanPropertyModel is a subclass of JToggleButton.ToggleButtonModel
49 * and so can be used as the underlying model of any swing JToggleButton.
50 */
51public class BooleanGroupPropertyModel extends JToggleButton.ToggleButtonModel
52  implements PropertyChangeListener
53{
54  // PropertyDescriptor is a beans class which handles the necessary
55  // reflection to work with the get/set methods of the property.
56  private PropertyDescriptor propertyDescriptor;
57  private Object propertyHolder;
58
59  // Hold the value of the property which this model should consider true
60  private Object match;
61
62  public BooleanGroupPropertyModel(String propertyName, Object propertyHolder,
63				   PropertyChangeSupport propertyChangeSupport,
64				   Object match)
65  {
66    super();
67    this.match = match;
68    PropertyDescriptor pd;
69    try
70    {
71      pd = new PropertyDescriptor(propertyName,
72       propertyHolder.getClass());
73    }
74    catch(IntrospectionException ie)
75    {
76      throw(new RuntimeException("Exception thrown: "+ie));
77    }
78    this.propertyHolder = propertyHolder;
79    setSelected(match.equals(getValue(pd)));
80    this.propertyDescriptor = pd;
81    propertyChangeSupport.addPropertyChangeListener(propertyName, this);
82  }
83
84  /**
85   * This propertyChange method means that the ButtonModel's setSelected method
86   * will be invoked if anything changes the property setting.
87   */
88  public void propertyChange(PropertyChangeEvent event)
89  {
90    Object newValue =  event.getNewValue();
91    boolean isMatch = (newValue.equals(match));
92    if(isSelected() != isMatch)
93    {
94      setSelected(isMatch);
95    }
96  }
97
98  /**
99   * setSelected extends the behaviour of the parent class by invoking the
100   * propertyHolder's writeMethod.
101   */
102  public void setSelected(boolean newValue)
103  {
104    super.setSelected(newValue);
105    // check that it has been initialised
106    if((propertyDescriptor != null) && newValue)
107    {
108      Method writeMethod = propertyDescriptor.getWriteMethod();
109      Object[] args = new Object[1];
110
111      args[0] = match;
112      try
113      {
114	  if (DebuggingSupport.logMessages) {
115	      DebuggingSupport.logMessage(this, "BooleanGroupPropertyModel invoking " + writeMethod);
116	  }
117          writeMethod.invoke(propertyHolder, args);
118      }
119      catch(IllegalAccessException iae)
120      {throw (new RuntimeException("Exception thrown: "+iae));}
121      catch(InvocationTargetException ite)
122      {
123	  ite.printStackTrace();
124	  throw (new RuntimeException("Exception thrown: "+ite.getTargetException()));}
125    }
126  }
127
128  /**
129   * The getValue method is used when the BooleanPropertyModel is first
130   * initialised. It is invoked in order to discover the initial value of the
131   * property, which is done by invoking the getMethod.
132   */
133  private Object getValue(PropertyDescriptor pd)
134  {
135    Method readMethod = pd.getReadMethod();
136    Object[] args = new Object[0];
137
138    Object result;
139
140    try
141    {
142      result = readMethod.invoke(propertyHolder, args);
143    }
144    catch(IllegalAccessException iae)
145    {throw (new RuntimeException("Exception thrown: "+iae));}
146    catch(InvocationTargetException ite)
147    {throw (new RuntimeException("Exception thrown: "+ite));}
148    return(result);
149  }
150
151}
152