禁止在JTabbedPane中更改选项卡

Nan*_*com 6 java swing jtabbedpane

我试图阻止用户在当前选项卡无效时更改选项卡.所以当他点击一个标签时,我想检查当前标签是否"有效",如果不是,请保持当前标签.我试图使用一个不起作用的VetoableChangeListener,代码永远不会进入vetoableChange方法:

jTabbedPane.addVetoableChangeListener(new VetoableChangeListener() {

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

我该怎么做呢?

谢谢!

kle*_*tra 16

VetoableChangeListener仅在注册的类触发可否决的propertyChange时才有用.JComponents和子类的大多数(所有?从未遇到过)属性都不可撤销.此外,选择由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"));
Run Code Online (Sandbox Code Playgroud)