6

現在のタブが有効でない場合、ユーザーがタブを変更できないようにしようとしています。そのため、彼がタブをクリックしたときに、現在のタブが「有効」かどうかを確認し、そうでない場合は現在のタブに留まりたいと考えています。機能しなかった VetoableChangeListener を使用しようとしましたが、コードが vetoableChange メソッド内に入ることはありません。

jTabbedPane.addVetoableChangeListener(new VetoableChangeListener() {

  @Override
  public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
    if (!isCurrentTabValid()) {
      throw new PropertyVetoException("test", evt);
    }
  }
});

どうすればこれを適切に行うことができますか?

ありがとう!

4

3 に答える 3

16

VetoableChangeListener は、それが登録されているクラスが拒否可能な propertyChange を起動する場合にのみ役立ちます。JComponents およびサブクラスのほとんどの (すべて? 1 つに遭遇することはありません) プロパティは拒否できません。さらに、選択は、コンポーネント自体ではなく、SingleSelectionModel によって処理されます。

そのモデルは、拒否可能な変更をサポートするためのフックです

  • 選択の変更時に vetoablePropertyChange を発生させるカスタム モデルを実装する
  • リスナーがオブジェクトを作成しない場合は、変更を続行し、そうでない場合は何もしません
  • カスタム モデルを tabbedPane に設定する
  • 検証ロジックを含む VetoablePropertyChangeListener を実装します
  • vetoableListener をモデルに登録する

コードでは、次のようなもの

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"));
于 2012-09-12T14:31:33.400 に答える
1

最初にタブを無効にしたいようです。次に、現在のページが有効になったら、タブを有効にします。また、タブの代わりに CardLayout を検討することもできます。現在のページが有効な場合は、[次へ] または [続行] ボタンを使用します。

于 2012-09-12T14:00:23.163 に答える
0

vetoableChange は java.beans パッケージの一部のようです。を追加してみてくださいjavax.swing.event.ChangeListener

bodyTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
        public void stateChanged(javax.swing.event.ChangeEvent evt) {
            bodyTabbedPaneStateChanged(evt);
        }
    });


private void bodyTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {
    if (!isCurrentTabValid()) {             
         throw new PropertyVetoException("test", evt);           
     }
}
于 2012-09-12T13:59:52.500 に答える