source: src/main/java/weka/gui/beans/BeanInstance.java @ 9

Last change on this file since 9 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 12.5 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    BeanInstance.java
19 *    Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui.beans;
24
25import java.awt.Dimension;
26import java.awt.Font;
27import java.awt.FontMetrics;
28import java.awt.Graphics;
29import java.awt.Point;
30import java.awt.Rectangle;
31import java.beans.Beans;
32import java.io.Serializable;
33import java.util.Vector;
34
35import javax.swing.JComponent;
36
37/**
38 * Class that manages a set of beans.
39 *
40 * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
41 * @version  $Revision: 4829 $
42 * @since 1.0
43 */
44public class BeanInstance
45  implements Serializable {
46
47  /** for serialization */
48  private static final long serialVersionUID = -7575653109025406342L;
49
50  /**
51   * class variable holding all the beans
52   */
53  private static Vector COMPONENTS = new Vector();
54
55  public static final int IDLE = 0;
56  public static final int BEAN_EXECUTING = 1;
57 
58  /**
59   * Holds the bean encapsulated in this instance
60   */
61  private Object m_bean;
62  private int m_x;
63  private int m_y;
64
65
66  /**
67   * Reset the list of beans
68   */
69  public static void reset(JComponent container) {
70    // remove beans from container if necessary
71    removeAllBeansFromContainer(container);
72    COMPONENTS = new Vector();
73  }
74
75  /**
76   * Removes all beans from containing component
77   *
78   * @param container a <code>JComponent</code> value
79   */
80  public static void removeAllBeansFromContainer(JComponent container) {
81    if (container != null) {
82      if (COMPONENTS != null) {
83        for (int i = 0; i < COMPONENTS.size(); i++) {
84          BeanInstance tempInstance = (BeanInstance)COMPONENTS.elementAt(i);
85          Object tempBean = tempInstance.getBean();
86          if (Beans.isInstanceOf(tempBean, JComponent.class)) {
87            container.remove((JComponent)tempBean);
88          }
89        }
90      }
91      container.revalidate();
92    }
93  }
94
95  /**
96   * Adds all beans to the supplied component
97   *
98   * @param container a <code>JComponent</code> value
99   */
100  public static void addAllBeansToContainer(JComponent container) {
101    if (container != null) {
102      if (COMPONENTS != null) {
103        for (int i = 0; i < COMPONENTS.size(); i++) {
104          BeanInstance tempInstance = (BeanInstance)COMPONENTS.elementAt(i);
105          Object tempBean = tempInstance.getBean();
106          if (Beans.isInstanceOf(tempBean, JComponent.class)) {
107            container.add((JComponent)tempBean);
108          }
109        }
110      }
111      container.revalidate();
112    }
113  }
114
115  /**
116   * Return the list of displayed beans
117   *
118   * @return a vector of beans
119   */
120  public static Vector getBeanInstances() {
121    return COMPONENTS;
122  }
123
124  /**
125   * Describe <code>setBeanInstances</code> method here.
126   *
127   * @param beanInstances a <code>Vector</code> value
128   * @param container a <code>JComponent</code> value
129   */
130  public static void setBeanInstances(Vector beanInstances, 
131                                      JComponent container) {
132    reset(container);
133   
134    if (container != null) {
135      for (int i = 0; i < beanInstances.size(); i++) {
136        Object bean = ((BeanInstance)beanInstances.elementAt(i)).getBean();
137        if (Beans.isInstanceOf(bean, JComponent.class)) {
138          container.add((JComponent)bean);
139        }
140      }
141      container.revalidate();
142      container.repaint();
143    }
144    COMPONENTS = beanInstances;
145  }
146
147  /**
148   * Renders the textual labels for the beans.
149   *
150   * @param gx a <code>Graphics</code> object on which to render
151   * the labels
152   */
153  public static void paintLabels(Graphics gx) {
154    gx.setFont(new Font(null, Font.PLAIN, 9));
155    FontMetrics fm = gx.getFontMetrics();
156    int hf = fm.getAscent();
157    for (int i = 0; i < COMPONENTS.size(); i++) {
158      BeanInstance bi = (BeanInstance)COMPONENTS.elementAt(i);
159      if (!(bi.getBean() instanceof Visible)) {
160        continue;
161      }
162      int cx = bi.getX(); int cy = bi.getY();
163      int width = ((JComponent)bi.getBean()).getWidth();
164      int height = ((JComponent)bi.getBean()).getHeight();
165      String label = ((Visible)bi.getBean()).getVisual().getText();
166      int labelwidth = fm.stringWidth(label);
167      if (labelwidth < width) {
168        gx.drawString(label, (cx+(width/2)) - (labelwidth / 2), cy+height+hf+2);
169      } else {
170        // split label
171
172        // find mid point
173        int mid = label.length() / 2;
174        // look for split point closest to the mid
175        int closest = label.length();
176        int closestI = -1;
177        for (int z = 0; z < label.length(); z++) {
178          if (label.charAt(z) < 'a') {
179            if (Math.abs(mid - z) < closest) {
180              closest = Math.abs(mid - z);
181              closestI = z;
182            }
183          }
184        }
185        if (closestI != -1) {
186          String left = label.substring(0, closestI);
187          String right = label.substring(closestI, label.length());
188          if (left.length() > 1 && right.length() > 1) {
189            gx.drawString(left, (cx+(width/2)) - (fm.stringWidth(left) / 2), 
190                          cy+height+(hf * 1)+2);
191            gx.drawString(right, (cx+(width/2)) - (fm.stringWidth(right) / 2), 
192                          cy+height+(hf * 2)+2);
193          } else {
194            gx.drawString(label, (cx+(width/2)) - (fm.stringWidth(label) / 2), 
195                          cy+height+(hf * 1)+2);
196          }
197        } else {
198          gx.drawString(label, (cx+(width/2)) - (fm.stringWidth(label) / 2), 
199                        cy+height+(hf * 1)+2);
200        }
201      }
202    }
203  }
204
205  /**
206   * Looks for a bean (if any) whose bounds contain the supplied point
207   *
208   * @param p a point
209   * @return a bean that contains the supplied point or null if no bean
210   * contains the point
211   */
212  public static BeanInstance findInstance(Point p) {
213    Rectangle tempBounds = new Rectangle();
214    for (int i=0; i < COMPONENTS.size(); i++) {
215     
216      BeanInstance t = (BeanInstance)COMPONENTS.elementAt(i);
217      JComponent temp = (JComponent)t.getBean();
218                                     
219      tempBounds = temp.getBounds(tempBounds);
220      if (tempBounds.contains(p)) {
221        return t;
222      }
223    }
224    return null;
225  }
226
227  /**
228   * Looks for all beans (if any) located within
229   * the supplied bounding box. Also adjusts the
230   * bounding box to be a tight fit around all
231   * contained beans
232   *
233   * @param boundingBox the bounding rectangle
234   * @return a Vector of BeanInstances
235   */
236  public static Vector findInstances(Rectangle boundingBox) {
237    Graphics gx = null;
238    FontMetrics fm = null;
239   
240    int centerX, centerY;
241    int startX, startY, endX, endY;
242    startX = (int)boundingBox.getX();
243    startY = (int)boundingBox.getY();
244    endX = (int)boundingBox.getMaxX();
245    endY = (int)boundingBox.getMaxY();
246    int minX = Integer.MAX_VALUE;
247    int minY = Integer.MAX_VALUE;
248    int maxX = Integer.MIN_VALUE;
249    int maxY = Integer.MIN_VALUE;
250    Vector result = new Vector();
251    for (int i = 0; i < COMPONENTS.size(); i++) {
252      BeanInstance t = (BeanInstance)COMPONENTS.elementAt(i);
253      centerX = t.getX() + (t.getWidth()/2);
254      centerY = t.getY() + (t.getHeight()/2);
255      if (boundingBox.contains(centerX, centerY)) {
256        result.addElement(t);
257
258
259        // adjust bounding box stuff
260//      int hf = 0;
261        if (gx == null) {
262          gx = ((JComponent)t.getBean()).getGraphics();
263          gx.setFont(new Font(null, Font.PLAIN, 9));
264          fm = gx.getFontMetrics();
265//        hf = fm.getAscent();
266        }
267        String label = "";
268        if (t.getBean() instanceof Visible) {
269          label = ((Visible)t.getBean()).getVisual().getText();
270        }
271        int labelwidth = fm.stringWidth(label);
272        int heightMultiplier = (labelwidth > t.getWidth())
273        ? 2
274        : 1;
275        /*if (label.length() == 0) {
276          heightMultiplier = 0;
277        }*/
278        int brx = 0;
279        int blx = 0;
280        if (centerX - (labelwidth / 2) - 2 < t.getX()) {
281          blx = (centerX - (labelwidth / 2) - 2);
282          brx = centerX + (labelwidth / 2) + 2;
283        } else {
284          blx = t.getX() - 2;
285          brx = t.getX() + t.getWidth() + 2;
286        }
287
288        if (blx < minX) {
289          minX = blx;
290        }
291        if (brx > maxX) {
292          maxX = brx;
293        }
294        if (t.getY() - 2 < minY) {
295          minY = t.getY() - 2;
296        }
297        if (t.getY() + t.getHeight() + 2 > maxY) {
298          maxY = t.getY() + t.getHeight()  + 2;
299        }
300      }
301    }
302    boundingBox.setBounds(minX, minY, maxX - minX, maxY - minY);
303   
304    return result;
305  }
306
307  /**
308   * Creates a new <code>BeanInstance</code> instance.
309   *
310   * @param container a <code>JComponent</code> to add the bean to
311   * @param bean the bean to add
312   * @param x the x coordinate of the bean
313   * @param y the y coordinate of the bean
314   */
315  public BeanInstance(JComponent container, Object bean, int x, int y) {
316    m_bean = bean;
317    m_x = x;
318    m_y = y;
319    addBean(container);
320  }
321
322  /**
323   * Creates a new <code>BeanInstance</code> instance given the fully
324   * qualified name of the bean
325   *
326   * @param container a <code>JComponent</code> to add the bean to
327   * @param beanName the fully qualified name of the bean
328   * @param x the x coordinate of the bean
329   * @param y th y coordinate of the bean
330   */
331  public BeanInstance(JComponent container, String beanName, int x, int y) {
332    m_x = x;
333    m_y = y;
334   
335    // try and instantiate the named component
336    try {
337      m_bean = Beans.instantiate(null, beanName);
338    } catch (Exception ex) {
339      ex.printStackTrace();
340      return;
341    }
342
343    addBean(container);
344  }
345
346  /**
347   * Remove this bean from the list of beans and from the containing component
348   *
349   * @param container the <code>JComponent</code> that holds the bean
350   */
351  public void removeBean(JComponent container) {
352    for (int i = 0; i < COMPONENTS.size(); i++) {
353      if ((BeanInstance)COMPONENTS.elementAt(i) == this) {
354        System.err.println("Removing bean");
355        COMPONENTS.removeElementAt(i);
356      }
357    }
358    if (container != null) {
359      container.remove((JComponent)m_bean);
360      container.revalidate();
361      container.repaint();
362    }
363  }
364
365  /**
366   * Adds this bean to the global list of beans and
367   * to the supplied container. The constructor
368   * calls this method, so a client should not need
369   * to unless they have called removeBean and then
370   * wish to have it added again.
371   *
372   * @param container the Component on which this
373   * BeanInstance will be displayed
374   */
375  public void addBean(JComponent container) {
376
377    // do nothing if we are already in the list
378    if (COMPONENTS.contains(this)) {
379      return;
380    }
381
382    // Ignore invisible components
383    if (!Beans.isInstanceOf(m_bean, JComponent.class)) {
384      System.err.println("Component is invisible!");
385      return;
386    }
387   
388    COMPONENTS.addElement(this);
389   
390    // Position and layout the component
391    JComponent c = (JComponent)m_bean;
392    Dimension d = c.getPreferredSize();
393    int dx = (int)(d.getWidth() / 2);
394    int dy = (int)(d.getHeight() / 2);
395    m_x -= dx;
396    m_y -= dy;
397    c.setLocation(m_x, m_y);
398    //    c.doLayout();
399    c.validate();
400    //    bp.addBean(c);
401    //    c.repaint();
402    if (container != null) {
403      container.add(c);
404      container.revalidate();
405    }
406  }
407
408  /**
409   * Gets the bean encapsulated in this instance
410   *
411   * @return an <code>Object</code> value
412   */
413  public Object getBean() {
414    return m_bean;
415  }
416
417  /**
418   * Gets the x coordinate of this bean
419   *
420   * @return an <code>int</code> value
421   */
422  public int getX() {
423    return m_x;
424  }
425
426  /**
427   * Gets the y coordinate of this bean
428   *
429   * @return an <code>int</code> value
430   */
431  public int getY() {
432    return m_y;
433  }
434
435  /**
436   * Gets the width of this bean
437   *
438   * @return an <code>int</code> value
439   */
440  public int getWidth() {
441    return ((JComponent)m_bean).getWidth();
442  }
443
444  /**
445   * Gets the height of this bean
446   *
447   * @return an <code>int</code> value
448   */
449  public int getHeight() {
450    return ((JComponent)m_bean).getHeight();
451  }
452 
453  /**
454   * Set the x and y coordinates of this bean
455   *
456   * @param newX the x coordinate
457   * @param newY the y coordinate
458   */
459  public void setXY(int newX, int newY) {
460    setX(newX);
461    setY(newY);
462    if (getBean() instanceof MetaBean) {
463      ((MetaBean)getBean()).shiftBeans(this, false);
464    }
465  }
466
467  /**
468   * Sets the x coordinate of this bean
469   *
470   * @param newX an <code>int</code> value
471   */
472  public void setX(int newX) {
473    m_x = newX;
474    ((JComponent)m_bean).setLocation(m_x, m_y);
475    ((JComponent)m_bean).validate();
476  }
477
478  /**
479   * Sets the y coordinate of this bean
480   *
481   * @param newY an <code>int</code> value
482   */
483  public void setY(int newY) {
484    m_y = newY;
485    ((JComponent)m_bean).setLocation(m_x, m_y);
486    ((JComponent)m_bean).validate();
487  }
488}
Note: See TracBrowser for help on using the repository browser.