VetoableChangeListener仅当它注册的类触发vetoable propertyChange时才有用。 JComponents和子类中的大多数(从未遇到过)属性都不可否决。另外,选择由SingleSelectionModel处理,而不是组件本身。
这种模式是支持可否决变化
- 实现触发一个vetoablePropertyChange选择更改自定义模型钩
- 如果没有它的听众对象,继续与变化,否则什么也不做
- 设置自定义模型为tabbedpane
- 实施VetoablePropertyChangeListener其中包含验证逻辑
- 注册vetoableList ENER到模型
代码
,像
public static class VetoableSingleSelectionModel extends
DefaultSingleSelectionModel {
private VetoableChangeSupport vetoableChangeSupport;
@Override
public void setSelectedIndex(int index) {
if (getSelectedIndex() == index)
return;
try {
fireVetoableChange(getSelectedIndex(), index);
} catch (PropertyVetoException e) {
return;
}
super.setSelectedIndex(index);
}
private void fireVetoableChange(int oldSelectionIndex,
int newSelectionIndex) throws PropertyVetoException {
if (!isVetoable())
return;
vetoableChangeSupport.fireVetoableChange("selectedIndex",
oldSelectionIndex, newSelectionIndex);
}
private boolean isVetoable() {
if (vetoableChangeSupport == null)
return false;
return vetoableChangeSupport.hasListeners(null);
}
public void addVetoableChangeListener(VetoableChangeListener l) {
if (vetoableChangeSupport == null) {
vetoableChangeSupport = new VetoableChangeSupport(this);
}
vetoableChangeSupport.addVetoableChangeListener(l);
}
public void removeVetoableChangeListener(VetoableChangeListener l) {
if (vetoableChangeSupport == null)
return;
vetoableChangeSupport.removeVetoableChangeListener(l);
}
}
// usage
JTabbedPane pane = new JTabbedPane();
VetoableSingleSelectionModel model = new VetoableSingleSelectionModel();
VetoableChangeListener validator = new VetoableChangeListener() {
@Override
public void vetoableChange(PropertyChangeEvent evt)
throws PropertyVetoException {
int oldSelection = (int) evt.getOldValue();
if ((oldSelection == -1) || isValidTab(oldSelection)) return;
throw new PropertyVetoException("change not valid", evt);
}
private boolean isValidTab(int oldSelection) {
// implement your validation logic here
return false;
}
};
model.addVetoableChangeListener(validator);
pane.setModel(model);
pane.addTab("one", new JLabel("here we are and stay"));
pane.addTab("other", new JLabel("poor me, never shown"));
这适用于制表符更改,但您如何否决制表符关闭?在关闭标签并选择前一个标签之后,会调用vetoableChange。我在网上搜索了vetoableClose,但没有点击。 –
听起来不相关/扩展 - 请发布一个问题与SSCCE – kleopatra
没关系,我解决了它。我在每个选项卡上添加了一个按钮组件,以关闭它们。它调用'JTabbedPane.remove(tabIndex)'。我设法解决了这个问题。我在关闭当前选项卡之前选择了前一个选项卡,以便调用'valueChanged'方法。 –