我添加了一个名为MyEditorPanel的自定义面板,该面板将JPanel扩展到JTabbedPanel,并希望每个选项卡上都有一个关闭按钮,以便使用以下代码并使用ButtonTabbedComponent.java中的ButtonTabbedComponent.java

public void addTab(String name, String desc) {
    MyEditorPane textEditorPane = new MyEditorPane(this, name, desc);
    this.addTab(name, normal, textEditorPane, desc);
    int i = this.getComponentCount() - 1;
    textEditorPane.setTabCount(i);
    this.setTabComponentAt(i, new ButtonTabComponent(this, normal, normalFont));
}


但是我想在关闭之前将文本保存在MyEditorPane中,如何在单击关闭按钮时获取要关闭的MyEditorPane

当我在JTabbedPane类中获得组件的名称时,它没有MyEditorPane类对象

@Override
public void remove(int index) {

Component component = this.getTabComponentAt(index);
if (component instanceof ButtonTabComponent) {
    ButtonTabComponent tab = (ButtonTabComponent) component;
    System.out.println("remove method called if : " + tab.getComponentCount());
    component = tab.getComponent(0);
    System.out.println("remove method called if : " + component.getClass().getName());

    component = tab.getComponent(1);
    System.out.println("remove method called if : " + component.getClass().getName());
    JPanel pane = (JPanel) component;
    Component[] components = pane.getComponents();
    for (int i = 0, l = components.length; i < l; i++) {
            System.out.println("remove method called for : " + components[i].getClass().getName());
    }
    super.remove(index);
}
}


方法删除的输出

remove method called if : 2
remove method called if : javax.swing.JLabel
remove method called if : javax.swing.JPanel
remove method called for : pkginterface.ButtonTabComponent$1
remove method called for : pkginterface.ButtonTabComponent$TabButton

最佳答案

因此,根据How to Use Tabbed Panes中的示例,您可以使用类似...

public void actionPerformed(ActionEvent e) {
    int i = pane.indexOfTabComponent(ButtonTabComponent.this);
    if (i != -1) {
        Component comp = pane.getComponentAt(i);
        if (comp instanceof JLabel) {
            JLabel label = (JLabel) comp;
            System.out.println("Label text = " + label.getText());
            switch (JOptionPane.showConfirmDialog(this, "Are you sure you want to close the \"" + pane.getTitleAt(i) + "\" tab?", "Close", JOptionPane.OK_CANCEL_OPTION)) {
                case JOptionPane.OK_OPTION:
                    pane.remove(i);
                    break;
            }
        }
    }
}


这使您可以确定已关闭的选项卡,找到充当选项卡视图的组件,询问用户是否要关闭此特定选项卡,并根据他们的反馈采取适当的措施

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.plaf.basic.BasicButtonUI;

public class TabComponentsDemo extends JFrame {

