加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 覆盖getPreferredSize()中断LSP

发布时间:2020-12-14 05:22:42 所属栏目:Java 来源:网络整理
导读:我总是看到在这个网站上重写getPreferredSize()而不是使用setPreferredSize()的建议,例如这些以前的线程所示. Use of overriding getPreferredSize() instead of using setPreferredSize() for fixed size Components Should I avoid the use of set(Preferr
我总是看到在这个网站上重写getPreferredSize()而不是使用setPreferredSize()的建议,例如这些以前的线程所示.

> Use of overriding getPreferredSize() instead of using setPreferredSize() for fixed size Components
> Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
> Overriding setPreferredSize() and getPreferredSize()

看这个例子:

public class MyPanel extends JPanel{

  private final Dimension dim = new Dimension(500,500); 

  @Override
  public Dimension getPreferredSize(){
      return new Dimension(dim);
  }

 public static void main(String args[]){
      JComponent component = new MyPanel();
      component.setPreferredSize(new Dimension(400,400));
      System.out.println(component.getPreferredSize());
 }

}

有必要对setPreferredSize()

  • Sets the preferred size of this component.

的getPreferredSize()

  • If the preferredSize has been set to a non-null value just returns it. If the UI delegate’s getPreferredSize method returns a non null
    value then return that; otherwise defer to the component’s layout
    manager.

所以这样做清楚地打破了Liskov Substitution Principle.

prefferedSize是一个绑定属性,所以当你设置一个firePropertyChange被执行.所以我的问题是当你重写getPrefferedSize()不需要重写setPreferredSize(..)吗?

例:

public class MyPanel extends JPanel{

  private Dimension dim = null; 

  @Override
  public Dimension getPreferredSize(){
      if(dim == null)
       return super.getPreferredSize();
      return new Dimension(dim);
  }

  @Override
  public void setPrefferedSize(Dimension dimension){
        if(dim == null)
            dim = new Dimension(500,500);
        super.setPreferredSize(this.dim); //
  }

 public static void main(String args[]){
      JComponent component = new MyPanel();
      component.setPreferredSize(new Dimension(400,400));
      System.out.println(component.getPreferredSize());
 }

}

现在我们看到我们得到相同的结果,但是听众将会收到真正的值的通知,而且我们不会破坏LSP的原因setPreferredSize states设置这个组件的首选大小.但不是如何.

解决方法

这个有趣的问题的几个方面(Mad已经提到了我的同伴开发者)

我们是否违反了只覆盖getXXSize()(和setXXSize())的LSP?

不,如果我们正确地执行:-)第一个权限是属性的API文档,最好从它的起源,即组件:

Sets the preferred size of this component to a constant value. Subsequent calls to getPreferredSize will always return this value.

这是一个有约束力的合同,但是我们实现了getter,它必须遵守恒定值,如果设置:

@Override
public Dimension getPreferredSize() {
    // comply to contract if set
    if(isPreferredSizeSet())
        return super.getPreferredSize();
    // do whatever we want
    return new Dimension(dim);
}

XXSize是一个绑定的属性 – 是吗?

在JComponent的祖先中,仅有间接证据:实际上,组件在setter中触发PropertyChangeEvent. JComponent本身似乎记录了事实(粗体我):

@beaninfo
preferred: true
bound: true
description: The preferred size of the component.

哪个是…错误的:被绑定的属性意味着每当值改变时,需要通知监听器,这就是以下(伪测试)必须通过的:

JLabel label = new JLabel("small");
Dimension d = label.getPreferredSize();
PropertyChangeListener l = new PropertyChangeListener() ...
    boolean called;
    propertyChanged(...) 
        called = true;
label.addPropertyChangeListener("preferredSize",l);
label.setText("just some longer text");
if (!d.equals(label.getPreferredSize())
   assertTrue("listener must have been notified",l.called);

…但失败.由于某些原因(不知道为什么这可能被认为是适当的),他们希望xxSize的常数部分是一个绑定的属性 – 这样的覆盖是根本不可能的.当然可以(疯狂地猜测)一个历史性的问题:起初,只有摆放者才能获得(因为很好的理由).在它的backport到awt它突变成一个bean属性,它从来没有.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读