积微成著 不积跬步,无以至千里

首页   >   web开发   >   JTabbedPane第二次优化,添加关闭按钮

JTabbedPane第二次优化,添加关闭按钮

上一篇文章中,我们优化了JTabbedPane的UI,对比原生组件来说,外观是好看了很多,但是这个组件在设计之初,貌似就没有考虑到关闭的情况,所以也没有设计关闭按钮,这个功能还是很有需要的,今天就来教大家如何在JTabbedPane的tab上添加可以关闭的按钮。

在开始这个功能的实现之前,我第一反应是重写它的paintTab方法来实现,可是太麻烦了,所以就放弃了,后来查阅资料发现了一个API能够实现,猜想可能是官方后来得到市场建议了,出的一个补救措施,毕竟重写一套完善的UI还是相当耗费人力和时间的。

API的名字叫做:setTabComponentAt(),字面意思很好理解,设置一个组件到某个地方(这个地方就是“tab页签”),它有两个参数,index和Component,分别是下标和swing组件

public void setTabComponentAt(int index, Component component) {
	......
}

so,大家是不是知道接下来要干什么了?

我们根本不用重绘paintTab,直接自己写一个组件,给他设置进去,就这么简单,简直不可思议。

tab页签本来是只有一个title,想要加一个关闭按钮,那么我们可以理解为,一个jlabel和一个jbutton,这样思路就来了,直接自己写一个jpanel,将label和button放进去,就OK了。

JTabbedPane优化第二次优化,添加关闭按钮

哎呀,我去,有效果了,标题也有了,按钮也有了,但是,,,这也太丑了,好不容易优化的UI,瞬间档次又反弹回去了。。。

没关系,兵来将挡,不就是jpanel的背景色和jbutton的默认UI太丑,那我们给它逐一优化了,背景色我们可以直接给它设置成透明色,按钮的话,大家还记得我们之前在 Swing界面优化JComboBox教程 中,也优化过那个下拉按钮,大体上差不多,都是将背景色和边框干掉了,所以我们直接用当时写的那个UI。

这样看下来,是不是发现,也没多少代码要写,我就直接上代码了:

package com.wolffy.frame;

import com.wolffy.ui.MyButtonUI;
import com.wolffy.ui.MyTabbedPaneUI;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;


/**
 * Created by SongFei on 2017/11/10.
 */
public class TabPaneFrame extends JFrame {

    private static final long serialVersionUID = 2034407950836221468L;

    private JPanel jPanel;

    public TabPaneFrame() {
        initGUI();
    }

    private void initGUI() {
        setSize(700, 500);
        //setUndecorated(true);// 把边框去了,优化的效果能看的更明显
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        jPanel = new JPanel();
        //jPanel.setBackground(Color.ORANGE);
        jPanel.setLayout(new BorderLayout());
        getContentPane().add(jPanel, BorderLayout.CENTER);

        JTabbedPane tab = new JTabbedPane(JTabbedPane.LEFT);
        tab.setUI(new MyTabbedPaneUI());

        JPanel jPanel1 = new JPanel();
        jPanel1.setLayout(new FlowLayout());
        jPanel1.add(new JButton("AAA111"));
        JPanel jPanel2 = new JPanel();
        jPanel2.add(new JButton("AAA222"));
        JPanel jPanel3 = new JPanel();
        jPanel3.add(new JButton("AAA333"));
        JPanel jPanel4 = new JPanel();
        jPanel4.add(new JButton("AAA444"));
        JPanel jPanel5 = new JPanel();
        jPanel5.add(new JButton("AAA555"));

        tab.add(jPanel1);
        tab.add(jPanel2);
        tab.add(jPanel3);
        tab.add(jPanel4);
        tab.add(jPanel5);

        addCloseBtn(tab, jPanel1, "我爱一条柴");
        addCloseBtn(tab, jPanel2, "含笑半步癫");
        addCloseBtn(tab, jPanel3, "七情六欲丹");
        addCloseBtn(tab, jPanel4, "奇淫合欢散");
        addCloseBtn(tab, jPanel5, "弹指红颜老");

        jPanel.add(tab, BorderLayout.CENTER);
    }

    /**
     * 添加关闭按钮
     *
     * @param tab    JTabbedPane组件
     * @param jPanel 重写的Jpanel
     * @param text   标题,相当于之前的title
     */
    private void addCloseBtn(JTabbedPane tab, JPanel jPanel, String text) {
        JPanel pane = new JPanel();
        pane.setOpaque(false);// 设置jpanel面板背景透明

        JLabel title = new JLabel(text);
        pane.add(title);

        JButton close = new JButton("X");
        close.setForeground(Color.LIGHT_GRAY);
        close.setUI(new MyButtonUI());// 这里会设置jbutton的背景透明
        pane.add(close);

        close.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                close.setForeground(Color.RED);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                close.setForeground(Color.LIGHT_GRAY);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                tab.remove(tab.indexOfComponent(jPanel));
                // 所有tab都关闭了,整个tabpane也要关闭
                if (tab.getTabCount() <= 0) {
                    System.exit(0);
                }
            }
        });

        // jdk1.6之后的新特性,也是实现这个功能的核心所在,在相应下表的tab出放置任何组件
        tab.setTabComponentAt(tab.indexOfComponent(jPanel), pane);
    }

    public static void main(String[] args) {
        TabPaneFrame paneFrame = new TabPaneFrame();
        paneFrame.setVisible(true);
        //loginFrame.pack();
        paneFrame.setLocationRelativeTo(null);
    }

}

MyTabbedPaneUI 和 MyButtonUI,在之前的文章中都有,这里就不再重复了,大家可以去之前的文章中拷贝代码,不用改动,直接用!

动手之前觉着很难,有了思路之后,还是很简单的,来一张最终的效果图:

JTabbedPane优化第二次优化,添加关闭按钮

点击X,关闭相应的tab页签,在贴出来的代码中也有,大家可以复制下来,自己运行看看效果如何!

QQ群:积微成著官方群(686430774),验证消息:积微成著

站长Q:1347384268(加好友请注明来意)

分享到:

欢迎分享本文,转载请注明出处!

作者:不忘初心

发布时间:2017-11-10

永久地址:http://www.jiweichengzhu.com/article/d07d1697e2cd447694a2e37e2328cce4