Как не оставить вкладку на JTabbedPane - PullRequest
2 голосов
/ 23 января 2012

У меня есть приложение, которое вложило JTabbedPanes.Каждый из JTabbedPanes включает в себя другие JTabbedPanes.

Я хочу кое-что проверить, прежде чем позволить пользователю покинуть текущую вкладку.

Когда вы запустите приведенный ниже код, вы увидите, что Months-> На вкладке «Февраль» есть флажок «Разрешено».

Если установлен флажок «Разрешено», я хочу разрешить пользователю переходить из текущей панели.Если это не так, то они не могут уйти, пока это не так.

Я не могу найти способ обработать запрос на выход ДО того, как будет показан следующий Компонент (который может быть на другом JTabbedPane).

Это можно продемонстрировать, перейдя на вкладку Месяцы-> Февраль и затем выбрав вкладку Цвета.

Есть идеи?

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 ]

3 голосов
/ 23 января 2012

Я расширил JTabbedPane и переопределил setSelectedIndex ().Если вы хотите, чтобы выбор был успешным, вызовите super.setSelectedIndex;иначе нет.

Я использую это, чтобы вызвать процедуру проверки, связанную с вкладкой, и наложить вето на изменение, если проверка не удалась.Хорошая особенность этого метода в том, что он совсем не зависит от того, как пользователь меняет вкладки - он может щелкнуть вкладку, нажать кнопку, которая перемещает вкладки и т. Д.

1 голос
/ 24 января 2012

Хорошо, решил продолжить с моим собственным примером; В двух классах запуск основного класса приводит к появлению изменяемого окна, которое позволяет менять вкладки каждый раз, когда вы нажимаете.

    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?");
            }
        }



    }

Я оставил комментарии, чтобы показать, где я проверяю в моей реальной программе.

0 голосов
/ 18 марта 2012

@ 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);
                }
            }
        });
    }

}
...