Package com.sun.dtv.lwuit

Source Code of com.sun.dtv.lwuit.TabbedPane$TabsRenderer

/*
* Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.dtv.lwuit;

import com.sun.dtv.lwuit.events.SelectionListener;
import com.sun.dtv.lwuit.geom.Dimension;
import com.sun.dtv.lwuit.geom.Rectangle;
import com.sun.dtv.lwuit.layouts.BorderLayout;
import com.sun.dtv.lwuit.list.DefaultListModel;
import com.sun.dtv.lwuit.list.ListCellRenderer;
import com.sun.dtv.lwuit.plaf.Style;
import com.sun.dtv.lwuit.plaf.UIManager;
import java.util.Hashtable;

/**
* A component that lets the user switch between a group of components by
* clicking on a tab with a given title and/or icon.
*
* <p>
* Tabs/components are added to a <code>TabbedPane</code> object by using the
* <code>addTab</code> and <code>insertTab</code> methods.
* A tab is represented by an index corresponding
* to the position it was added in, where the first tab has an index equal to 0
* and the last tab has an index equal to the tab count minus 1.
* <p>
* The <code>TabbedPane</code> uses a <code>SingleSelectionModel</code>
* to represent the set of tab indices and the currently selected index. 
* If the tab count is greater than 0, then there will always be a selected
* index, which by default will be initialized to the first tab. 
* If the tab count is 0, then the selected index will be -1.
* <p>
*
* @author Tamir Shabat
*
*/
public class TabbedPane extends Container {

    private Container contentPane = new Container(new BorderLayout());
    private List tabsList = new List();
    private Hashtable tabsTable = new Hashtable();
    /**
     * Where the tabs are placed.
     */
    private int tabPlacement = -1;
    /**
     * The TabbedPane surrounded border width (contentPane and tabs border)
     */
    private int tPBorder = 1;

    /**
     * Creates an empty <code>TabbedPane</code> with a default
     * tab placement of <code>Component.TOP</code>.
     */
    public TabbedPane() {
        this(TOP);
    }

    /**
     * Creates an empty <code>TabbedPane</code> with the specified tab placement
     * of either: <code>Component.TOP</code>, <code>Component.BOTTOM</code>,
     * <code>Component.LEFT</code>, or <code>Component.RIGHT</code>.
     *
     * @param tabPlacement the placement for the tabs relative to the content
     */
    public TabbedPane(int tabPlacement) {
        super(new BorderLayout());
        contentPane.getStyle().setBgPainter(new Painter() {

            public void paint(Graphics g, Rectangle rect) {
                UIManager.getInstance().getLookAndFeel().
                        drawTabbedPaneContentPane(TabbedPane.this, g, rect,
                        tabsList.getPreferredSize(), tabsList.size(),
                        tabsList.getSelectedIndex(), tabsList.getElementSize(true),
                        tabsList.getScrollX(), tabsList.getScrollY());
            }
        });
        super.addComponent(BorderLayout.CENTER, contentPane);
       
        setTabPlacement(tabPlacement);

        tabsList.getStyle().setPadding(0, 0, 0, 0);
        tabsList.getStyle().setMargin(0, 0, 0, 0);
        tabsList.getStyle().setBorder(null);
        tabsList.setListCellRenderer(new TabsRenderer());
        tabsList.setItemGap(0);
        tabsList.setIsScrollVisible(false);
        tabsList.setSmoothScrolling(false);
        tabsList.setBorderGap(0);       
        tabsList.addSelectionListener(new SelectionListener() {

            public void selectionChanged(int oldSelected, int newSelected) {
                Component c = (Component) tabsList.getModel().getItemAt(newSelected);
                contentPane.removeAll();
                contentPane.addComponent("Center", (Component) tabsTable.get(c));
                revalidate();
            }
        });       
       
    }

