动态 JList 实现
我有一个实体列表,其中每个实体基于 JPanel
渲染到小部件中。小部件具有动态行为 - 一旦放置在面板上,它就可以被底层实体更改。这是自动发生的。此外,某些小部件可以通过不同的操作来调整大小,例如单击按钮。
问题是如何将它们组织成类似 JList
的东西,但不使用橡皮图章技术。换句话说,我想要 JList
其中使用 cellrenderer 渲染的每个项目都保持“活动”。
现在我已经实现了基于 JPanel
和垂直 BoxLayout
的快速组件,它使用 JList 的
渲染器组件及其模型...但我的实现太脏了...
嗯..是的,使用 JTable
也不适合。
你有什么想法吗?
I have a list of entities where each entity render into widget based on JPanel
. Widgets have dynamic behaviour - once placed on panel it can be changed by underlying entity. This happens automaticaly. Moreover some widgets can be resized by different actions, on button click for example.
The question is how to organise them into something like JList
but without rubber stamp technics. In other words I wanna JList
where each item rendered with cellrenderer stay "alive".
Right now I have implemented quick-and-dirty component based on JPanel
with vertical BoxLayout
, it uses JList's
renderer component and it's model... but my implementation is too dirty...
Um.. yeah, using JTable
is not suitable too.
Do you have some ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您不希望进行橡皮图章,那么您必须创建自己的使用实际组件的 JList 实现。
您可以尝试通过缓存渲染器中每行的每个组件并将值绑定到其中来解决橡皮图章效果,并在 JList 向渲染器请求时返回该实例。这是相当危险的,因为如果显示 20 行,则必须在渲染器中缓存 20 个实例,并且只有当该行不可见时才能重用其中一个。这意味着,如果您有 5 种独特的组件配置(A、B、C、D、E),则可能有 10 个 A 类型、5 个 B 类型、2 个 C 类型、3 个 D 类型和 0 个类型E 正在显示。但是,您不能简单地重用这些组件之一而不知道它是否显示。因此,您必须考虑该行是否正在显示以及它是否是您正在呈现的行的正确类型。隐藏该行后您必须进行清理。
另一种选择是为封装所有 X 变体的行创建一个组件,并将它们放在 CardLayout 上。然后,您可以简单地为正在显示的每行缓存一个,并在渲染该行时简单地交换正在显示的卡。我认为这对您来说可能是最简单的选择。
更困难的部分是将事件单击鼠标单击、键盘事件等路由到这些活动组件,以使它们像普通组件一样响应。当用户单击按钮时重新呈现按钮等等将具有挑战性。并非不可能,但很乏味。
最后,可变行高 JList 是一个痛苦。特别是在计算是否显示一行时,因为您不能简单地进行简单的数学运算,例如:int rowHeight = jlist.getHeight / model.size()。这不起作用。您必须计算每一行的高度以及它们的高度以确定一行是否可见。
做你所说的事情需要大量的工作,并且需要非常棘手的编码来解决 JList 的一些假设以使其工作。最后,您可能会发现实现自己的列表控件以做出不同的设计决策会更容易。无论哪种方式,都需要您擅长 Swing 才能让它发挥作用。
If you don't want rubber stamping to take place then you'll have to create your own JList implementation that uses actual components.
You could try and work around the rubber stamping effect by caching each component for each row in your renderer and bind values into it and return that instance when JList asks the renderer for it. This is pretty risky because if you have 20 rows being displayed you'll have to cache 20 instances in your renderer, and only when the row isn't visible can you reuse one. That would mean if you had 5 unique configurations (A,B,C,D,E) of components you might have 10 of type A, 5 of type B, 2 of type C, and 3 of type D, and 0 of type E being displayed. However, you can't simply reuse one of those components without knowing if its being displayed or not. So you'd have to take into account if the row is being displayed and if it's the right type for the row you are rendering. And you'll have to clean up after the row is hidden.
Another option is make a single component for the row that encapsulates all X variations you have and put those on a CardLayout. Then you can simply cache one per row being displayed, and simply swap the card being displayed upon rendering that row. I think that might be the simplest option for you.
The harder part is going to be routing events click mouse clicks, keyboard events, etc to those active components to have them respond like normal components. Re-rendering the buttons when the user clicks them, and so forth is going to be challenging. Not impossible, but tedious.
Finally, variable row height JList is a pain. Especially in your calculations to figure out if a row is displayed or not because you can't simply do easy math like: int rowHeight = jlist.getHeight / model.size(). It doesn't work. You have to calculate each row's height and them up to figure out if a row is visible or not.
Doing what you're talking about is a lot of work, and very tricky coding to work around some of the assumptions of JList to make it work. In the end you might find it easier just to implement your own List control that makes different design decisions. Either way its going to require you are good at Swing to get it to work.
好的。我没有找到此类组件的任何实现。让它成为第一个。
https://github.com/wertlex/JActiveList
PS我认为这不是正确的实现方式。 ..但它有效。
Ok. I don't find any implementation of such component. Let it be first one.
https://github.com/wertlex/JActiveList
P.S. I don't think this is proper way implementation... but it works.
使用 JList 和 ActionListener XD
use JList and ActionListener XD