001    /*
002     * LAPIS lightweight structured text processing system
003     *
004     * Copyright (C) 1998-2002 Carnegie Mellon University,
005     * Copyright (C) 2003 Massachusetts Institute of Technology.
006     * All rights reserved.
007     *
008     * This library is free software; you can redistribute it
009     * and/or modify it under the terms of the GNU General
010     * Public License as published by the Free Software
011     * Foundation, version 2.
012     *
013     * LAPIS homepage: http://graphics.lcs.mit.edu/lapis/
014     */
015    
016    package lapis.swing.cluster;
017    
018    import lapis.*;
019    import lapis.swing.*;
020    import java.awt.*;
021    import java.awt.image.*;
022    import java.util.*;
023    import java.awt.event.*;
024    import javax.swing.*;
025    import lapisx.swing.*;
026    import javax.swing.text.BadLocationException;
027    import java.awt.Dimension;
028    import javax.swing.border.LineBorder;
029    import lapis.swing.cluster.MatchNodeCreator.Node;
030    
031    public class ClusterRenderer {
032    
033            public ClusterRenderer() {}
034    
035            public JComponent getTopLevelClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
036                    TopLevelClip tp = new TopLevelClip(browser, n, expanded, sel, hasFocus);
037                    JPanel jp = new JPanel();
038                    Layout.vertical(jp).add(tp).done();
039                    if (!expanded) {
040                            jp.setBorder(new LineBorder(new Color(220,220,220), 3));
041                    }
042                    return jp;
043    
044            }
045            public JComponent getTopSingleClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
046                    TopSingleClip tp = new TopSingleClip(browser, n, expanded, sel, hasFocus);
047                    JPanel jp = new JPanel();
048                    Layout.vertical(jp).add(tp).done();
049                    if (!expanded) {
050                            jp.setBorder(new LineBorder(new Color(220,220,220), 3));
051                    }
052                    return jp;
053    
054            }
055            public JComponent getTopOverlayClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
056                    TopOverlayClip tp = new TopOverlayClip(browser, n, expanded, sel, hasFocus);
057                    JPanel jp = new JPanel();
058    
059                    Layout.vertical(jp).add(tp).done();
060                    if (!expanded) {
061                            jp.setBorder(new LineBorder(new Color(220,220,220), 3));
062                    }
063                    return jp;
064    
065            }
066    
067            public JComponent getSingleClip(Browser browser, Node n, Region r, boolean sel, boolean hasFocus) {
068                    return new SingleClip(browser, n, r, sel, hasFocus);
069            }
070            public static lapisx.util.Debug debug = lapisx.util.Debug.QUIET;
071    
072            public class TopSingleClip extends JPanel {
073    
074                    RegionSet rs;
075                    Region r1 = null;
076    
077                    Rectangle rect = null;
078                    Rectangle rect1 = new Rectangle(0, 0, 0, 0);
079                    Browser browser;
080                    boolean expanded;
081                    Rectangle regionRec1;
082                    Node node;
083                    JButton explanationButton;
084                    JTextArea explanationText;
085                    boolean sel;
086    
087                    public TopSingleClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
088                            //                      debug.printStackTrace();
089                            setBackground(Color.white);
090                            this.rs = n.getMatch();
091                            this.sel = sel;
092                            RegionEnumeration e = rs.regions();
093    
094                            this.node = n;
095                            for (Region r = e.first(); r != null; r = e.next()) {
096                                    if (!(r.getStart() == r.getEnd())) {
097                                            if (r1 == null) {
098                                                    r1 = r;
099    
100                                            }
101                                    }
102                            }
103    
104                            this.browser = browser;
105                            this.expanded = expanded;
106                            setRegion(r1);
107    
108                            Component b1 = null;
109                            JLabel textLabel = new JLabel();
110    
111                            if (r1 != null)
112                                    if (!(r1.getStart() == r1.getEnd())) {
113                                            //                  Node drawn = new Node (browser, "head.sub", new NamedRegionSet (browser.getDocument(), r1));
114                                            //                  debug.println("drawn image: " + drawn.getImage());
115                                            b1 = new SingleClip(browser, n, r1, false, false);
116                                    }
117                            if (b1 != null)
118                                    debug.println("browserClip not null");
119                            else {
120                                    Node child = null;
121                                    if (n.getChildCount() >0)
122                                             child = (Node)n.children.get(0);
123                                    
124                                    if (child != null){
125                                    
126                                            b1 = new SingleClip(browser, child, child.getMatch().regions().first(), sel, hasFocus);
127                                        n.setImage(((SingleClip)b1).getClip());
128                                    }
129                            }
130                            String text = n.getLabel();
131    
132                            if ((!expanded) && (b1 != null)) {
133                                    Layout.horizontal(this)
134                                            .add(textLabel = new JLabel(text), Layout.FIXED_SIZE, Layout.WEST)
135                                            .add(b1)
136                                            .done();
137                            }
138                            if ((!expanded) && (b1 == null)) {
139                                    Layout.vertical(this).add(Layout.horizontal().addGlue()
140                                    //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
141                                    .done()).done();
142                            }
143                            if (expanded) {
144                                    Layout.vertical(this).add(Layout.horizontal().add(textLabel = new JLabel(text), Layout.FIXED_SIZE, Layout.WEST).addGlue()
145                                            //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
146                                    .done()).done();
147                            }
148                            setBorder(new LineBorder(new Color(220,220,220), 1));
149                            if (hasFocus) {
150                                    setBorder(new LineBorder(Color.blue, 1));
151                            }
152    
153                            setToolTipText(n.getExplanationText());
154                            setOpaque(true);
155                            textLabel.setBackground(Color.white);
156                            textLabel.setOpaque(true);
157                    }
158    
159                    public void setRegion(Region r1) {
160    
161                            if (r1 != null) {
162                                    if (!(r1.getStart() == r1.getEnd())) {
163                                            try {
164                                                    regionRec1 = browser.getActivePane().regionToExpandedRectangle(r1);
165                                                    rect1 =
166                                                            new Rectangle(
167                                                                    regionRec1.x,
168                                                                    regionRec1.y,
169                                                                    Math.min(regionRec1.width + 200, browser.getActivePane().getWidth()),
170                                                                    regionRec1.height + 10);
171                                            }
172                                            catch (BadLocationException ble) {
173                                                    ble.printStackTrace();
174                                            }
175                                    }
176                            }
177                            rect = new Rectangle(0, 0, rect1.width + 6, rect1.height + 30);
178    
179                    }
180    
181                    public Action explainAction = new AcceleratedAction("&?") {
182                            public void actionPerformed(ActionEvent evt) {}
183                    };
184    
185                    public void paint(Graphics g) {
186                            super.paint(g);
187                            debug.println("painting toplevel " + node.toString());
188                            g.setPaintMode();
189                            g.setColor(new Color(102, 102, 255, 100));
190                            if (sel) {
191                                    debug.println("selected");
192                                    //g.setClip(0,0,getPreferredSize().width,getPreferredSize().height);
193                                    //g.fillRect(0,0,getPreferredSize().width,getPreferredSize().height);
194                                    g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
195                                    debug.println("bounds: " + g.getClipBounds().toString());
196                            }
197    
198                    }
199            }
200    
201            public class TopLevelClip extends JPanel {
202    
203                    RegionSet rs;
204                    Region r1 = null;
205    
206                    Rectangle rect = null;
207                    Rectangle rect1 = new Rectangle(0, 0, 0, 0);
208                    Rectangle rect2 = new Rectangle(0, 0, 0, 0);
209                    Rectangle rect3 = new Rectangle(0, 0, 0, 0);
210                    Browser browser;
211                    boolean expanded;
212                    Rectangle regionRec1;
213                    Rectangle regionRec2;
214                    Rectangle regionRec3;
215                    Node node;
216                    JButton explanationButton;
217                    JTextArea explanationText;
218                    boolean sel;
219    
220                    public TopLevelClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
221                            this.rs = n.getMatch();
222                            this.sel = sel;
223                            RegionEnumeration e = rs.regions();
224    
225                            this.node = n;
226                            for (Region r = e.first(); r != null; r = e.next()) {
227                                    if (!(r.getStart() == r.getEnd())) {
228                                            if (r1 == null) {
229                                                    r1 = r;
230    
231                                            }
232                                    }
233                            }
234    
235                            this.browser = browser;
236                            this.expanded = expanded;
237                            setRegion(r1);
238    
239                            SingleClip b1 = null;
240    
241                            if (r1 != null)
242                                    if (!(r1.getStart() == r1.getEnd())) {
243                                            //                  Node drawn = new Node (browser, "head.sub", new NamedRegionSet (browser.getDocument(), r1));
244                                            //                  debug.println("drawn image: " + drawn.getImage());
245                                            b1 = new SingleClip(browser, n, r1, false, false);
246                                    }
247                            if (b1 != null)
248                                    debug.println("browserClip not null");
249                            String text = n.getLabel();
250                            JLabel textLabel = new JLabel();
251                            JLabel select = new JLabel(" (  selected)");
252                            select.setVisible(false);
253                            if ((n.getSelectedChildren().size() != 0) && (n.getSelectedChildren().size() < n.getChildCount())) {
254                                    select.setText(" (" + n.getSelectedChildren().size() + " selected)");
255                                    select.setVisible(true);
256                            }
257                            select.setOpaque(false);
258    
259                            if ((!expanded) && (b1 != null)) {
260                                    Layout.vertical(
261                                            this)
262                                                    .add(
263                                                            Layout
264                                                            .horizontal()
265                                                            .add(textLabel = new JLabel(text), Layout.FIXED_SIZE, Layout.WEST)
266                                                            .add(select, Layout.FIXED_SIZE)
267                                                            .addGlue()
268                                            //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
269            .done()).add(b1).done();
270                            }
271                            if ((!expanded) && (b1 == null)) {
272                                    Layout.vertical(
273                                            this)
274                                                    .add(
275                                                            Layout
276                                                            .horizontal()
277                                                            .add(textLabel = new JLabel(text), Layout.FIXED_SIZE, Layout.WEST)
278                                                            .add(select, Layout.FIXED_SIZE)
279                                                            .addGlue()
280                                            //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
281            .done()).done();
282                            }
283                            if (expanded) {
284                                    Layout.vertical(
285                                            this)
286                                                    .add(
287                                                            Layout
288                                                            .horizontal()
289                                                            .add(textLabel = new JLabel(text), Layout.FIXED_SIZE, Layout.WEST)
290                                                            .add(select, Layout.FIXED_SIZE)
291                                                            .addGlue()
292                                            //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
293            .done())
294    
295                                            // .add(explanationText = new JTextArea(n.getExplanationText()))
296            .done();
297    
298                                    //              explanationText.getDocument().putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");
299                                    //              explanationText.setSize(explanationText.getPreferredSize());
300                            }
301                            setBorder(new LineBorder(Color.black, 1));
302                            if (hasFocus) {
303                                    setBorder(new LineBorder(Color.blue, 1));
304                            }
305    
306                            setToolTipText(n.getExplanationText());
307                            setOpaque(true);
308    
309                    }
310    
311                    public void setRegion(Region r1) {
312    
313                            if (r1 != null) {
314                                    if (!(r1.getStart() == r1.getEnd())) {
315                                            try {
316                                                    regionRec1 = browser.getActivePane().regionToExpandedRectangle(r1);
317                                                    rect1 =
318                                                            new Rectangle(
319                                                                    regionRec1.x,
320                                                                    regionRec1.y,
321                                                                    Math.min(regionRec1.width + 200, browser.getActivePane().getWidth()),
322                                                                    regionRec1.height + 10);
323                                            }
324                                            catch (BadLocationException ble) {
325                                                    ble.printStackTrace();
326                                            }
327                                    }
328                            }
329                            rect = new Rectangle(0, 0, rect1.width + 6, rect1.height + 30);
330    
331                    }
332    
333                    public Action explainAction = new AcceleratedAction("&?") {
334                            public void actionPerformed(ActionEvent evt) {}
335                    };
336                    public void paint(Graphics g) {
337                            super.paint(g);
338                            debug.println("painting toplevel");
339                            g.setPaintMode();
340                            g.setColor(new Color(102, 102, 255, 100));
341                            if (sel) {
342                                    debug.println("selected");
343                                    //g.fillRect(0,0,getPreferredSize().width,getPreferredSize().height);
344                                    g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
345                                    debug.println("bounds: " + g.getClipBounds().toString());
346                            }
347    
348                    }
349            }
350    
351            public class TopOverlayClip extends JPanel {
352                    boolean sel;
353    
354                    public TopOverlayClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
355    
356                            this.sel = sel;
357                            OverlayClip o1 = new OverlayClip(browser, n, expanded, sel, hasFocus);
358                            String text = n.getLabel();
359                            JLabel textLabel = new JLabel();
360                            JLabel select = new JLabel(" (  selected)");
361                            select.setVisible(false);
362                            if ((n.getSelectedChildren().size() != 0) && (n.getSelectedChildren().size() < n.getChildCount())) {
363                                    select.setText(" (" + n.getSelectedChildren().size() + " selected)");
364                                    select.setVisible(true);
365                            }
366                            select.setOpaque(false);
367    
368                            if ((!expanded) && (o1 != null)) {
369                                    Layout.vertical(this).add(Layout.horizontal().add(select, Layout.FIXED_SIZE).addGlue()
370                                    //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
371                                    .done()).add(o1).done();
372                            }
373                            if ((!expanded) && (o1 == null)) {
374                                    Layout.vertical(this).add(Layout.horizontal().add(select, Layout.FIXED_SIZE).addGlue()
375                                    //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
376                                    .done()).done();
377                            }
378                            if (expanded) {
379                                    Layout.vertical(
380                                            this)
381                                                    .add(
382                                                            Layout
383                                                            .horizontal()
384                                                            .add(textLabel = new JLabel(text), Layout.FIXED_SIZE, Layout.WEST)
385                                                            .add(select, Layout.FIXED_SIZE)
386                                                            .addGlue()
387                                            //                       .add(explanationButton = ActionAdapters.toTinyButton(explainAction),  Layout.FIXED_SIZE)
388            .done())
389    
390                                            // .add(explanationText = new JTextArea(n.getExplanationText()))
391            .done();
392    
393                                    //              explanationText.getDocument().putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");
394                                    //              explanationText.setSize(explanationText.getPreferredSize());
395                            }
396                            setBorder(new LineBorder(new Color(220,220,220), 1));
397                            if (hasFocus) {
398                                    setBorder(new LineBorder(Color.blue, 1));
399                            }
400    
401                            setToolTipText(n.getExplanationText());
402                            setOpaque(true);
403                            setSize(getPreferredSize());
404    
405                    }
406    
407                    public void paint(Graphics g) {
408                            super.paint(g);
409                            debug.println("painting toplevel");
410                            g.setPaintMode();
411                            g.setColor(new Color(102, 102, 255, 100));
412                            if (sel) {
413                                    debug.println("selected");
414                                    //g.fillRect(0,0,getPreferredSize().width,getPreferredSize().height);
415                                    g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
416                                    debug.println("bounds: " + g.getClipBounds().toString());
417                            }
418    
419                    }
420    
421            }
422            public class OverlayClip extends JPanel {
423                    RegionSet rs;
424                    Browser browser;
425                    boolean expanded;
426                    Rectangle rect = null;
427                    Node node;
428                    Vector images = new Vector();
429                    boolean selected;
430                    int height = 0;
431                    int width = 0;
432    
433                    public OverlayClip(Browser browser, Node n, boolean expanded, boolean sel, boolean hasFocus) {
434                            this.selected = sel;
435                            this.rs = n.getMatch();
436                            this.node = n;
437    
438                            debug.println("creating overlay image: " + n.toString() + " " + n.getChildCount());
439                            for (Enumeration e = n.children(); e.hasMoreElements();) {
440                                    Node child = (Node)e.nextElement();
441                                    //                              MiniBrowser mb = new MiniBrowser(child.getImage());
442                                    //                              mb.show();
443                                    if (child.getImage() != null) {
444                                            //debug.println(child.getImage().toString());
445                                            images.add(child.getImage());
446                                            height = Math.max(height, ((BufferedImage)child.getImage()).getHeight());
447                                            width = Math.max(width, ((BufferedImage)child.getImage()).getWidth());
448                                            //debug.println("w: " + width + " h: " + height);
449                                    }
450                            }
451                            setPreferredSize(new Dimension(width, height));
452                    }
453    
454                    public void paintComponent(Graphics g) {
455    
456                            setBackground(Color.white);
457    
458                            //                      revalidate();
459                            //                      setSize(getPreferredSize());
460    
461                            super.paintComponent(g);
462    
463                            g.setPaintMode();
464                            g.setColor(Color.white);
465                            g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
466    
467                            for (Enumeration e = images.elements(); e.hasMoreElements();) {
468                                    BufferedImage img = (BufferedImage)e.nextElement();
469                                    int rgbColourSpec = 0xffffff;
470                                    // filter the supplied image 
471                                    Image image = createImage(new FilteredImageSource(img.getSource(), new ImageTransparencyFilter(rgbColourSpec)));
472    
473                                    g.drawImage(image, 0, 0, this);
474                            }
475    
476                            g.setPaintMode();
477                            g.setColor(new Color(102, 102, 255, 100));
478                            if (selected) {
479    
480                                    //g.fillRect(0,0,getPreferredSize().width,getPreferredSize().height);
481                                    g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
482                            }
483    
484                    }
485                    public BufferedImage getClip() {
486                            return (BufferedImage)this.createImage(width, height);
487                    }
488    
489            }
490    
491            public class MultiClip extends JPanel {
492                    RegionSet rs;
493                    Region r1 = null;
494                    Region r2 = null;
495                    Region r3 = null;
496                    Region r4 = null;
497                    Rectangle rect = null;
498                    Rectangle rect1 = new Rectangle(0, 0, 0, 0);
499                    Rectangle rect2 = new Rectangle(0, 0, 0, 0);
500                    Rectangle rect3 = new Rectangle(0, 0, 0, 0);
501                    Browser browser;
502                    boolean expanded;
503                    Rectangle regionRec1;
504                    Rectangle regionRec2;
505                    Rectangle regionRec3;
506                    Node node;
507    
508                    public MultiClip(Browser browser, Node n, boolean expanded, boolean sel) {
509                            RegionSet rs = n.getMatch();
510                            RegionEnumeration e = rs.regions();
511                            this.node = n;
512    
513                            for (Region r = e.first(); r != null; r = e.next()) {
514                                    if (!(r.getStart() == r.getEnd())) {
515                                            if (r1 == null)
516                                                    r1 = r;
517                                            else
518                                                    if (r2 == null)
519                                                            r2 = r;
520                                                    else
521                                                            if (r3 == null)
522                                                                    r3 = r;
523                                                            else
524                                                                    if (r4 == null)
525                                                                            r4 = r;
526                                                                    else
527                                                                            break;
528                                    }
529                            }
530    
531                            this.browser = browser;
532                            this.expanded = expanded;
533                            setRegions(r1, r2, r3);
534                            //          setPreferredSize(new Dimension((int)rect.getWidth(),(int)rect.getHeight()));
535                            SingleClip b1 = null;
536                            SingleClip b2 = null;
537                            SingleClip b3 = null;
538    
539                            if (r1 != null)
540                                    if (!(r1.getStart() == r1.getEnd()))
541                                            b1 = new SingleClip(browser, n, r1, false, false);
542                            if (r2 != null)
543                                    if (!(r2.getStart() == r2.getEnd()))
544                                            b2 = new SingleClip(browser, n, r2, false, false);
545                            if (r3 != null)
546                                    if (!(r3.getStart() == r3.getEnd()))
547                                            b3 = new SingleClip(browser, n, r3, false, false);
548                            String text = n.getLabel();
549                            if ((n.getSelectedChildren().size() != 0) && (n.getSelectedChildren().size() < n.getChildCount())) {
550                                    text = text + " (" + n.getSelectedChildren().size() + " selected)";
551                            }
552                            Layout.vertical(this).add(new JLabel(text)).done();
553    
554                            if (!expanded) {
555                                    //              setPreferredSize(new Dimension((int)rect.getWidth(),(int)rect.getHeight()));
556                                    if (b1 != null)
557                                            Layout.vertical(this).add(b1).done();
558                                    if (b2 != null)
559                                            Layout.vertical(this).add(b2).done();
560                                    if (b3 != null)
561                                            Layout.vertical(this).add(b3).done();
562                                    if (r4 != null)
563                                            if (!(r4.getStart() == r4.getEnd()))
564                                                    Layout.vertical(this).add(new JLabel("(more)")).done();
565                            }
566                            setBorder(new LineBorder(Color.red, 2));
567                            if (sel) {
568                                    setBorder(new LineBorder(Color.black, 2));
569                                    setBackground(new Color(102, 102, 255, 100));
570                                    //debug.println(n.toString() + " " + n.getExplanationText());
571                            }
572    
573                            setToolTipText(n.getExplanationText());
574                            setOpaque(true);
575    
576                    }
577    
578                    public void setRegions(Region r1, Region r2, Region r3) {
579    
580                            if (r1 != null) {
581                                    if (!(r1.getStart() == r1.getEnd())) {
582                                            try {
583                                                    regionRec1 = browser.getActivePane().regionToExpandedRectangle(r1);
584                                                    rect1 =
585                                                            new Rectangle(
586                                                                    regionRec1.x,
587                                                                    regionRec1.y,
588                                                                    Math.min(regionRec1.width + 200, browser.getActivePane().getWidth()),
589                                                                    regionRec1.height + 10);
590                                            }
591                                            catch (BadLocationException ble) {
592                                                    ble.printStackTrace();
593                                            }
594                                    }
595                                    if (r2 != null) {
596                                            if (!(r2.getStart() == r2.getEnd())) {
597                                                    try {
598                                                            regionRec2 = browser.getActivePane().regionToExpandedRectangle(r2);
599                                                            rect2 =
600                                                                    new Rectangle(
601                                                                            regionRec2.x,
602                                                                            regionRec2.y,
603                                                                            Math.min(regionRec2.width + 200, browser.getActivePane().getWidth()),
604                                                                            regionRec2.height + 10);
605                                                    }
606                                                    catch (BadLocationException ble) {
607                                                            ble.printStackTrace();
608                                                    }
609                                            }
610    
611                                            if (r3 != null) {
612                                                    if (!(r3.getStart() == r3.getEnd())) {
613                                                            try {
614                                                                    regionRec3 = browser.getActivePane().regionToExpandedRectangle(r3);
615                                                                    rect3 =
616                                                                            new Rectangle(
617                                                                                    regionRec3.x,
618                                                                                    regionRec3.y,
619                                                                                    Math.min(regionRec3.width + 200, browser.getActivePane().getWidth()),
620                                                                                    regionRec3.height + 10);
621                                                            }
622                                                            catch (BadLocationException ble) {
623                                                                    ble.printStackTrace();
624                                                            }
625                                                    }
626                                            }
627                                    }
628                            }
629                            int width = Math.max(rect1.width, Math.max(rect2.width, rect3.width)) + 6;
630                            int height = rect1.height + rect2.height + rect3.height + 30;
631                            rect = new Rectangle(0, 0, width, height);
632    
633                    }
634    
635            }
636    
637            public class SingleClip extends JPanel {
638                    int height = 0;
639                    int width = 0;
640                    public SingleClip(Browser browser, Node n, Region r, boolean selected, boolean hasFocus) {
641                            BrowserClip b = new BrowserClip(browser, n, r, selected);
642                            Layout.vertical(this).setContainerInsets(5, 0, 5, 0).add(b).done();
643                            //setPreferredSize(new Dimension((int)b.getPreferredSize().width, (int) b.getPreferredSize().height+10));
644                            //setBackground(Color.white);
645                            setSize(getPreferredSize());
646                            //          debug.println("S preferred: " + getPreferredSize().toString());
647                            //          debug.println("S size: " + getSize().toString());
648                            if (hasFocus) {
649                                    setBorder(new LineBorder(Color.blue, 1));
650                            }
651                            else
652                                    setBorder(new LineBorder(new Color(220,220,220), 1));
653                            if (n.getImage() != null){
654                                    height = ((BufferedImage)n.getImage()).getHeight();
655                                    width = ((BufferedImage)n.getImage()).getWidth();
656                            }
657                    }
658                    public BufferedImage getClip() {
659                            return (BufferedImage)this.createImage(width, height);
660                    }
661    
662            }
663    
664            public class BrowserClip extends JComponent {
665                    Region r;
666                    Rectangle rect;
667                    Browser browser;
668                    boolean selected;
669                    Rectangle regionRec;
670                    Node node;
671    
672                    public BrowserClip(Browser browser, Node n, Region r, boolean selected) {
673                            this.r = r;
674                            this.browser = browser;
675                            this.selected = selected;
676                            this.node = n;
677                            if (r != null) {
678                                    setRegion(r);
679                                    setPreferredSize(new Dimension((int)rect.getWidth(), (int)rect.getHeight()));
680                            }
681                            // setMaximumSize(getPreferredSize());
682                            setBackground(Color.white);
683                            setOpaque(true);
684                    }
685    
686                    //      public void setBounds(int x, int y, int w, int h) {
687                    //          super.setBounds(x, 0, w, MatchTree.this.getHeight());
688                    //      }
689    
690                    public void setRegion(Region r) {
691                            this.r = r;
692    
693                            try {
694                                    if (r != null) {
695                                            regionRec = browser.getActivePane().regionToExpandedRectangle(r);
696                                            //                                      rect =
697                                            //                                              new Rectangle(
698                                            //                                                      regionRec.x,
699                                            //                                                      regionRec.y,
700                                            //                                                      Math.min(regionRec.width + 200, browser.getActivePane().getWidth()),
701                                            //                                                      regionRec.height);
702                                            //                              }
703                                            rect = new Rectangle(regionRec.x, regionRec.y, regionRec.width + 200, regionRec.height);
704                                    }
705                                    //              debug.println("regionRec:  " + regionRec.toString() );
706                                    //              debug.println("boundingRec: " + rect.toString());
707                                    //              debug.println("region: " + r.toString());
708                            }
709                            catch (BadLocationException ble) {
710                                    ble.printStackTrace();
711                            }
712    
713                    }
714    
715                    public void paintComponent(Graphics g) {
716    
717                            setBackground(Color.white);
718    
719                            revalidate();
720                            setSize(getPreferredSize());
721    
722                            super.paintComponent(g);
723                            if (r != null) {
724    
725                                    g.setPaintMode();
726                                    g.setColor(Color.white);
727                                    g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
728    
729                                    if (node.getImage() != null)
730                                            g.drawImage(node.getImage(), 0, 0, this);
731                                    debug.println("painted browserClip");
732    
733                                    g.setPaintMode();
734                                    g.setColor(new Color(102, 102, 255, 100));
735                                    if (selected) {
736    
737                                            //      g.fillRect(0,0,getPreferredSize().width,getPreferredSize().height);
738                                            g.fillRect(g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
739                                    }
740                            }
741                    }
742    
743            }
744    
745            //      ImageTransparencyFilter.java - filter to create a transparent background 
746            //               Copyright (c) 1995, Optimation Software Engineering Pty. Ltd.,     
747            //                                                       Melbourne, Australia.                          
748    
749            //      $Id: ClusterRenderer.java,v 1.12 2003/08/07 05:45:35 minwu Exp $ 
750            /* 
751            
752             Revision 3.1  1996/08/12 06:27:41  ronm 
753             Moved to rev 3 
754            
755            # Revision 1.1  1996/07/15  05:29:39  grege 
756            # Initial revision 
757            # 
758             */
759    
760            public class ImageTransparencyFilter extends RGBImageFilter {
761    
762                    /** 
763                     * Default dimensions 
764                     */
765                    //              public static final int WIDTH = 100;
766                    //              public static final int HEIGHT = 100;
767                    //              public static final int EDGE = 10;
768    
769                    /** 
770                     * RGB value (24 bit) of the colour targetted for transparency 
771                     */
772                    protected int transTargetColour;
773    
774                    /** 
775                     * Construct an ImageTransparencyFilter for `targetColour` 
776                     */
777                    public ImageTransparencyFilter(int targetColour) {
778    
779                            transTargetColour = targetColour;
780                            canFilterIndexColorModel = true;
781    
782                    }
783    
784                    /** 
785                     * @return a filtered RGB 
786                     */
787                    public int filterRGB(int x, int y, int rgb) {
788    
789                            if ((rgb & 0xffffff) == transTargetColour) {
790                                    // pull out the rgb values (ignore alpha) 
791                                    return 0; // alpha == 0   
792                            }
793                            else {
794                                    // nothing to filter 
795                                    return rgb;
796                            }
797    
798                    }
799    
800            }
801    
802    }