考虑了很久要不要写出来现眼。。因为对于这里的这些牛人来说,肯定这算不上什么难题。不过昨天晚上这东西真的困扰我很久所以当作是自己的小结,也希望能对其他一些初学者起到帮助作用。 实现方法一:baidu过后,看见大多数人都是这么实现的。利用JTabbedPane的这个方法:addTab(String title, Icon icon, Component component)这个方法可以为Tab添加一个icon图标。于是大家就开始把图标绘制成X,然后响应鼠标点击是否在icon范围内,如果在,就remove掉这个tab。昨天晚上看的几乎所有实现代码,都是这么做的。只是小有区别,另外由于要绘制icon,所以代码乱七八糟的。。(都是画嘛~)看的我头疼另外,查过OPENSWING,也是这么实现的。缺点是画起来太麻烦,代码多,而且icon总是出现在title的前面。如下(openswing实现的效果图) 后来我就想这玩意有那么费劲么。。当时疏忽了去查API又在大量搜索几近崩溃的情况下,找到了sun的一个例子。原来JDK6早就有了类似的新特征,我把注意力直接放在能否加关闭按钮上,禁锢了思路。JDK6新特征允许向Tab里增加组件(但貌似只能加一个组件,加后title就显示不了了。。)。所用方法:setTabComponentAt(int index, Component component)title显示不了怎么办?其实可以往Tab里面加panel嘛~panel里面放个JLabel和JButton。这就是总的实现思路。sun的实现效果如下:sun的那个例子代码也够长,还要重绘按钮状态之类。其实有个偷懒的解决办法,就是截按钮图,平常状态、presse状态、rollover状态各一张,这样省的自己画了,写个自定义按钮好了。这样省去了很多代码行,省事了。。我实现的效果图如下(绿窗口是保护眼睛用的。。别慌。。): 具体代码如下,自定义按钮用内部类实现。虽然不是什么高深的东西,写的也不好,但多少对大家有点用处,因为代码比较简单、比较短。或者拿走直接也能用。由于我毕设自身需要,remove最后一个tab后会生成一个以blank作为title的tab,且没有关闭按钮。用的时候,实例一个JTabbedPane后,把下面这个类的实例当component传给setTabComponentAt这个方法就行了。下面这个类的构造方法的参数是title和JTabbedPane的实例本身。
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;/**
 *
 * @author wangchong
 */
public class TabPanel extends JPanel{
    private JLabel title;
    private CloseButton closebutton;
    private final JTabbedPane pane;    public TabPanel(String s,JTabbedPane pane){
        super(new FlowLayout(FlowLayout.LEFT, 0, 0));
        title=new JLabel(s);
        this.pane=pane;
        closebutton=new CloseButton();
        add(title);
        add(closebutton);
        title.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
        setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
        setOpaque(false);
    }    private class CloseButton extends JButton {
        private ImageIcon icon;
        public CloseButton(){
            icon=new ImageIcon(getClass().getResource("/Image/Button/close.png"));
            setSize(icon.getImage().getWidth(null),icon.getImage().getHeight(null));
            setIcon(icon);
            setBorder(null);
            setBorderPainted(false);
            setFocusPainted(false);
            setPressedIcon(new ImageIcon(getClass().getResource("/Image/Button/close_pressed.png")));
            setRolloverIcon(new ImageIcon(getClass().getResource("/Image/Button/close_rollover.png")));
            addMouseListener(new MouseAdapter(){
                public void mouseClicked(MouseEvent e){
                    pane.remove(pane.indexOfTabComponent(TabPanel.this));
                    if (pane.getTabCount()==0) {
                        pane.addTab("blank", null);
                    }
                }
            });
        }
    }}
其实要再加个icon,就比较全面了~完毕
写的不好,大家不要笑话~有不足之处请指教~我会虚心接受~