    /**
     * @inheritDoc
     */
    public void setFocusable(boolean b) {
        if(tabsList != null) {
            tabsList.setFocusable(b);
        }
        super.setFocusable(b);
    }
   
    /**
     * This method adds a listener to the tabs.
     *
     * @param listener a selection listener to gets the selection
     * events
     */
    public void addTabsListener(SelectionListener listener){
        tabsList.addSelectionListener(listener);
    }
   
    /**
     * @inheritDoc
     */
    public void requestFocus() {
        tabsList.requestFocus();
    }
   
    /**
     * @inheritDoc
     */
    protected Dimension calcPreferredSize() {
        int maxContentW = 0;
        int maxContentH = 0;
        int maxW = 0;
        int maxH = 0;

        for (int i = 0; i < tabsList.size(); i++) {
            Component tabsComp = (Component) tabsList.getModel().getItemAt(i);
            Component contentComp = (Component) tabsTable.get(tabsComp);

            if (contentComp.getPreferredSize().getWidth() > maxContentW) {
                maxContentW = contentComp.getPreferredSize().getWidth();
            }
            if (contentComp.getPreferredSize().getHeight() > maxContentH) {
                maxContentH = contentComp.getPreferredSize().getHeight();
            }
        }
        if (tabPlacement == TOP || tabPlacement == BOTTOM) {
            maxW = maxContentW;
            maxH = tabsList.getPreferredSize().getHeight() + maxContentH;
        } else {
            maxW = tabsList.getPreferredSize().getWidth() + maxContentW;
            maxH = maxContentH;
        }
        return new Dimension(maxW, maxH);
    }

    /**
     * Sets the tab placement for this tabbedpane.
     * Possible values are:<ul>
     * <li><code>Component.TOP</code>
     * <li><code>Component.BOTTOM</code>
     * <li><code>Component.LEFT</code>
     * <li><code>Component.RIGHT</code>
     * </ul>
     * The default value, if not set, is <code>Component.TOP</code>.
     *
     * @param tabPlacement the placement for the tabs relative to the content
     */
    public void setTabPlacement(int tabPlacement) {
        if (tabPlacement != TOP && tabPlacement != LEFT &&
                tabPlacement != BOTTOM && tabPlacement != RIGHT) {
            throw new IllegalArgumentException("illegal tab placement: must be TOP, BOTTOM, LEFT, or RIGHT");
        }
        if (this.tabPlacement == tabPlacement) {
            return;
        }
        this.tabPlacement = tabPlacement;
        removeComponent(tabsList);
       
        if (tabPlacement == TOP || tabPlacement == BOTTOM) {
            tabsList.setOrientation(List.HORIZONTAL);
            if (tabPlacement == TOP) {
                super.addComponent(BorderLayout.NORTH, tabsList);
            } else if (tabPlacement == BOTTOM) {
                super.addComponent(BorderLayout.SOUTH, tabsList);
            }
        } else {// LEFT Or RIGHT
            tabsList.setOrientation(List.VERTICAL);
            if (tabPlacement == LEFT) {
                super.addComponent(BorderLayout.WEST, tabsList);
            } else {// RIGHT
                super.addComponent(BorderLayout.EAST, tabsList);
            }
        }
        tabsList.setShouldCalcPreferredSize(true);
        contentPane.setShouldCalcPreferredSize(true);

        revalidate();
    }

