日期:2014-05-20  浏览次数:20766 次

共享一下模仿QQ好友列表,点击表头展开对应Tab的源码
共享模仿QQ好友列表,点击表头展开对应Tab的源码。
Tab的展开使用动画,有兴趣的还可以去看看Easing的各种动画效果。


package com.tur.demo;

import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstraints;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

/**
 * 模仿QQ好友列表的布局, 展开一个tab的同时,其他tab被隐藏.
 *
 * 主要使用API:
 *  1. addTab: 添加一个新的tab
 *  2. removeTab: 删除一个tab,这个方法有待改进
 *  3. setExpandedTabIndex: 指定要展开的tab,默认所有的tab都是收缩起来的。界面初始化的时候经常有必要调用这个方法设置一个tab是展开的.
 *
 * tab的标题栏如果想要好看一些,可以使用图片美化,也可以手动绘制好一点的样式。
 */
public class ScrollingTabPane extends JComponent {
    private TableLayout layout;
    private List<Tab> tabs;
    private MouseListener mouseListener;

    private int expandedTabIndex = 0; // 被展开的tab的index
    public static final int COLLAPSE_TAB_HEIGHT = 30; // 收陇的tab标签的高度

    public ScrollingTabPane() {
        tabs = new LinkedList<Tab>();
        mouseListener = new TabMouseListener();
        layout = new TableLayout(new double[]{TableLayout.FILL}, new double[]{});
        setLayout(layout);
    }

    /**
     * 添加一个新的tab
     * @param com - 要添加到tab里的组件
     */
    public void addTab(JComponent com, String title) {
        Tab tab = new Tab(com, title);
        tabs.add(tab);

        int rowCount = layout.getNumRow();
        layout.insertRow(rowCount, COLLAPSE_TAB_HEIGHT);
        add(tab, "0, " + rowCount);
    }

    /**
     * 删除第index个tab
     * @param index - 删除的tab的index
     */
    public void removeTab(int index) {
        if (index < 0 || index >= tabs.size()) { return; }

        Container tab = tabs.get(index);
        int row = layout.getConstraints(tab).row1;

        // 必须同时从layout和component中移除
        remove(tab);
        tabs.remove(tab);
        layout.deleteRow(row);

        if (row == expandedTabIndex) {
            // 如果删除的是展开的tab,则展开它下面的tab
            setExpandedTabIndex(expandedTabIndex);
        } else if (row < expandedTabIndex) {
            // 如果删除的tab在展开的tab上面,则展开的tab的index减一
            --expandedTabIndex;
        }

        invalidate();
        validate();
    }

    /**
     * 取得当前展开的tab的index
     * @return - 当前展开的tab的index
     */
    public int getExpandedTabIndex() {
        return expandedTabIndex;
    }

    /**
     * 设置展开的tab的index,然后展开此tab并把其他的tab的高度设置为TAB_HEIGHT.
     * @param expandedTabIndex - 需要被展开的tab的index
     */
    public void setExpandedTabIndex(int expandedTabIndex) {
        this.expandedTabIndex = expandedTabIndex;

        for (int i = 0; i < layout.getNumRow(); ++i) {
            layout.setRow(i, COLLAPSE_TAB_HEIGHT);