Package com.sshtools.ui.awt

Source Code of com.sshtools.ui.awt.TabbedPanel$TabbedLayout

package com.sshtools.ui.awt;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
* <p>
* AWT component to provide a tabbed pane similar to Swings JTabbedPane (albeit somewhat simpler!).
* </p>
*
* <p>
* Each component added except the first will be invisible until the user clicks on the tab heading either above, below. to the
* left, or to the right of the visible component. Clicking on the heading will hide the current tab and make the new selection
* visible.
* </p>
*
* @author $Author: lee $
*/

public class TabbedPanel
    extends Container {

  /**
   * Tabs are placed above the components
   */
  public final static int TOP = 0;

  /**
   * Tabs are placed to the left of the components
   */
  public final static int LEFT = 1;

  /**
   * Tabs are placed below the components
   */
  public final static int BOTTOM = 2;

  /**
   * Tabs are placed to the right of the components
   */
  public final static int RIGHT = 3;

  //
  private final static Insets DEFAULT_INSETS = new Insets(2, 2, 2, 2);
  private final static int HORIZONTAL_GAP = 3;
  private final static int VERTICAL_GAP = 3;
  private final static int IMAGE_TEXT_GAP = 2;

  //  Private instance variables
  private int position;
  private FontMetrics metrics;
  private Hashtable tabs;
  private int sel;
  private TabbedLayout layout;
  private Vector listenerList;

  /**
   * <p>
   * Create a tabbed panel with the tabs at the specified position. Can be one of :-
   * </p>
   * <ul>
   * <li>TabbedPanel.TOP</li>
   * <li>TabbedPanel.LEFT</li>
   * <li>TabbedPanel.BOTTOM</li>
   * <li>TabbedPanel.RIGHT</li>
   * </ul>
   *
   * <p>
   * <b><font color="#ff0000">Note, only <i>TOP</i> is currently supported</font></b>
   * </p>
   *
   * @param position position
   */
  public TabbedPanel(int position) {
    super();

    tabs = new Hashtable();
    listenerList = new Vector();
    sel = -1;

    setLayout(layout = new TabbedLayout(3, 3));
    setPosition(position);

    addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent evt) {
        for (Enumeration e = tabs.elements(); e.hasMoreElements(); ) {
          TabWrapper w = (TabWrapper) e.nextElement();
          if (w.bounds != null && w.bounds.contains(evt.getX(), evt.getY())) {
            int idx = indexOfTab(w);
            if (idx != sel) {
              setSelectedTab(idx);
            }
            break;
          }
        }

      }
    });

    //        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  }

  /**
   * Add an <code>ActionListener</code> to be informed when the user selects
   * a tab.
   *
   * @param l listener to add
   */
  public void addActionListener(ActionListener l) {
    listenerList.addElement(l);
  }

  /**
   * Remove an <code>ActionListener</code> so as to no longer be informed when
   * the user selects a tab.
   *
   * @param l listener to remove
   */
  public void removeActionListener(ActionListener l) {
    listenerList.removeElement(l);
  }

  /**
   * Set the title of a tab at the given index
   *
   * @param i index of tab
   * @param title new tab title
   */
  public void setTitleAt(int i, String title) {
    Component c = getComponent(sel);
    TabWrapper t = (TabWrapper) tabs.get(c);
    t.text = title;
    repaint();
  }

  /**
   * Set the selected tab given its index.
   *
   * @param idx index of tab to select
   */
  public void setSelectedTab(int idx) {
    sel = idx;
    if (sel != -1) {
      int s = listenerList.size();
      ActionEvent aevt = null;
      for (int i = s - 1; i >= 0; i--) {
        if (aevt == null) {
          aevt = new ActionEvent(TabbedPanel.this, ActionEvent.ACTION_PERFORMED,
                                 ""); //$NON-NLS-1$
        }
        ( (ActionListener) listenerList.elementAt(i)).actionPerformed(aevt);
      }
      Component c = getComponent(sel);
      TabWrapper t = (TabWrapper) tabs.get(c);
      if(t != null) {
          layout.show(this, (String) t.name);
      }
      repaint();
    }
  }

  /**
   * Get the index of the currently selected tab
   *
   * @return selected tab index
   */
  public int getSelectedTab() {
    return sel;
  }

  /**
   * <p>
   * Create a tabbed panel with the tabs at the specified position. Can be one of :-
   * </p>
   * <ul>
   * <li>TabbedPanel.TOP</li>
   * <li>TabbedPanel.LEFT</li>
   * <li>TabbedPanel.BOTTOM</li>
   * <li>TabbedPanel.RIGHT</li>
   * </ul>
   *
   * <p>
   * <b><font color="#ff0000">Note, only <i>TOP</i> is currently supported</font></b>
   * </p>
   *
   * @param position position
   */
  public void setPosition(int position) {
    doLayout();
    repaint();
  }

  public void remove(int idx) {
    Component c = getComponent(idx);
    TabWrapper t = (TabWrapper) tabs.get(c);
    tabs.remove(c);
    if (sel == idx) {
      setSelectedTab(tabs.size() - 1);
    }
    super.remove(idx);
  }

  /**
   * Add a tab.
   *
   * @param comp component
   * @param constraints tab name
   * @param index tab index
   * @param image tab image
   */
  public void add(Component comp, Object constraints, int index, Image image) {
    TabWrapper w = new TabWrapper(comp.getName(), String.valueOf(constraints),
                                  image, comp, constraints);
    tabs.put(comp, w);
    super.addImpl(comp, comp.getName(), index);
    if (sel == -1) {
      setSelectedTab(0);
    }
    else {
      repaint();
    }
  }

  public int getPosition() {
    return position;
  }

  public void removeNotify() {
    super.removeNotify();
    if (getComponentCount() == 0) {
      sel = -1;
    }
  }

  protected void addImpl(Component comp, Object constraints, int index) {
    add(comp, constraints, index, null);
  }

  public void add(Component comp, Object constraints, Image image) {
    add(comp, constraints, -1, image);
  }

  public Insets getInsets() {
    return DEFAULT_INSETS;
  }

  public void addNotify() {
    super.addNotify();
    metrics = getFontMetrics(getFont());
  }

  public void paint(Graphics g) {
    super.paint(g);

    Dimension s = getSize();
    Rectangle r = getHeadingBounds();
    int ncomponents = getComponentCount();
    int sel = getSelectedTab();

    // Work out the colors for the border
    Color c = getBackground();
    Color midlight = c.brighter();
    Color highlight = midlight.brighter();
    Color lowlight = c.darker();
    Color shadow = lowlight.darker();
    Color darkShadow = shadow.darker();

    //
    switch (position) {
      case TOP:

        //
        g.setColor(darkShadow);
        g.drawLine(0, s.height - 1, s.width - 1, s.height - 1);
        g.drawLine(s.width - 1, s.height - 1, s.width - 1, r.height - 1);
        //
        g.setColor(shadow);
        g.drawLine(1, s.height - 2, s.width - 2, s.height - 2);
        g.drawLine(s.width - 2, s.height - 2, s.width - 2, r.height);
        //
        g.setColor(highlight);
        g.drawLine(0, s.height - 2, 0, r.height);

        //  Paint the tabs
        int x = 0;
        int selx = -1;

        for (int i = 0; i < ncomponents; i++) {
          Component comp = getComponent(i);
          TabWrapper tab = (TabWrapper) tabs.get(comp);

          if (tab != null) {

            int hw = metrics.stringWidth(tab.text) + (HORIZONTAL_GAP * 2);
            tab.bounds = new Rectangle(x, 0, hw, r.height);

            if (sel == i) {
              selx = x;
              //                    g.setColor(darkShadow);
            }
            else {
              g.setColor(lowlight);
              g.fillRect(x, 3, hw - 1, r.height - 4);

              //
              g.setColor(midlight);
              g.drawLine(x, 3, x, r.height - 2);
              g.drawLine(x + 1, 2, x + hw - 2, 2);
              //
              g.setColor(darkShadow);
              g.drawLine(x + hw - 1, 3, x + hw - 1, r.height - 2);
              //
              g.setColor(shadow);
              g.drawLine(x + hw - 2, 4, x + hw - 2, r.height - 2);
              //
              g.setColor(highlight);
              g.drawLine(x, r.height - 1, x + hw - 1, r.height - 1);

              g.setColor(getForeground());
              g.drawString(tab.text, x + HORIZONTAL_GAP,
                           (r.height / 2) + (metrics.getHeight() / 2) - 1);
              //                    g.setColor(darkShadow);
            }

            x += hw;
          }

        }
        g.setColor(highlight);
        g.drawLine(x, r.height - 1, s.width - 2, r.height - 1);

        if (selx != -1) {
          x = selx;
          Component comp = getComponent(sel);
          TabWrapper tab = (TabWrapper) tabs.get(comp);

          int hw = metrics.stringWidth(tab.text) + (HORIZONTAL_GAP * 2);

          //                    g.setColor(getBackground());
          //                    g.fillRect(x, 3, hw - 1, r.height - 3);

          //
          g.setColor(highlight);
          g.drawLine(x, 1, x, r.height - 2);
          g.drawLine(x + 1, 0, x + hw - 1, 0);
          //
          g.setColor(darkShadow);
          g.drawLine(x + hw, 1, x + hw, r.height - 2);
          //
          g.setColor(shadow);
          g.drawLine(x + hw - 1, 2, x + hw - 1, r.height - 2);

          g.setColor(getForeground());
          g.drawString(tab.text, x + HORIZONTAL_GAP,
                       (r.height / 2) + (metrics.getHeight() / 2) - 3);
        }
        break;
    }
  }

  //
  private Dimension getHeadingSize() {
    Dimension s = new Dimension();
    int c = getComponentCount();
    for (int i = 0; i < c; i++) {
      Component comp = getComponent(i);
      TabWrapper tab = (TabWrapper) tabs.get(comp);
      if (tab != null) {
        int thw =
            (HORIZONTAL_GAP * 2)
            +
            (metrics != null ?
             metrics.stringWidth(tab.text == null ? "" : tab.text) : 0) //$NON-NLS-1$
            + (tab.image == null ? 0 : (IMAGE_TEXT_GAP + tab.image.getWidth(this)));
        int thh = (VERTICAL_GAP * 2) +
            Math.max(metrics != null ? metrics.getHeight() : 0,
                     tab.image == null ? 0 : tab.image.getHeight(this));
        if (position == TOP || position == BOTTOM) {
          s.width += thw;
          s.height = Math.max(s.height, thh);
        }
        else {
          s.height += thh;
          s.width = Math.max(s.width, thw);
        }
      }
      else {
        /*DEBUG*/System.err.println(Messages.getString("TabbedPanel.tabWrapperCouldNotBeFound") + i + " [" + comp + //$NON-NLS-1$ //$NON-NLS-2$
                                    " could not be found"); //$NON-NLS-1$
      }
    }
    return s;

  }

  /*
   * Get the bounds of the tab headings
   */
  private Rectangle getHeadingBounds() {
    Dimension s = getHeadingSize();
    Point loc = new Point();
    switch (position) {
      case BOTTOM:
        loc.y = getSize().height - s.height;
        break;
      case RIGHT:
        loc.x = getSize().width - s.width;
        break;
    }
    return new Rectangle(loc.x, loc.y, s.width, s.height);
  }

  private int indexOfTab(TabWrapper tab) {
    int c = getComponentCount();
    for (int i = 0; i < c; i++) {
      if (tab.component == getComponent(i)) {
        return i;
      }
    }
    return -1;
  }

  //  Debug
  public static void main(String[] args) {
    Frame frame = new Frame("Tabs"); //$NON-NLS-1$
    frame.setLayout(new BorderLayout());

    Label l1 = new Label("Test label 1"); //$NON-NLS-1$
    Panel p1 = new Panel(new BorderLayout());
    p1.add(l1, BorderLayout.CENTER);

    Label l2 = new Label("Test label 2"); //$NON-NLS-1$
    Panel p2 = new Panel(new BorderLayout());
    p2.add(l2, BorderLayout.CENTER);

    Label l3 = new Label("Test label 3"); //$NON-NLS-1$
    Panel p3 = new Panel(new BorderLayout());
    p3.add(l3, BorderLayout.CENTER);

    Label l4 = new Label("Test label 4"); //$NON-NLS-1$
    Panel p4 = new Panel(new BorderLayout());
    p4.add(l4, BorderLayout.CENTER);

    TabbedPanel tabs = new TabbedPanel(TabbedPanel.TOP);
    tabs.add("Test Tab 1", p1); //$NON-NLS-1$
    tabs.add(Messages.getString("TabbedPanel.11"), p2); //$NON-NLS-1$
    tabs.add(Messages.getString("TabbedPanel.12"), p3); //$NON-NLS-1$
    tabs.add(Messages.getString("TabbedPanel.13"), p4); //$NON-NLS-1$

    tabs.setSelectedTab(1);

    frame.add(tabs, BorderLayout.CENTER);
    frame.pack();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) {
        System.exit(0);
      }

    });
    frame.setVisible(true);
  }

  //  Supporting classes

  class TabWrapper {
    Component component;
    String text;
    Image image;
    Rectangle bounds;
    Object constraints;
    String name;

    TabWrapper(String name, String text, Image image, Component component,
               Object contraints) {
      this.name = name;
      this.text = text;
      this.image = image;
      this.component = component;
      this.constraints = contraints;
    }
  }

  class TabbedLayout
      extends CardLayout {
    TabbedLayout(int hgap, int vgap) {
      super(hgap, vgap);
    }

    public void layoutContainer(Container parent) {
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        Component comp = null;
        boolean currentFound = false;
        Dimension s = getHeadingSize();
        int headingSize = position == TOP || position == BOTTOM ? s.height :
            s.width;
        insets =
            new Insets(
            insets.top + (position == TOP ? headingSize : 0),
            insets.left + (position == LEFT ? headingSize : 0),
            insets.bottom + (position == BOTTOM ? headingSize : 0),
            insets.right + (position == BOTTOM ? headingSize : 0));
        for (int i = 0; i < ncomponents; i++) {
          comp = parent.getComponent(i);
          comp.setBounds(
              getHgap() + insets.left,
              getVgap() + insets.top,
              parent.getSize().width -
              (getHgap() * 2 + insets.left + insets.right),
              parent.getSize().height -
              (getVgap() * 2 + insets.top + insets.bottom));
          if (comp.isVisible()) {
            currentFound = true;
          }
        }

        if (!currentFound && ncomponents > 0) {
          parent.getComponent(0).setVisible(true);
        }
      }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
     */
    public Dimension minimumLayoutSize(Container parent) {
      Dimension s = super.maximumLayoutSize(parent);
      Dimension c = getHeadingSize();
      return position == TOP
          || position == BOTTOM
          ? new Dimension(Math.max(s.width, c.width), s.height + c.height)
          : new Dimension(s.width + c.width, Math.max(s.height, c.height));
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
     */
    public Dimension preferredLayoutSize(Container parent) {
      Dimension s = super.preferredLayoutSize(parent);
      Dimension c = getHeadingSize();
      return position == TOP
          || position == BOTTOM
          ? new Dimension(Math.max(s.width, c.width), s.height + c.height)
          : new Dimension(s.width + c.width, Math.max(s.height, c.height));
    }
  }

  /**
   * @return
   */
  public int getSelectedTabIndex() {
    return sel;
  }

}
TOP

Related Classes of com.sshtools.ui.awt.TabbedPanel$TabbedLayout

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.