VetoableChangeListenerは、登録されたクラスが拒否可能なpropertyChangeを発生させる場合にのみ有効です。 JComponentsとサブクラスのほとんどのプロパティー(すべてが一度も見つからない)は拒否できません。さらに、選択はコンポーネント自体ではなく、SingleSelectionModelによって処理されます。モデルは拒否可能をサポートするためのフックが
に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'メソッドが呼び出されるように、現在のタブを閉じる前に前のタブを選択しています。 –