       1 /*
       2  * $Id$
       3  *
       4  * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
       5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       6  *
       7  * This code is free software; you can redistribute it and/or modify it
       8  * under the terms of the GNU General Public License version 2 only, as
       9  * published by the Free Software Foundation.  Oracle designates this
      10  * particular file as subject to the "Classpath" exception as provided
      11  * by Oracle in the LICENSE file that accompanied this code.
      12  *
      13  * This code is distributed in the hope that it will be useful, but WITHOUT
      14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16  * version 2 for more details (a copy is included in the LICENSE file that
      17  * accompanied this code).
      18  *
      19  * You should have received a copy of the GNU General Public License version
      20  * 2 along with this work; if not, write to the Free Software Foundation,
      21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      22  *
      23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
      24  * or visit www.oracle.com if you need additional information or have any
      25  * questions.
      26  */
      27 package com.sun.javatest.agent;
      28
      29 import java.awt.AWTEventMulticaster;
      30 import java.awt.CardLayout;
      31 import java.awt.Color;
      32 import java.awt.Component;
      33 import java.awt.Container;
      34 import java.awt.Dimension;
      35 import java.awt.FontMetrics;
      36 import java.awt.Graphics;
      37 import java.awt.Insets;
      38 import java.awt.ItemSelectable;
      39 import java.awt.Panel;
      40 import java.awt.Polygon;
      41 import java.awt.event.ItemEvent;
      42 import java.awt.event.ItemListener;
      43 import java.awt.event.MouseAdapter;
      44 import java.awt.event.MouseEvent;
      45 import java.awt.event.MouseListener;
      46 import java.util.Vector;
      47
      48 /**
      49  * Folder is a panel with a layout based on CardLayout that also provides GUI controls
      50  * to allow a user-selected component to be displayed.
      51  */
      52
      53 class Folder extends Panel implements ItemSelectable
      54 {
      55     private class Entry
      56     {
      57         Entry(Component comp, String name, Color color, boolean visibleTab) {
      58             this.comp = comp;
      59             this.name = name;
      60             this.color = color;
      61             this.visibleTab = visibleTab;
      62         }
      63
      64         Component comp;
      65         String name;
      66         Color color;
      67         boolean visibleTab;
      68     }
      69
      70     private class Layout extends CardLayout
      71     {
      72         public Dimension minimumLayoutSize(Container parent) {
      73             Dimension size = super.minimumLayoutSize(parent);
      74             int width = Math.max(size.width, ((Folder)parent).getMinimumWidth());
      75             return new Dimension(width, size.height);
      76         }
      77
      78         public Dimension preferredLayoutSize(Container parent) {
      79             Dimension size = super.preferredLayoutSize(parent);
      80             int width = Math.max(size.width, ((Folder)parent).getMinimumWidth());
      81             return new Dimension(width, size.height);
      82         }
      83     }
      84
      85     public Folder() {
      86         this(0, 0);
      87     }
      88
      89     public Folder(int hgap, int vgap) {
      90         this(hgap, vgap, 10, 5, 5);
      91     }
      92
      93     Folder(int hgap, int vgap, int border, int slant, int tabSpace) {
      94         this.hgap = hgap;
      95         this.vgap = vgap;
      96         this.border = border;
      97         this.slant = slant;
      98         this.tabSpace = tabSpace;
      99         this.tabpad = 10;
     100         //setLayout(new Layout());
     101         setLayout(new CardLayout());
     102
     103         MouseListener mouseListener = new MouseAdapter() {
     104             public void mousePressed(MouseEvent e) {
     105                 Folder.this.mousePressed(e.getX(), e.getY());
     106             }
     107         };
     108
     109         addMouseListener(mouseListener);
     110     }
     111
     112     public Insets getInsets() {
     113         FontMetrics fm = getFontMetrics(getFont());
     114         int left_right = border + hgap;
     115         int top = border + (fm == null ? 0 : fm.getHeight()) + tabpad + vgap;
     116         int bottom = border + vgap;
     117         return new Insets(top, left_right, bottom, left_right);
     118     }
     119
     120     public Component add(String name, Component comp) {
     121         entries.addElement(new Entry(comp, name, null, true));
     122         return super.add(name, comp);
     123     }
     124
     125     public Component add(String name, Component comp, Color color) {
     126         entries.addElement(new Entry(comp, name, color, true));
     127         return super.add(name, comp);
     128     }
     129
     130     public Component add(String name, Component comp, Color color, boolean visibleTab) {
     131         entries.addElement(new Entry(comp, name, color, visibleTab));
     132         return super.add(name, comp);
     133     }
     134
     135
     136     public void showTab(String name) {
     137         showTab(name, true);
     138     }
     139
     140     public void hideTab(String name) {
     141         showTab(name, false);
     142     }
     143
     144     public void showTab(String name, boolean visible) {
     145         for (int i = 0; i < entries.size(); i++) {
     146             Entry e = (Entry)entries.elementAt(i);
     147             if (e.name.equals(name)) {
     148                 if (e.visibleTab != visible) {
     149                     e.visibleTab = visible;
     150                     repaint();
     151                 }
     152                 return;
     153             }
     154         }
     155     }
     156
     157     public String getNextVisibleTab() {
     158         int currentIndex = Math.max(0, getCurrentIndex());
     159         for (int i = currentIndex + 1; i < entries.size(); i++) {
     160             Entry e = (Entry)entries.elementAt(i);
     161             if (e.visibleTab)
     162                 return e.name;
     163         }
     164         return null;
     165     }
     166
     167     public String getPrevVisibleTab() {
     168         int currentIndex = getCurrentIndex();
     169         for (int i = currentIndex - 1; i >= 0; i--) {
     170             Entry e = (Entry)entries.elementAt(i);
     171             if (e.visibleTab)
     172                 return e.name;
     173         }
     174         return null;
     175     }
     176
     177     public Component current() {
     178         for (int i = 0; i < entries.size(); i++) {
     179             Entry e = (Entry)entries.elementAt(i);
     180             if (e.comp.isVisible())
     181                 return e.comp;
     182         }
     183         return null;
     184     }
     185
     186     public void show(Component comp) {
     187         for (int i = 0; i < entries.size(); i++) {
     188             Entry e = (Entry)entries.elementAt(i);
     189             if (e.comp == comp) {
     190                 show(e);
     191                 return;
     192             }
     193         }
     194     }
     195
     196     public void show(String name) {
     197         for (int i = 0; i < entries.size(); i++) {
     198             Entry e = (Entry)entries.elementAt(i);
     199             if (e.name.equals(name)) {
     200                 show(e);
     201                 return;
     202             }
     203         }
     204     }
     205
     206     public void paint(Graphics g) {
     207
     208         if (entries == null || entries.isEmpty()) {
     209             return;
     210         }
     211
     212         Dimension dims = getSize();
     213
     214         FontMetrics fm = g.getFontMetrics();
     215         int tabHeight = fm.getHeight() + tabpad;
     216         Entry selected = null;
     217         for (int i = 0; i < entries.size(); i++) {
     218             Entry e = (Entry)entries.elementAt(i);
     219             if (e.comp.isVisible()) {
     220                 selected = e;
     221                 break;
     222             }
     223         }
     224         if (selected != null) {
     225             g.setColor(selected.color != null ? selected.color : getBackground());
     226         }
     227         g.fillRoundRect(hgap, tabHeight + vgap,
     228             dims.width - 2*hgap - 1, dims.height - tabHeight - 2*vgap - 1,
     229             border, border);
     230         g.setColor(getForeground());
     231         g.drawRoundRect(hgap, tabHeight + vgap,
     232               dims.width - 2*hgap - 1, dims.height - tabHeight - 2*vgap - 1,
     233               border, border);
     234         int x = border + hgap;
     235         int baseLine = tabHeight + vgap;
     236         for (int i = 0; i < entries.size(); i++) {
     237             Entry e = (Entry)entries.elementAt(i);
     238             int tabH = (e.visibleTab || e.comp.isVisible() ? tabHeight : tabHeight / 3);
     239             int w = fm.stringWidth(e.name);
     240             Polygon tab = new Polygon();
     241             tab.addPoint(x, baseLine);
     242             tab.addPoint(x + slant, baseLine - tabH);
     243             tab.addPoint(x + slant + w, baseLine - tabH);
     244             tab.addPoint(x + slant + w + slant, baseLine);
     245             if (e.color != null) {
     246                 g.setColor(e.color);
     247                 g.fillPolygon(tab);
     248             }
     249             g.setColor(getForeground());
     250             g.drawLine(tab.xpoints[0], tab.ypoints[0], tab.xpoints[1], tab.ypoints[1]);
     251             g.drawLine(tab.xpoints[1], tab.ypoints[1], tab.xpoints[2], tab.ypoints[2]);
     252             g.drawLine(tab.xpoints[2], tab.ypoints[2], tab.xpoints[3], tab.ypoints[3]);
     253             if (e.visibleTab || e.comp.isVisible())
     254                 g.drawString(e.name, x + slant, baseLine - tabpad/2 - fm.getDescent());
     255             if (e.comp.isVisible()) {
     256                 g.setColor(e.color != null ? e.color : getBackground());
     257                 g.drawLine(tab.xpoints[0], tab.ypoints[0], tab.xpoints[3], tab.ypoints[3]);
     258             }
     259             x = tab.xpoints[3] + tabSpace;
     260         }
     261
     262         super.paint(g);
     263     }
     264
     265     public void addItemListener(ItemListener l) {
     266         itemListener = AWTEventMulticaster.add(itemListener, l);
     267     }
     268
     269     public void removeItemListener(ItemListener l) {
     270         itemListener = AWTEventMulticaster.remove(itemListener, l);
     271     }
     272
     273     public Object[] getSelectedObjects() {
     274         Entry ce = getCurrentEntry();
     275         if (ce == null)
     276             return null;
     277         else
     278             return new Object[] { ce.comp };
     279     }
     280
     281     int getMinimumWidth() {
     282         FontMetrics fm = getFontMetrics(getFont());
     283         int w = border + 2 * hgap + tabSpace;
     284         for (int i = 0; i < entries.size(); i++) {
     285           Entry e = (Entry)entries.elementAt(i);
     286           w += slant + (fm == null ? 0 : fm.stringWidth(e.name)) + slant + tabSpace;
     287         }
     288         return w;
     289     }
     290
     291     private void show(Entry e) {
     292         Entry prevEntry = getCurrentEntry();
     293         Component prevComp = (prevEntry == null ? null : prevEntry.comp);
     294
     295         ((CardLayout)getLayout()).show(this, e.name);
     296         repaint(); // needed to repaint the tab area
     297
     298         if (itemListener != null) {
     299             ItemEvent ev1 =
     300                 new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
     301                               prevComp, ItemEvent.DESELECTED);
     302             ItemEvent ev2 =
     303                 new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
     304                               e.comp, ItemEvent.SELECTED);
     305             itemListener.itemStateChanged(ev1);
     306             itemListener.itemStateChanged(ev2);
     307         }
     308     }
     309
     310     private int getCurrentIndex() {
     311         for (int i = 0; i < entries.size(); i++) {
     312             Entry e = (Entry)entries.elementAt(i);
     313             if (e.comp.isVisible())
     314                 return i;
     315         }
     316         return -1;
     317     }
     318
     319     private Entry getCurrentEntry() {
     320         int i = getCurrentIndex();
     321         return (i == -1 ? null : (Entry)(entries.elementAt(i)) );
     322     }
     323
     324     void mousePressed(int mouseX, int mouseY) {
     325         FontMetrics fm = getFontMetrics(getFont());
     326         if (vgap < mouseY  &&  mouseY < border + fm.getHeight() + vgap) {
     327             int x = border + hgap;
     328             for (int i = 0; i < entries.size(); i++) {
     329                 Entry e = (Entry)entries.elementAt(i);
     330                 int w = fm.stringWidth(e.name);
     331                 x += slant + w + slant + tabSpace;
     332                 if (mouseX < x) {
     333                     show(e);
     334                     break;
     335                 }
     336             }
     337         }
     338     }
     339
     340
     341     private ItemListener itemListener;
     342     private Vector entries = new Vector();
     343     private int border;
     344     private int slant;
     345     private int tabSpace;
     346     private int hgap;
     347     private int vgap;
     348     private int tabpad;
     349 }
     350