简体   繁体   English

如何向JTabbedPane标签添加关闭按钮?

[英]How to add close button to a JTabbedPane Tab?

I'm working in with a JTabbedPane, I need to add a close button in the tabs to close the current one. 我正在使用JTabbedPane,我需要在选项卡中添加一个关闭按钮来关闭当前的关闭按钮。

I have been searching and as I understand I must extend from JPanel and add the close button as they say here But, is there a way to add the close buttons extending JTabbedPane or is there a easier way to do it? 我一直在搜索,据我所知,我必须从JPanel扩展并添加他们在这里说的关闭按钮但是,有没有办法添加延伸JTabbedPane的关闭按钮或者有更简单的方法吗?

Thanks in advance, I really appreciate your time and your help. 在此先感谢,我非常感谢您的时间和帮助。

Essentially, you're going to need to supply a "renderer" for the tab. 基本上,您将需要为选项卡提供“渲染器”。 Take a look at JTabbedPane.setTabComponentAt(...) for more information. 查看JTabbedPane.setTabComponentAt(...)以获取更多信息。

The basic idea is to supply a component that will be laid out on the tab. 基本思想是提供将在选项卡上布局的组件。

I typically create a JPanel, onto which I add a JLabel (for the title) and, depending on what I want to display, some kind of control that acts as the close action. 我通常创建一个JPanel,我在其上添加一个JLabel(用于标题),并根据我想要显示的内容,使用某种控件作为关闭操作。

tabPane.addTab(title, tabBody);
int index = tabPane.indexOfTab(title);
JPanel pnlTab = new JPanel(new GridBagLayout());
pnlTab.setOpaque(false);
JLabel lblTitle = new JLabel(title);
JButton btnClose = new JButton("x");

GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;

pnlTab.add(lblTitle, gbc);

gbc.gridx++;
gbc.weightx = 0;
pnlTab.add(btnClose, gbc);

tabPane.setTabComponentAt(index, pnlTab);

btnClose.addActionListener(myCloseActionHandler);

Now somewhere else, I establish the action handler... 现在在其他地方,我建立了动作处理程序......

public class MyCloseActionHandler implements ActionListener {

    public void actionPerformed(ActionEvent evt) {

        Component selected = tabPane.getSelectedComponent();
        if (selected != null) {

            tabPane.remove(selected);
            // It would probably be worthwhile getting the source
            // casting it back to a JButton and removing
            // the action handler reference ;)

        }

    }

}

Now, you just as easily use any component you like and attach a mouse listener to it and monitor the mouse clicks... 现在,您可以轻松使用您喜欢的任何组件并将鼠标监听器连接到它并监控鼠标点击...

Updated 更新

The above example will only remove the currently active tab, there are a couple of ways to fix this. 以上示例仅删除当前活动的选项卡,有几种方法可以解决此问题。

The best is to probably provide some means for the action to find the tab it's associated with... 最好的方法是为行动找到与之相关的标签提供一些手段......

public class MyCloseActionHandler implements ActionListener {

    private String tabName;

    public MyCloseActionHandler(String tabName) {
        this.tabName = tabName;
    }

    public String getTabName() {
        return tabName;
    }

    public void actionPerformed(ActionEvent evt) {

        int index = tabPane.indexOfTab(getTabName());
        if (index >= 0) {

            tabPane.removeTabAt(index);
            // It would probably be worthwhile getting the source
            // casting it back to a JButton and removing
            // the action handler reference ;)

        }

    }

}   

This uses the name of tab (as used with JTabbedPane#addTab ) to find and then remove the tab and its associated component... 这使用tab的名称(与JTabbedPane#addTab )来查找然后删除选项卡及其关联的组件...

I found a tab example (from the java site) that appears to do that, at least in theirs. 我找到了一个标签示例(来自java网站)似乎这样做,至少在他们的。 (Though I thought, when I tried it in the past, that it also closed the currently selected tab, though it works properly when you run their example, though I think when I updated it to work on a tabbed java notepad, it was closing the currently selected tab, though maybe I did it wrong. (虽然我以为,当我过去尝试它时,它也关闭了当前选中的选项卡,虽然它在运行他们的示例时工作正常,但我认为当我更新它以在标签式java记事本上工作时,它正在关闭当前选择的标签,虽然我可能做错了。

http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java

Yes, my thing is working now! 是的,我现在正在努力! This WILL work for the actual tab, rather than the currently selected tab! 这将适用于实际的选项卡,而不是当前选定的选项卡!

Hopefully you have got the answer to your question. 希望你能得到你的问题的答案。 I want to give a link that was very useful for me. 我想提供一个对我非常有用的链接。

JTabbedPane with a close button 带有关闭按钮的JTabbedPane

Here is some code as well. 这里有一些代码。

public static void createAndShowGUI()
{
    JFrame frame = new JFrame("Tabs");
    frame.setMinimumSize(new Dimension(500, 200));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTabbedPane tabbedPane = new JTabbedPane();

    JPanel panel = new JPanel();
    panel.setOpaque(false);
    tabbedPane.add(panel);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel), getTitlePanel(tabbedPane, panel, "Tab1"));

    JPanel panel1 = new JPanel();
    panel1.setOpaque(false);
    tabbedPane.add(panel1);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel1), getTitlePanel(tabbedPane, panel1, "Tab2"));

    JPanel panel2 = new JPanel();
    panel2.setOpaque(false);
    tabbedPane.add(panel2);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel2), getTitlePanel(tabbedPane, panel2, "Tab3"));

    JPanel panel3 = new JPanel();
    panel3.setOpaque(false);
    tabbedPane.add(panel3);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel3), getTitlePanel(tabbedPane, panel3, "Tab4"));

    frame.add(tabbedPane);

    // Display the window.
    frame.pack();
    frame.setVisible(true);
}

