重写 getPreferredSize() 会破坏 LSP

2024-05-16

我总是在这个压倒一切的网站上看到建议getPreferredSize()而不是使用setPreferredSize()例如,如前面的线程所示。

  1. 对于固定大小的组件,使用重写 getPreferredSize() 而不是使用 setPreferredSize() https://stackoverflow.com/questions/10866762/use-of-overriding-getpreferredsize-instead-of-using-setpreferredsize-for-fix
  2. 我应该避免在 Java Swing 中使用 set(Preferred|Maximum|Minimum)Size 方法吗? https://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi
  3. 重写 setPreferredSize() 和 getPreferredSize() https://stackoverflow.com/questions/15308487/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()

  • 设置该组件的首选大小。

getPreferredSize()

  • 如果 PreferredSize 已设置为非空值,则返回它。如果 UI 委托的 getPreferredSize 方法返回非 null 值然后返回该值;否则遵循组件的布局 经理。

所以这样做显然会破坏里氏替换原则 http://www.oodesign.com/liskov-s-substitution-principle.html.

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

例子:

 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 Sets the preferred size of this component.但不知道如何。


这个有趣问题的几个方面(Mad 已经提到了备用开发人员)

我们仅重写 getXXSize()(也相对于 setXXSize())是否违反了 LSP?

如果我们做得正确的话就不会:-) 第一个权威是属性的 API 文档,最好从它的起源开始,即组件:

将此组件的首选大小设置为常量值。对 getPreferredSize 的后续调用将始终返回该值。

这是一个具有约束力的合同,因此无论我们如何实现吸气剂,它都必须尊重constant如果设置的话值:

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

XXSize 是一个绑定属性 - 是吗?

在 JComponent 的祖先中,只有间接证据:实际上,Component 在 setter 中触发 PropertyChangeEvent。 JComponent 本身似乎记录了这一事实(我加粗):

@beaninfo 首选:真实绑定:真实描述:组件的首选尺寸。

这是……完全错误的:作为绑定属性意味着每当值发生变化时都需要通知侦听器,即以下(伪测试)必须通过:

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); 

