Java Swing(回转)按钮被";制表符行“;在JTabbedPane中,没有选项卡

Java Swing(回转)按钮被";制表符行“;在JTabbedPane中,没有选项卡,java,swing,tabs,jtabbedpane,miglayout,Java,Swing,Tabs,Jtabbedpane,Miglayout,我想要的是: 但是按钮必须是可点击的。现在,对于我的SSCCE,无法单击此按钮。但是如果我将按钮添加到此区域之外,例如,将此按钮边界的y设置为0,则它不再位于JTabbedPane的“选项卡行”后面,因此可以单击 因此: 为什么??这不是我们想要的行为。“制表符行”不应阻止任何元素,如果它们位于制表符的相同高度,但前面没有任何实际制表符。我的同事告诉我原因 它与布局无关,只是添加组件的顺序Java Swing的Z轴似乎以非直观的方式运行:从顶层到底层,这意味着如果先添加组件a,然后添加组件B,

我想要的是:

但是按钮必须是可点击的。现在,对于我的SSCCE,无法单击此按钮。但是如果我将按钮添加到此区域之外,例如,将此按钮边界的
y
设置为
0
,则它不再位于
JTabbedPane
的“选项卡行”后面,因此可以单击

因此:


为什么??这不是我们想要的行为。“制表符行”不应阻止任何元素,如果它们位于制表符的相同高度,但前面没有任何实际制表符。

我的同事告诉我原因

它与布局无关,只是添加组件的顺序Java Swing的Z轴似乎以非直观的方式运行:从顶层到底层,这意味着如果先添加组件a,然后添加组件B,如果它们位于同一位置,a将阻止B我重新阅读了Oracle文档,确信没有在任何地方提到它


为了让按钮工作,我必须先添加按钮,然后添加“<代码> jTabDePANE< /COD>”,因此“标签行”的空白将在按钮后面。真奇怪。Swing真是糟透了……

我重新阅读了Oracle文档,确信没有在任何地方提到它-行为在
Container.setComponentZOrder(…)
方法中定义。根据此方法API中的详细信息[此处](,据说:
z顺序决定了组件的绘制顺序;z顺序最高的组件首先绘制,z顺序最低的组件最后绘制。如果组件重叠,z顺序较低的组件将绘制在z顺序较高的组件上。
但我们不知道首先添加的是哪个组件ed组件的z阶较低。我认为随着添加组件,ZOrder会增加。您不知道将添加多少组件,因此无法首先分配最高的ZOrder。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

import net.miginfocom.swing.MigLayout;

public class MigLayoutWithJTabbedPaneButton extends JFrame {
    public MigLayoutWithJTabbedPaneButton() {
        begin();
    }

    private void begin() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.setLayout(null);

        JTabbedPane tabsPane = new JTabbedPane();
        tabsPane.setBounds(20, 20, 300, 400);
        panel.add(tabsPane);


        JLayeredPane tab = new JLayeredPane();
        tab.setLayout(new MigLayout("insets 2 2 2 2, fillx, debug", "[]5[]5[]", "[]5[]"));

        JButton button1 = new JButton("In the grid");
        JButton button2 = new JButton("Out of the grid");
        ActionListener ls = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(MigLayoutWithJTabbedPaneButton.this, "This can be clicked. ");

            }
        };
        button1.addActionListener(ls);
        button2.addActionListener(ls);

        tab.add(button1, "cell 0 0, grow");

        tabsPane.addTab("This is a tab", tab);

        button2.setBounds(200, 20, 80, 20);
        panel.add(button2);
        getContentPane().add(panel);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                MigLayoutWithJTabbedPaneButton frame = new MigLayoutWithJTabbedPaneButton();

            }

        });
    }
}