解决方案 »

  1.   

    我怎么用着有问题,请帮忙看下,非常感谢!
    //import java.awt.Color;
    import java.awt.GraphicsConfiguration;
    import java.awt.HeadlessException;import java.awt.event.*;
    import java.awt.BorderLayout;import javax.swing.*;
    import javax.swing.tree.*;import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Hashtable;
    import java.util.Map;import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.SAXException;public class ProTester extends JFrame implements ActionListener, MouseListener
    {
    JMenuItem exit;
    JTextArea xmlText;
    JTextArea runLogText;
    JTextArea sysLogText;
    JTabbedPane xmlTab;
    public DefaultTreeModel treeModel;
    public JTree tree;

    Hashtable<Integer, String> ht;

    final static int xpos = 200;
    final static int ypos = 200;
    final static int width = 800;
    final static int height = 600; public ProTester() throws HeadlessException
    {
    // TODO Auto-generated constructor stub
    super("Protocol Tester");
    // this.setSize(ProTester.width, ProTester.height);
    this.setBounds(ProTester.xpos, ProTester.ypos, ProTester.width, ProTester.height);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    initGUI(); // setVisible(true);
    } static final long serialVersionUID = 65; /**
     * @param args
     */
    public static void main(String[] args)
    {
    // TODO Auto-generated method stub
    ProTester proTester = new ProTester(); try
    {
    UIManager.setLookAndFeel(
    // UIManager.getCrossPlatformLookAndFeelClassName()
    UIManager.getSystemLookAndFeelClassName());
    SwingUtilities.updateComponentTreeUI(proTester);
    } catch (Exception e)
    {
    System.out.println("Can't set look and feel: " + e.getMessage());
    e.printStackTrace();
    }
    // proTester.DomParse();
    // File path = new File("E:\\My project\\Eclipesworkspace\\ProTester\\xml\\");
    // proTester.InitTree(path, (MutableTreeNode) proTester.treeModel.getRoot());
    // proTester.tree.expandPath(new TreePath(proTester.treeModel.getRoot()));
    proTester.setVisible(true);
    } public void actionPerformed(ActionEvent evt)
    {
    Object source = evt.getSource();
    if (source == exit)
    {
    System.out.println("How to exit this program, en?");
    System.exit(EXIT_ON_CLOSE);
    }
    } private void initGUI()
    {
    // create xml edit area
    JTabbedPane tabXMLText = new JTabbedPane();
    this.xmlTab = tabXMLText;
    BorderLayout tabLay = new BorderLayout();
    this.xmlTab.setLayout(tabLay);

    // create log record pane
    JTabbedPane tabLog = new JTabbedPane(JTabbedPane.BOTTOM);

    // run log
    JTextArea runLogText = new JTextArea("run log record here.");
    runLogText.setLineWrap(false);
    runLogText.setEditable(false);
    this.runLogText = runLogText; JScrollPane runScrollPane = new JScrollPane(runLogText);
    tabLog.addTab("run log", runScrollPane);

    // system log
    JTextArea sysLogText = new JTextArea("system log record here.");
    sysLogText.setLineWrap(false);
    sysLogText.setEditable(false);
    this.sysLogText = sysLogText; JScrollPane sysScrollPane = new JScrollPane(sysLogText);
    tabLog.addTab("system log", sysScrollPane); /* Create the tree. */
    JTree tree = new JTree();
    tree.putClientProperty("JTree.lineStyle", "Angled");
    this.tree = tree;
    tree.addMouseListener(this); JScrollPane treePanel = new JScrollPane(tree);
    // BorderLayout bt = new BorderLayout();
    // treePanel.setLayout(bt);
    // treePanel.add(tree); JSplitPane splitPane = new JSplitPane();
    splitPane.setOneTouchExpandable (true);
    splitPane.setDividerLocation(ProTester.width*1/6);
    splitPane.setLeftComponent(treePanel);
    splitPane.setRightComponent(tabXMLText);

    JSplitPane splitPane2 = new JSplitPane();
    splitPane2.setOneTouchExpandable (true);
    splitPane2.setDividerLocation(ProTester.height*3/5);
    splitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT);
    splitPane2.setTopComponent(splitPane);
    splitPane2.setBottomComponent(tabLog);

    BorderLayout big = new BorderLayout();
    this.setLayout(big);
    this.add(splitPane2);
    } @Override
    public void mouseClicked(MouseEvent e)
    {
    // TODO Auto-generated method stub
    Object source = e.getSource();
    if (source == this.tree)
    {
    DefaultMutableTreeNode node = 
    (DefaultMutableTreeNode)this.tree.getLastSelectedPathComponent();
    if (node == null)
        //Nothing is selected.
        return;
    this.runLogText.selectAll();
    this.runLogText.replaceSelection("");
    this.runLogText.append(node.toString() + "\r\n");
    TreeNode[] treeNode = node.getPath();
    this.runLogText.append("this node.getPath() return TreeNode[" + treeNode.length + "].\r\n");
    for (int i=0; i<treeNode.length; i++)
    {
    this.runLogText.append("treeNode[" + i + "] is : " + treeNode[i].toString() + "\r\n");
    }
    // try {
    // InputStream is = new FileInputStream("E:\\My project\\Eclipesworkspace\\ProTester\\xml\\" + node.toString());
    // int buffsize = 512;
    // byte[] buff = new byte[buffsize];
    // while (is.read(buff) != -1) 
    // {
    // this.runLogText.append(new String(buff));
    // }
    // is.close();
    // } catch (FileNotFoundException ex)
    // {
    // ex.printStackTrace();
    // } catch (IOException ex)
    // {
    // ex.printStackTrace();
    // }
    if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() >= 2)) 
    {
    this.runLogText.append("you chick double the left mouse key." + "\r\n");
    if (node.isLeaf()) 
    {
    if (this.xmlTab.indexOfTab(node.toString()) == -1)
    {
    JTextArea xml = new JTextArea("<html>" + node.toString() + "<br><center>" + node.toString() + "</center><br></html>");
    JScrollPane text = new JScrollPane(xml);
    xml.setWrapStyleWord(false);
    xml.setEditable(true);
    TabPanel t = new TabPanel(node.toString(), this.xmlTab);
    // t.add(text);
    // this.xmlTab.addTab(node.toString(), text);
    this.xmlTab.add(t);
    }
    // this.xmlTab.setSelectedIndex(this.xmlTab.indexOfTab(node.toString()));
    }
    }
    }
    } @Override
    public void mouseEntered(MouseEvent e)
    {
    // TODO Auto-generated method stub } @Override
    public void mouseExited(MouseEvent e)
    {
    // TODO Auto-generated method stub } @Override
    public void mousePressed(MouseEvent e)
    {
    // TODO Auto-generated method stub } @Override
    public void mouseReleased(MouseEvent e)
    {
    // TODO Auto-generated method stub
    if (e.isPopupTrigger())
    {
    JPopupMenu popMenu = new JPopupMenu("right");
    JMenuItem menuOpen = new JMenuItem("run the test case");
    popMenu.add(menuOpen);
    popMenu.show(e.getComponent(), e.getX(), e.getY());// 弹出右键菜单
    }
    }
    }
      

  2.   

    测试可用。thanks, 好像比例子哪个短了很多