    /**
     * Adds a <code>component</code>
     * represented by a <code>title</code> and/or <code>icon</code>,
     * either of which can be <code>null</code>.
     * Cover method for <code>insertTab</code>.
     *
     * @param title the title to be displayed in this tab
     * @param icon the icon to be displayed in this tab
     * @param component the component to be displayed when this tab is clicked
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void addTab(String title, Image icon, Component component) {
        insertTab(title, icon, component, tabsList.size());
    }

    /**
     * Adds a <code>component</code>
     * represented by a <code>title</code> and no <code>icon</code>.
     * Cover method for <code>insertTab</code>.
     *
     * @param title the title to be displayed in this tab
     * @param component the component to be displayed when this tab is clicked
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void addTab(String title, Component component) {
        insertTab(title, null, component, tabsList.size());
    }

    /**
     * Inserts a <code>component</code>, at <code>index</code>,
     * represented by a <code>title</code> and/or <code>icon</code>,
     * either of which may be <code>null</code>.
     * Uses java.util.Vector internally, see <code>insertElementAt</code>
     * for details of insertion conventions.
     *
     * @param title the title to be displayed in this tab
     * @param icon the icon to be displayed in this tab
     * @param component The component to be displayed when this tab is clicked.
     * @param index the position to insert this new tab
     *
     * @see #addTab
     * @see #removeTabAt
     */
    public void insertTab(String title, Image icon, Component component,
            int index) {
        checkIndex(index);
        if (component == null) {
            return;
        }
        Button b = new Button(title != null ? title : "", icon);
        ((DefaultListModel) tabsList.getModel()).addItemAtIndex(b, index);
        tabsTable.put(b, component);

        if (tabsList.size() == 1) {
            contentPane.addComponent("Center", component);
        }

    }
   
    /**
     * Updates the information about the tab details
     *
     * @param title the title to be displayed in this tab
     * @param icon the icon to be displayed in this tab
     * @param index the position to insert this new tab
     */
    public void setTabTitle(String title, Image icon, int index) {
        checkIndex(index);
        Button b = (Button)tabsList.getModel().getItemAt(index);
        b.setText(title);
        b.setIcon(icon);
        ((DefaultListModel) tabsList.getModel()).setItem(index, b);
    }
   
    /**
     * Removes the tab at <code>index</code>.
     * After the component associated with <code>index</code> is removed,
     * its visibility is reset to true to ensure it will be visible
     * if added to other containers.
     * @param index the index of the tab to be removed
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #addTab
     * @see #insertTab 
     */
    public void removeTabAt(int index) {
        checkIndex(index);

        Component removedComp = (Component) tabsTable.get(((Component) tabsList.getModel().getItemAt(index)));
        ((DefaultListModel) tabsList.getModel()).removeItem(index);
        tabsTable.remove(removedComp);
    }

    /**
     * Returns tthe tab at <code>index</code>.
     *
     * @param index the index of the tab to be removed
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #addTab
     * @see #insertTab 
     */
    public Component getTabComponentAt(int index) {
        checkIndex(index);

        return (Component) tabsTable.get(((Component) tabsList.getModel().getItemAt(index)));
    }
   
    private void checkIndex(int index) {
        if (index < 0 || index > tabsList.size()) {
            throw new IndexOutOfBoundsException("Index: " + index);
        }
    }

    /**
     * Returns the index of the tab for the specified component.
     * Returns -1 if there is no tab for this component.
     *
     * @param component the component for the tab
     * @return the first tab which matches this component, or -1
     *    if there is no tab for this component
     */
    public int indexOfComponent(Component component) {
        for (int i = 0; i < getTabCount(); i++) {
            Component c = (Component) tabsList.getModel().getItemAt(i);
            Component content = (Component) tabsTable.get(c);
               
            if(component.equals(content)){
                return i;
            }
        }
        return -1;
    }

    /**
     * Returns the number of tabs in this <code>tabbedpane</code>.
     *
     * @return an integer specifying the number of tabbed pages
     */
    public int getTabCount() {
        return tabsList.size();
    }

    /**
     * Returns the currently selected index for this tabbedpane.
     * Returns -1 if there is no currently selected tab.
     *
     * @return the index of the selected tab
     */
    public int getSelectedIndex() {
        return tabsList.getSelectedIndex();
    }

    /**
     * @inheritDoc
     */
    protected String getUIID() {
        return "TabbedPane";
    }

