如何防止在JTabbedPane上留下Tab

时间:2012-01-22 21:43:54

标签: java swing jtabbedpane

我有一个嵌套了JTabbedPanes的应用程序。每个JTabbedPanes都包含其他JTabbedPanes。

我想在允许用户离开当前标签之前检查一下。

当您运行下面的代码时,您会看到Months-> February标签有一个ALLOW复选框。

如果选中“允许”复选框,则我希望允许用户导航以退出当前面板。如果不是,那么他们就不能离开,直到它。

我似乎无法找到一种方法来处理下一个组件(可能在另一个JTabbedPane上)之前离开的请求。

这可以通过转到Months-> February标签,然后选择Colors选项卡来证明。

有什么想法吗?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

public class VerifyBeforeLeavingTab extends JFrame
{
    private static final long   serialVersionUID    = 1L;

    public VerifyBeforeLeavingTab()
    {
        setSize(700, 700);

        JTabbedPane mainTabbedPane = new JTabbedPane(JTabbedPane.TOP);

        MyJTabbedPane colorsPane = new MyJTabbedPane(JTabbedPane.TOP, "colors");
        JPanel bluePanel = new JPanel();
        bluePanel.setBackground(Color.blue);
        colorsPane.addTab("Blue", bluePanel);

        JPanel redPanel = new JPanel();
        redPanel.setBackground(Color.red);
        colorsPane.addTab("Red", redPanel);

        mainTabbedPane.addTab("Colors", colorsPane);

        JTabbedPane monthsPane = new MyJTabbedPane(JTabbedPane.TOP, "months");

        JPanel janPanel = new JPanel();
        monthsPane.addTab("January", janPanel);

        JPanel febPanel = new MyUnleavableJPanel();
        monthsPane.addTab("February", febPanel);

        mainTabbedPane.addTab("Months", monthsPane);

        add(mainTabbedPane, BorderLayout.CENTER);

        getContentPane().add(mainTabbedPane);
    }

    private class MyUnleavableJPanel extends JPanel
    {
        private static final long   serialVersionUID    = 1L;

        public MyUnleavableJPanel()
        {
            final JCheckBox chckBoxAllowToLeave = new JCheckBox("Allow to leave");
            chckBoxAllowToLeave.setBounds(100, 100, 50, 50);
            this.add(chckBoxAllowToLeave);

            addHierarchyListener(new HierarchyListener()
            {
                public void hierarchyChanged(HierarchyEvent e)
                {
                    if ((HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags()) != 0)
                    {
                        if (isShowing())
                        {
                            System.out.println("Showing an unleavable panel");
                        }
                        else
                        {
                            // TODO: Do not let them leave this JCheckbox is selected
                            if (chckBoxAllowToLeave.isSelected())
                            {
                                System.out.println("OK to leave");
                            }
                            else
                            {
                                System.out.println("Not allowed to leave");
                            }
                        }
                    }
                }
            });
        }
    }

    private class MyJTabbedPane extends JTabbedPane
    {
        private static final long   serialVersionUID    = 1L;

        public MyJTabbedPane(int i, String name)
        {
            super(i);
            setName(name);
        }

        @Override
        public void setSelectedIndex(int index)
        {
            System.out.println("Now on '" + getName() + "' tab #" + index);
            super.setSelectedIndex(index);
        }
    }

    private static void createAndShowGUI()
    {
        // Create and set up the window.
        VerifyBeforeLeavingTab frame = new VerifyBeforeLeavingTab();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    createAndShowGUI();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    System.exit(0);
                }
            }
        });
    }

}

3 个答案:

答案 0 :(得分:3)

我扩展了JTabbedPane并覆盖了setSelectedIndex()。如果要允许选择成功,请调用super.setSelectedIndex;否则不要。

我使用它来调用与选项卡关联的验证例程,并在验证失败时否决更改。关于这种方法的一个好处是它根本不依赖于用户如何更改标签 - 他可以单击选项卡,单击移动标签的按钮等。

答案 1 :(得分:1)

好的,决定继续我自己的榜样;两个类,运行主类产生一个挥杆窗口,允许您每次单击时更改选项卡。

    import javax.swing.JFrame;
    import javax.swing.JPanel;

    public class TabbedPaneExample extends JFrame
    {
        public static void main(String[] args)
        {
            TabbedPaneExample example = new TabbedPaneExample();
            example.go();
        }

        public void go()
        {
            ValidatingTabbedPane vtp = new ValidatingTabbedPane();
            for(int i=0; i<3; i++)
            {
                vtp.addTab(""+i, new JPanel());
            }
            vtp.setSelectedIndex(0);

            getContentPane().add(vtp);
            pack();
            setVisible(true);
        }
    }

