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'方法。 –