    /**
     * The prototype is optionally used in calculating the size of an individual
     * tab and is recommended for performance reasons. You should invoke it with a String
     * representing the width/height which will be used to calculate
     * the size required for each element in the list.\
     * <p>This operation is not essential and if it isn't invoked the size of the first
     * few tabs is used to determin the overall size of a tab.
     * <p>This allows the size calculations to work across look and feels and allows
     * developers to predetermin size for the tabs.
     * <p>e.g. For tabs which you would like to always be 5 characters wide
     * you can use a prototype "XXXXX" which would use the preferred size of the XXXXX
     * String to determin the size of the tabs..
     *
     * @param title a string to determine the size.
     */
    public void setTabTitlePrototype(String title) {
        tabsList.setRenderingPrototype(title);
    }
   
    /**
     * @inheritDoc
     */
    public String toString() {
        String className = getClass().getName();
        className = className.substring(className.lastIndexOf('.') + 1);
        return className + "[x=" + getX() + " y=" + getY() + " width=" +
                getWidth() + " height=" + getHeight() + ", tab placement = " +
                tabPlacement + ", tab count = " + getTabCount() +
                ", selected index = " + getSelectedIndex() + "]";
    }

    /**
     * @inheritDoc
     */
    public void paint(Graphics g) {
        super.paint(g);
        UIManager.getInstance().getLookAndFeel().drawTabbedPane(g, this);
    }

    /**
     * @inheritDoc
     */
    public void setStyle(Style style) {
        tabsList.setStyle(style);
        contentPane.setStyle(style);
    }

    /**
     * Returns the placement of the tabs for this tabbedpane.
     *
     * @see #setTabPlacement
     */
    public int getTabPlacement() {
        return tabPlacement;
    }

    /**
     * The TabbedPane surrounded border width
     *
     * @return The TabbedPane surrounded border width
     */
    public int getTabbedPaneBorderWidth() {
        return tPBorder;
    }

    /**
     * Setting the TabbedPane surrounded border width
     *
     * @param tabbedPaneBorderWidth TabbedPane surrounded border width
     */
    public void setTabbedPaneBorderWidth(int tabbedPaneBorderWidth) {
        this.tPBorder = tabbedPaneBorderWidth;
    }

    /**
     * @inheritDoc
     */
    public void setPadding(int top, int bottom, int left, int right) {
        if (contentPane != null) {
            contentPane.getStyle().setPadding(top, bottom, left, right);
        }
    }
   
    /**
     * @inheritDoc
     */
    public void setPadding(int orientation, int gap) {
        if (contentPane != null) {
            contentPane.getStyle().setPadding(orientation, gap);
        }
    }
   
    /**
     * Sets the selected index for this tabbedpane. The index must be a valid
     * tab index.
     * @param index the index to be selected
     * @throws IndexOutOfBoundsException if index is out of range
     * (index < 0 || index >= tab count)
     */
    public void setSelectedIndex(int index) {
        if (index < 0 || index >= tabsList.size()) {
            throw new IndexOutOfBoundsException("Index: "+index+", Tab count: "+tabsList.size());
        }
        tabsList.setSelectedIndex(index);
    }
   
    class TabsRenderer implements ListCellRenderer {

        public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {           
            // prototype value can cause this
            if(value == null || (!(value instanceof Button))) {
                value = new Button("" + value);
            }
            return UIManager.getInstance().getLookAndFeel().getTabbedPaneCell(
                    TabbedPane.this, ((Button) value).getText(),
                    ((Button) value).getIcon(), isSelected,
                    list.hasFocus(), list.getStyle(), TabbedPane.this.getStyle(),
                    list.getScrollX(), list.getScrollY(),
                    list.getPreferredSize(), contentPane.getBounds().getSize());
        }

        public Component getListFocusComponent(List list) {
            return null;
        }
    }
}
TOP

Related Classes of com.sun.dtv.lwuit.TabbedPane$TabsRenderer

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.