和另一个班级:

    import javax.swing.JOptionPane;
    import javax.swing.JTabbedPane;

    public class ValidatingTabbedPane extends JTabbedPane
    {
      private static final long serialVersionUID = 1L;
      private static void debug(String msg) { System.out.println(msg); }
      private static boolean thisTime = true;

      /**
       * override of selecting a new panel; the new panel selection
       * is only allowed after the current panel determines that
       * its data is valid.
       */
        @Override
        public void setSelectedIndex(int newIndex)
        {
            int currentIndex = getSelectedIndex();
            if (newIndex >=0 && newIndex < getTabCount())
            {
                // if we are currently setting the selected tab for the first
                // time, we don't need to validate the currently selected panel;
                // same if we're (somehow) selecting the current panel
                if(currentIndex == -1)
                {
                    super.setSelectedIndex(newIndex);
                }
          else
          {
              if (currentIndex != newIndex)
              {
                if (thisTime)
                {
                    super.setSelectedIndex(newIndex);
                }
                else
                {
                    JOptionPane.showMessageDialog(null, "Not this time");
                }
                thisTime = !thisTime;
                // ok, the user wants to go from one panel to another.
                // ensure there are no validation errors on the current
                // panel before he moves on.
    //          DataPanel panel = (DataPanel) getSelectedComponent();
    //          if (panel.validateData())
    //          {
    //              super.setSelectedIndex(newIndex);
    ////                tabChangeListener.tabsChanged();
    //          }
            }
          }
            }
            else
            {
                debug("setting new tabbed pane index to " + newIndex + "; wonder why?");
            }
        }



    }

我留下了评论,以显示我在真实节目中的确认位置。

答案 2 :(得分:0)

@rcook - 我已将setSelected()方法插入到原始代码中。 运行程序时,将显示蓝色面板(在“颜色”选项卡下)。

如果您转到二月面板(在月份标签下),您将看到一个复选框。此复选框用于确定用户是否应该离开二月面板。

取消选中复选框,然后单击“一月”。正如所料,不允许用户离开面板。

现在,在取消选中复选框时,单击“颜色”。它不起作用 - 用户不应该离开二月面板,因为未选中复选框。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

public class VerifyBeforeLeavingTab extends JFrame
{
    private static final long       serialVersionUID    = 1L;
    private static final JCheckBox  chckBoxAllowToLeave = new JCheckBox("Allow to leave");

    public VerifyBeforeLeavingTab()
    {
        setSize(700, 700);

        JTabbedPane mainTabbedPane = new JTabbedPane(JTabbedPane.TOP);

        MyJTabbedPane colorsPane = new MyJTabbedPane(JTabbedPane.TOP, "colors");
        JPanel bluePanel = new JPanel();
        bluePanel.setBackground(Color.blue);
        colorsPane.addTab("Blue", bluePanel);

        JPanel redPanel = new JPanel();
        redPanel.setBackground(Color.red);
        colorsPane.addTab("Red", redPanel);

        mainTabbedPane.addTab("Colors", colorsPane);

        JTabbedPane monthsPane = new MyJTabbedPane(JTabbedPane.TOP, "months");

        JPanel janPanel = new JPanel();
        monthsPane.addTab("January", janPanel);

        JPanel febPanel = new MyUnleavableJPanel();
        monthsPane.addTab("February", febPanel);

        mainTabbedPane.addTab("Months", monthsPane);

        add(mainTabbedPane, BorderLayout.CENTER);

        getContentPane().add(mainTabbedPane);
    }

    private class MyUnleavableJPanel extends JPanel
    {
        private static final long   serialVersionUID    = 1L;

        public MyUnleavableJPanel()
        {
            // final JCheckBox chckBoxAllowToLeave = new JCheckBox("Allow to leave");
            chckBoxAllowToLeave.setBounds(100, 100, 50, 50);
            chckBoxAllowToLeave.setSelected(true);
            this.add(chckBoxAllowToLeave);

            addHierarchyListener(new HierarchyListener()
            {
                public void hierarchyChanged(HierarchyEvent e)
                {
                    if ((HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags()) != 0)
                    {
                        if (isShowing())
                        {
                            System.out.println("Showing an unleavable panel");
                        }
                        else
                        {
                            // TODO: Do not let them leave if this JCheckbox is selected
                            if (chckBoxAllowToLeave.isSelected())
                            {
                                System.out.println("OK to leave");
                            }
                            else
                            {
                                System.out.println("Not allowed to leave");
                            }
                        }
                    }
                }
            });
        }
    }

    private class MyJTabbedPane extends JTabbedPane
    {
        private static final long   serialVersionUID    = 1L;

        public MyJTabbedPane(int i, String name)
        {
            super(i);
            setName(name);
        }

        /**
         * override of selecting a new panel; the new panel selection is only allowed after the current panel determines
         * that its data is valid.
         */
        @Override
        public void setSelectedIndex(int newIndex)
        {
            System.out.println("Now on '" + getName() + "' tab #" + newIndex);
            int currentIndex = getSelectedIndex();
            if (newIndex >= 0 && newIndex < getTabCount())
            {
                // if we are currently setting the selected tab for the first
                // time, we don't need to validate the currently selected panel;
                // same if we're (somehow) selecting the current panel
                if (currentIndex == -1)
                {
                    super.setSelectedIndex(newIndex);
                }
                else
                {
                    if (currentIndex != newIndex)
                    {
                        if (chckBoxAllowToLeave.isSelected())
                        {
                            super.setSelectedIndex(newIndex);
                        }
                        else
                        {
                            JOptionPane.showMessageDialog(null, "Not this time");
                        }

                    }
                }
            }
            else
            {
                System.out.println("setting new tabbed pane index to " + newIndex + "; wonder why?");
            }
        }
    }

    private static void createAndShowGUI()
    {
        // Create and set up the window.
        VerifyBeforeLeavingTab frame = new VerifyBeforeLeavingTab();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    createAndShowGUI();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    System.exit(0);
                }
            }
        });
    }

}