I made some changes in the code of oracle. 我在oracle代码中做了一些更改。

http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java

Giving the possibility to add an icon to the tab , plus the close tab button. 可以在选项卡中添加图标,以及关闭选项卡按钮。 Hope that helps. 希望有所帮助。

public static void addTag(JTabbedPane tab, String title, Icon icon, int index){
     MouseListener close = new MouseAdapter() {

        @Override
        public void mouseClicked(MouseEvent e) {
            //your code to remove component
            //I use this way , because I use other methods of control than normal: tab.remove(int index);
        }

    };
    final ButtonClose buttonClose = new ButtonClose (title, icon, close );

    tab.setTabComponentAt(index, buttonClose);
    tab.validate();
    tab.setSelectedIndex(index);

} }

public class ButtonClose extends JPanel { 公共类ButtonClose扩展JPanel {

public ButtonClose(final String title, Icon icon, MouseListener e) {
    JLabel ic = new JLabel(icon);
    ic.setSize(icone.getIconWidth(), icone.getIconHeight());

    JLabel text= new JLabel(title);
    text.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));

    ButtonTab button = new ButtonTab();
    button.addMouseListener(e);
    button.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));

    JPanel p = new JPanel();
    p.setSize(getWidth() - icone.getIconWidth(), 15);
    p.add(text);
    p.add(button);

    add(ic);
    add(p);
}

private class ButtonTab extends JButton {

    public ButtonTab() {
        int size = 13;
        setPreferredSize(new Dimension(size, size));
        setToolTipText("Close");

        setUI(new BasicButtonUI());

        setFocusable(false);
        setBorderPainted(false);

        addMouseListener(listener);
        setRolloverEnabled(true);
    }

    @Override
    public void updateUI() {
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();

        if (getModel().isPressed()) {
            g2.translate(1, 1);
        }
        g2.setStroke(new BasicStroke(2));
        g2.setColor(new Color(126, 118, 91));

        if (getModel().isRollover()) {
            g2.setColor(Color.WHITE);
        }

        int delta = 3;
        g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
        g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
        g2.dispose();
    }
}

private final MouseListener listener = new MouseAdapter() {
    @Override
    public void mouseEntered(MouseEvent e) {
        Component component = e.getComponent();
        if (component instanceof AbstractButton) {
            AbstractButton button = (AbstractButton) component;
            button.setContentAreaFilled(true);
            button.setBackground(new Color(215, 65, 35));
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        Component component = e.getComponent();
        if (component instanceof AbstractButton) {
            AbstractButton button = (AbstractButton) component;
            button.setContentAreaFilled(false); //transparent
        }
    }
};

} }

Check out Peter-Swing here . 在这里看看Peter-Swing。 It has a JClosableTabbedPane class in it, as well as many others. 它有一个JClosableTabbedPane类,以及许多其他类。

When you download the jar file you can run it and have examples of all the classes. 下载jar文件时,您可以运行它并获得所有类的示例。

You can have a JLabel named "x" and use the mouseListener 您可以拥有名为“x”的JLabel并使用mouseListener

 private final JLabel l = new JLabel(); // this is the label for tabbedPane
 private final JLabel b = new JLabel("x");//Close Button
 if (closeable)
        {
            b.setToolTipText("Click to close");

            b.setOpaque(false);
            b.setBackground(Color.gray);

            b.addMouseListener(new MouseAdapter()
            {
                @Override
                public void mouseExited(MouseEvent e)
                {
                    b.setBorder(bordere);
                    b.setOpaque(false);
                }

                @Override
                public void mouseEntered(MouseEvent e)
                {
                    b.setBorder(borderl);
                }

                @Override
                public void mouseReleased(MouseEvent e)
                {
                    b.setOpaque(false);
                    b.repaint();

                    if (b.contains(e.getPoint()))
                    {
                        b.setBorder(borderl);

                        if (confirmTabClosing())
                        {
                            tab.remove(tabIndex());
                            if(tab.getTabCount() == 0)
                                spacialTabComponent.maximizeOrRestore.doClick();
                        }
                    }
                    else
                        b.setBorder(bordere);

                }

                @Override
                public void mousePressed(MouseEvent e)
                {
                    b.setOpaque(true);
                    b.repaint();
                }
            });

            b.setBorder(bordere);
            add(b, getLeftAlignedBothFilledGBC(1, 0, new Insets(0, 0, 0, 0), 0, 0));
        }



    }
jbCloseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int index = jtbMainTabbedPane.indexOfTabComponent(jbCloseButton);
                jtbMainTabbedPane.remove(index);
            }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM