我有一个嵌套了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);
}
}
});
}
}
答案 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);
}
}
});
}
}