...但是失败了。出于某种原因(不知道为什么这可能被认为是合适的),他们想要constantxxSize 的一部分是绑定属性 - 这种覆盖根本不可能。可能(当然是疯狂猜测)一个历史性问题:最初,二传手仅在 Swing 中可用(有充分的理由)。在向后移植到 awt 时,它突变为一种从未存在过的 bean 属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重写 getPreferredSize() 会破坏 LSP 的相关文章

  • 不支持的字段:将瞬间格式化为日期 ISO 时的年份[重复]

    这个问题在这里已经有答案了 我正在尝试将 Instant 格式化为 ldap 日期 ISO8601 但在 f format Instant now 处失败 String input 20161012235959 0Z DateTimeFor
  • 在 String 值之后打印 int 值

    我有以下示例代码 int pay 80 int bonus 65 System out println pay bonus bonus pay 有人可以向我解释一下为什么我得到以下输出 145 6580 您的代码正在从左到右解释表达式 pa
  • 简单 XML 框架:ElementMap 中的对象具有“类似内联”的行为

    我正在尝试在 Android 上序列化自定义对象的 Hashmap 以获得如下 xml
  • 如何在ArrayList中的特定位置插入对象

    假设我有一个大小为 n 的对象的 ArrayList 现在我想在特定位置插入另一个对象 假设在索引位置 k 大于 0 且小于 n 并且我希望索引位置 k 处及其之后的其他对象向前移动一个索引位置 那么有没有什么方法可以直接在Java中做到这
  • 如何在 Android 中的 Chrome 或 Firefox 等特定浏览器的 Web 视图中加载应用程序

    我是 Android 新手 我正在做一个应用程序 我需要在平板电脑上的 Web 视图中加载现有的应用程序 在平板电脑中 当我使用 Web 视图加载应用程序时 我的应用程序将加载到默认浏览器中 如何在平板电脑上的 Web 视图中的特定浏览器
  • Java 小程序在 Mac 上闪烁

    这个问题很奇怪 问题并非在每个平台上都会发生 我在使用 MacOSX 的 Google Chrome 中出现了这种情况 但在 Safari 中却没有出现这种情况 对于使用 Windows 的朋友来说 在 Google Chrome 上运行得
  • 如何准确判断 double 是否为整数? [复制]

    这个问题在这里已经有答案了 具体来说 在 Java 中 我如何确定double是一个整数 为了澄清 我想知道如何确定 double 实际上不包含任何分数或小数 我主要关心的是浮点数的性质 我想到的方法 以及我通过谷歌找到的方法 基本上遵循以
  • Java Junit 测试 HTTP POST 请求

    我需要测试以下方法而不改变方法本身 该方法向服务器发出 POST 方法 但我需要制作一个独立于服务器的测试用例 在将其重定向到本地文件之前 我测试了类似的方法 但为此我将协议指定为文件 主机名指定为 localhost 端口指定为 1 我的
  • 对对象集合进行排序[重复]

    这个问题在这里已经有答案了 如果我有一个简单的字符串列表 List
  • 在拇指上方显示修改后的 JSlider 值

    有没有一种简单的方法可以在使用某些 外观和感觉 的同时更改 JSlider 上方标签中显示的值 为了清楚起见 我正在谈论这个值 具体来说 我想显示除以 1000 的值而不是值本身 我知道如果我显示它们 我可以为刻度设置标签 但用户将不得不猜
  • 但是创建静态实用方法不应该被过度使用吗?如何避免呢? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 随着时间的推移 java项目中引入了许多实用方法来完成更复杂和简单的任务 当使用静态方法时 我们在代码中引入了紧密耦合 这使得我们的代
  • for循环中更新JLabel的问题

    我的程序的想法是从之前在其他 JFrame 中保存的列表中选择一个名称 我想在标签中一个接一个地打印所有名称 它们之间有很小的延迟 然后停在其中一个名称上 问题是lbl setText String 如果有多个则不起作用setText co
  • 在Java中如何将字节数组转换为十六进制?

    我有一个字节数组 我希望该数组的每个字节字符串转换为其相应的十六进制值 Java中有没有将字节数组转换为十六进制的函数 byte bytes 1 0 1 2 3 StringBuilder sb new StringBuilder for
  • RxJava android mvp 单元测试 NullPointerException

    我是 mvp 单元测试的新手 我想对演示者进行一个非常基本的测试 它负责登录 我只想断言 view onLoginSuccess 这是演示者代码 public LoginPresenter LoginViewContract loginVi
  • ActiveMQ JNDI 查找问题

    尝试使用 JNDI 运行以下 ActiveMQ http activemq apache org jndi support html http ActiveMQ 20JNDI 并且我的 jboss server node lib 文件夹中有
  • 使用 Guava Ordering 对对象列表进行多条件排序

    我有一个类无法实现可比较 但需要根据 2 个字段进行排序 我怎样才能用番石榴实现这一目标 假设班级是 class X String stringValue java util Date dateValue 我有一个清单 List
  • JPA Web 应用程序管理策略

    我们目前正在开发一个 J2EE Web 应用程序 使用 JPA 作为我们的数据访问层 我们目前正在研究几种不同的策略来在我们的应用程序中利用缓存 Create an EntityManager per request 在请求范围内获取缓存
  • java.lang.UnsatisfiedLinkError - android studio gradle 中的 NDK?

    文件夹结构 app main java jni Android mk Application mk hello jni c res 在构建 gradle apply plugin com android application androi
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • Android ClassNotFoundException:在路径上找不到类

    10 22 15 29 40 897 E AndroidRuntime 2561 FATAL EXCEPTION main 10 22 15 29 40 897 E AndroidRuntime 2561 java lang Runtime