    private final int tabNumber = 5;
    private final JTabbedPane pane = new JTabbedPane();
    private JMenuItem tabComponentsItem;
    private JMenuItem scrollLayoutItem;

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    //Turn off metal's use of bold fonts
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                new TabComponentsDemo("TabComponentsDemo").runTest();
            }
        });
    }

    public TabComponentsDemo(String title) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initMenu();
        add(pane);
    }

    public void runTest() {
        pane.removeAll();
        for (int i = 0; i < tabNumber; i++) {
            String title = "Tab " + i;
            pane.add(title, new JLabel(title));
            initTabComponent(i);
        }
        tabComponentsItem.setSelected(true);
        pane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
        scrollLayoutItem.setSelected(false);
        setSize(new Dimension(400, 200));
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void initTabComponent(int i) {
        pane.setTabComponentAt(i,
                new ButtonTabComponent(pane));
    }

    //Setting menu
    private void initMenu() {
        JMenuBar menuBar = new JMenuBar();
        //create Options menu
        tabComponentsItem = new JCheckBoxMenuItem("Use TabComponents", true);
        tabComponentsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_MASK));
        tabComponentsItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < pane.getTabCount(); i++) {
                    if (tabComponentsItem.isSelected()) {
                        initTabComponent(i);
                    } else {
                        pane.setTabComponentAt(i, null);
                    }
                }
            }
        });
        scrollLayoutItem = new JCheckBoxMenuItem("Set ScrollLayout");
        scrollLayoutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.ALT_MASK));
        scrollLayoutItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (pane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT) {
                    pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
                } else {
                    pane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
                }
            }
        });
        JMenuItem resetItem = new JMenuItem("Reset JTabbedPane");
        resetItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_MASK));
        resetItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                runTest();
            }
        });

        JMenu optionsMenu = new JMenu("Options");
        optionsMenu.add(tabComponentsItem);
        optionsMenu.add(scrollLayoutItem);
        optionsMenu.add(resetItem);
        menuBar.add(optionsMenu);
        setJMenuBar(menuBar);
    }

    public static class ButtonTabComponent extends JPanel {

        private final JTabbedPane pane;

        public ButtonTabComponent(final JTabbedPane pane) {
            //unset default FlowLayout' gaps
            super(new FlowLayout(FlowLayout.LEFT, 0, 0));
            if (pane == null) {
                throw new NullPointerException("TabbedPane is null");
            }
            this.pane = pane;
            setOpaque(false);

            //make JLabel read titles from JTabbedPane
            JLabel label = new JLabel() {
                public String getText() {
                    int i = pane.indexOfTabComponent(ButtonTabComponent.this);
                    if (i != -1) {
                        return pane.getTitleAt(i);
                    }
                    return null;
                }
            };

            add(label);
            //add more space between the label and the button
            label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
            //tab button
            JButton button = new TabButton();
            add(button);
            //add more space to the top of the component
            setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
        }

        private class TabButton extends JButton implements ActionListener {

            public TabButton() {
                int size = 17;
                setPreferredSize(new Dimension(size, size));
                setToolTipText("close this tab");
                //Make the button looks the same for all Laf's
                setUI(new BasicButtonUI());
                //Make it transparent
                setContentAreaFilled(false);
                //No need to be focusable
                setFocusable(false);
                setBorder(BorderFactory.createEtchedBorder());
                setBorderPainted(false);
                //Making nice rollover effect
                //we use the same listener for all buttons
                addMouseListener(buttonMouseListener);
                setRolloverEnabled(true);
                //Close the proper tab by clicking the button
                addActionListener(this);
            }

            public void actionPerformed(ActionEvent e) {
                int i = pane.indexOfTabComponent(ButtonTabComponent.this);
                if (i != -1) {
                    Component comp = pane.getComponentAt(i);
                    if (comp instanceof JLabel) {
                        JLabel label = (JLabel) comp;
                        System.out.println("Label text = " + label.getText());
                        switch (JOptionPane.showConfirmDialog(this, "Are you sure you want to close the \"" + pane.getTitleAt(i) + "\" tab?", "Close", JOptionPane.OK_CANCEL_OPTION)) {
                            case JOptionPane.OK_OPTION:
                                pane.remove(i);
                                break;
                        }
                    }
                }
            }

            //we don't want to update UI for this button
            public void updateUI() {
            }

            //paint the cross
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g.create();
                //shift the image for pressed buttons
                if (getModel().isPressed()) {
                    g2.translate(1, 1);
                }
                g2.setStroke(new BasicStroke(2));
                g2.setColor(Color.BLACK);
                if (getModel().isRollover()) {
                    g2.setColor(Color.MAGENTA);
                }
                int delta = 6;
                g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
                g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
                g2.dispose();
            }
        }

        private final static MouseListener buttonMouseListener = new MouseAdapter() {
            public void mouseEntered(MouseEvent e) {
                Component component = e.getComponent();
                if (component instanceof AbstractButton) {
                    AbstractButton button = (AbstractButton) component;
                    button.setBorderPainted(true);
                }
            }

            public void mouseExited(MouseEvent e) {
                Component component = e.getComponent();
                if (component instanceof AbstractButton) {
                    AbstractButton button = (AbstractButton) component;
                    button.setBorderPainted(false);
                }
            }
        };
    }
}

10-06 09:04