【问题标题】:Swing: Problem distinguishing between user-induced and automatic components resizing (Writing a custom LayoutManager)Swing:区分用户引起的组件和自动调整大小的问题(编写自定义 LayoutManager)
【发布时间】:2023-03-26 22:50:02
【问题描述】:

我正在尝试编写自己的布局管理器

组件的放置和大小必​​须相对彼此。
这意味着:当用户拖动或调整组件大小时,其他一些 组件(但不是由用户手动更改的组件)必须 改变。

Swing 告诉布局管理器在每次 其中一些被移动/调整大小。这是一个问题,因此布局 管理器自身移动/调整组件大小:
失败了,方法 layoutContainer(Container parent) 被多次调用。

整个事情的一个示例(简化了,实际上我的布局管理器就是这样做的) 更复杂的东西):

  • [-component1-][-component2-------][-component3-]
  • 用户将 component2 调整为更小,我的布局管理器会调整 其他组件,以便它们都占用与以前相同的空间:
    [-component1-][-component2-][-component3-------]
  • 在这里,动作应该停止,但它们会继续:现在是布局管理器 由于调整 component3 的大小而被调用

我怎样才能(以优雅的方式)实现我的意图?
谢谢。

编辑:
根据回答者的建议删除了与线程相关的信息。

【问题讨论】:

    标签: java multithreading swing events synchronization


    【解决方案1】:

    这种反馈循环在处理事件时并不少见。您可以使用几种方法来打破这个循环,我建议您尝试的一种方法是跟踪组件的计算大小。然后,当您处理调整大小事件时,将实际大小与计算出的大小进行比较,如果它们相等则直接返回而不做任何事情。这可能是最稳健的方法,因为它不依赖于事件的顺序或频率。如其他地方所述,您不需要从布局管理器中触摸与线程相关的任何内容。

    【讨论】:

    • "将实际尺寸与计算尺寸进行比较"
    【解决方案2】:

    这不是线程同步问题。

    你说过当用户改变一个对象的大小或位置时,其他对象也必须改变。我猜您正在列出某种更改事件,以便在用户更改对象时触发布局的重新计算。如果是这样,我进一步猜测您的布局管理器正在触发此事件,导致它再次被调用。

    当然,这只是猜测,没有审查你的代码。

    【讨论】:

    • 我没有在监听事件。当 SOMETHING 被移动时,Swing 会调用 layoutmanager 的“layoutContainer(Container parent)”。
    • 您正在监听事件的地方,否则您的组件无法调整大小。用户正在做的事情是调整大小,所以你必须有一个鼠标监听器或拖动监听器。您可以捕获鼠标向下,在用户拖动的布局管理器上设置一个标志,并在看到鼠标向上时清除该标志。那么您可以区分“用户”更改(在拖动期间)和“系统”事件。您还可以捕获用户在同一地点/时间主动修改的组件。
    • 不,布局管理器的“layoutContainer(Container parent)”方法在任何组件被移动/调整大小后被调用(由 Swing)。就是这样。请相信我;)
    【解决方案3】:

    我无法谈论布局管理器的正确实现,但就线程而言,Swing 中的所有事件都在 Swing UI 线程上调度,即同一个线程。因此,同步对象将不起作用,因为只涉及一个线程。您可以通过打印 Thread.currentThread() 或在调试器中检查它来查看正在调用方法的线程。

    根据您要执行的操作,您可能需要查看miglayout。我发现它非常强大且易于使用。正确实现 Swing 布局管理器并非易事。

    【讨论】:

    • 好的,我喜欢听到 Swing 在一个线程中处理所有事情。但是如何阻止这种滚雪球效应呢?应该处理用户引起的组件移动,而不是自动移动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    相关资源
    最近更新 更多