随机推荐

  • 返回主要活动(意图)时传递数据我做错了什么?

    我是安卓新手 这可能是最简单的问题 但我不明白这里出了什么问题 我试图创建一个通过意图传递值的基本示例 因此 当我关闭第二个活动时 我需要将数据传递到主活动 这是代码 意图测试1 主要活动 public void onClick View
  • 将单独的月、日和年值转换为时间戳

    我有月份值 1 12 日期值 1 31 和年份值 2010 2011 2012 我还有一个小时值和一个分钟值 我怎样才能把这个给strtotime 它可以以某种方式将其转换为时间戳吗 当您已经知道年月和日期时 为什么将字符串转换为日期 us
  • 尝试从网页Python和BeautifulSoup获取编码

    我试图从网页检索字符集 这会一直改变 目前我使用 beautifulSoup 来解析页面 然后从标题中提取字符集 这工作正常 直到我遇到一个网站 到目前为止 我的代码以及与其他页面一起使用的代码是 def get encoding soup
  • 如何使用多个数据库设置 symfony 3 学说迁移?

    我在验证和更新模式时努力让 symfony doctrine 排除数据库视图 我第一次尝试没有教条迁移 看到这个问题 https stackoverflow com questions 46775200 symfony 3 doctrine
  • 查询 MongoDB 集合中的字段。

    我正在尝试查询 mongodb 集合中的特定字段 这是我的代码和输出 Mongo m new Mongo DB db m getDB mydb DBCollection coll db getCollection student addin
  • Hector 在执行incrementCounter 后获取结果计数器值

    我们正在执行以下操作来更新计数器的值 现在我们想知道是否有一种简单的方法可以立即取回更新的计数器值 mutator incrementCounter rowid1 cf1 counter1 value Cassandra thrift AP
  • 将自定义参数传递给 Symfony2 中的自定义 ValidationConstraint

    我正在 Symfony2 中创建一个表单 表格只包含一个book字段允许用户在列表中进行选择Books实体 我需要检查是否选择了Book属于Author我的控制器里有 public class MyFormType extends Abst
  • Python re无限执行

    我正在尝试执行这段代码 import re pattern r w w s re compiled re compile pattern results re compiled search COPRO HORIZON 2000 HOR p
  • PHP URL 验证

    我知道有无数的线程问这个问题 但我一直无法找到一个可以帮助我解决这个问题的线程 我基本上试图解析大约 10 000 000 个 URL 的列表 确保它们根据以下标准有效 然后获取根域 URL 此列表包含您能想象到的几乎所有内容 包括类似的内
  • 使用 find - 删除除任何一个之外的所有文件/目录(在 Linux 中)

    如果我们想删除我们使用的所有文件和目录 rm rf 但是 如果我希望一次性删除除一个特定文件之外的所有文件和目录怎么办 有什么命令可以做到这一点吗 rm rf 可以轻松地一次性删除 甚至可以删除我最喜欢的文件 目录 提前致谢 find ht
  • jQuery 可以操作插入的元素吗?

    我是 jQuery 的新手 我认为 jQuery 可以操作由代码添加的元素是合理的 但我发现现在还不能 function addVideo click function publisher append div div
  • 使用 PHP 修剪字符串开头的任何零

    用户将在字段中填写与其帐户相关的数字 不幸的是 一些用户会在号码开头添加零来组成六位数字 例如 000123 001234 而其他用户则不会 例如 123 1234 我想 修剪 前面带有零前缀的用户的数字 因此如果用户输入 000123 它
  • 使用 ZBarSDK 时 iPhone 相机失去自动对焦功能

    我正在开发一个应用程序 用户可以选择是否要扫描条形码或拍摄某物的照片 为了拍照 我正在使用UIImagePickerController照常 为了扫描条形码 我使用 ZbarSDK 1 2ZBarReaderViewController 拍
  • React中如何触发同级组件的函数?

    I am new to front end world and could not figure out how to trigger a function from a sibling component Lets say I have
  • UILabel 中的文本未垂直居中

    我使用以下代码创建了一个标签 func setupValueLabel valueLabel numberOfLines 1 valueLabel font UIFont name Avenir Black size 50 valueLab
  • 指示电子邮件的类型

    我有以下自动化程序 它将电子邮件发送给我自己 并添加了特定的链接 import win32com client as win32 import easygui import tkinter as to from tkinter import
  • 将 N 种类型的参数包折叠成 N-1 对

    我正在尝试折叠参数包N不同类型分为std tuple of N 1 std pairs与各自的类型 例如表达式 ResolveToTupleOfPairs
  • 导入模块 WebAdministration 不会从脚本加载,但会从命令行加载

    我正在进行一个使用的项目PowerShell编写构建脚本 该构建利用了WebAdministration模块来管理本地 IIS 实例 当我运行构建脚本时 尝试导入时会引发以下错误WebAdministration 错误 06 29 2016
  • 简单 Haskell Monad - 随机数

    我正在尝试扩展代码这个帖子 https stackoverflow com questions 3944170 haskell and state 接受的答案 允许我能够基于以种子作为参数的函数 randomGen 调用 randomGen
  • 重写 getPreferredSize() 会破坏 LSP

    我总是在这个压倒一切的网站上看到建议getPreferredSize 而不是使用setPreferredSize 例如 如前面的线程所示 对于固定大小的组件 使用重写 getPreferredSize 而不是使用 setPreferredS