1

在我开始之前,存在类似的(我的)问题,我希望删除那个问题,因为我没有很好地解释我的观点,但不是这个问题。谢谢你。

首先,我没有代码,这只是一个我想不通的概念。但这很有趣(至少对我来说)。

你们都知道 MSWord 是如何工作的。你写东西。然后,当您填写一个页面时,它将创建一个新页面并开始在该页面上书写。如果您将更多文本粘贴到第一页,所有内容都将被下推。如果您删除页面上的一大块文本,它会吸收前一页上的一些文本。如果您正在处理例如图片并且您在页面顶部有一个,如果有足够的空间容纳图片的缩小版本,则减小它的大小会导致它被吸到上一页。

既然您是这样想的,我想将这个概念转移到 Java Swing 中。页面是 JPanel,图片和文本块(或行)是适合页面 JPanel 的 JPanel。

我想出了一个使用填充器的方法(好吧,我撒谎了,我有一些代码,但它是一团糟,而且无论如何它都不起作用),这在所有情况下都不起作用。如果您想知道原因,请阅读两行之间的内容,否则请跳过它。


因此,结构本身很容易复制,但维护它是一件令人头疼的事情。您会看到,可能会发生两种主要类型的事件:

a) height of the page content has increased
b) height of the page content has decreased

通过使用 Filler 作为页面的最后一个组件,并附加一个 componentAdapter (componentResized),您可以监控这些更改。

这些变化可以进一步分为:

a) element is added/removed to/from page
b) height of the element has increased/decreased 

考虑到这些事件,可能会发生很多事情。跳过简单的案例,看这个例子:

Page 1:
{element 1
blabla
blabla}
{element 2
blabla}
{element 3}
{element 4
blabla
blabla
blabla
blabla}
{free space
---
---
---}

/

Page 2:
{element 1
blabla
blabla
blabla
blabla}
{element 2
blabla
blabla
blabla
blabla}
{element 3}
{element 4
blabla
blabla
blabla}

/

Page 3:
{element 1}
{element 2}
{element 3}
{element 4}
{element 5}
{free space
---
---
---
---
---
---
---
---
---}

每页的高度为 15 行。现在看看如果将第二页的元素 1 的高度减少一行会发生什么。它将变为 4 行高,使其适合上一页,被吸起。这将在第二页上创建 5(1 个删除的行 + 4 个被吸收的行)行的可用空间。这将吸收第三页上的所有五个元素,并将第三页留空(现在应该删除)。

这不起作用的原因是因为在删除时,会为第二页触发一个侦听器,它必须将顶部元素向上推,并从前一页中吸收元素。由于这一切都是在侦听器中完成的,因此我必须等待它执行才能在我的程序中注册视觉变化。由于它必须更改页面上的两件事,因此会导致某种听众混乱。页面高度减少了两次,但只注册了一次,最后我只能完全移动顶部或底部,或每侧的单个组件。这不是一个很好的解释,但如果你了解摇摆的工作原理,你应该能够自己连接这些点。

正如我之前提到的,我已经为此编写了代码,但是它很长而且很难遵循,如果有人愿意看到它,我可以在这里发布它。我说的是SSCCE 本身。它真的不能缩短为几十行代码。


我想要的是跳过编写一个算法来维护“文档”的结构并移动所有元素,因为这是一件非常复杂的事情,需要考虑所有众多案例。

我想要的是另一种选择,我问你是否有任何想法。我想到的一件事是有一个类似于 JPanel 的组件。它将具有可以与其他组件一起填充的固定高度部分,并且在它们之间具有不可填充(?)或“实心”的固定高度部分。

它的工作方式是每次您向可填充(?)部分添加一些东西时,它们都会自动重新排列。如果某些东西不适合当前可填充的部分,它只是移动到下一个(类似于垂直框布局的工作原理,将一个东西添加到一个点会推动所有其他东西向下),但会跳过实体部分。

因为我还必须能够判断某个组件在哪个可填充部分中,所以我不知道在 Java swing 中是否可以创建这样的结构。

好吧,欢迎任何建议,包括外部库。

请记住,整个文档是包含页面的文档,这些页面将一个接一个地放置在 JScrollPane 的视口中,这是对其外观的唯一限制。

4

1 回答 1

3

让布局完成工作:add()的实例JPanel,每个实例都有基于内容的首选大小,Box具有垂直布局。放入Box一个JScrollPane,可选地实现Scrolable. 根据需要使用滚动窗格的行和列标题;JTable是一个例子。您可以根据需要从和remove()面板中选择。Boxrevalidate()repaint()

附录:最初的答案仅涉及问题的视图方面。它可能有助于更严格地分离模型和视图,就像文本组件一样;从模型中删除内容并通知视图相应地更新自身。为了实现这一点,这里提到了几种实现观察者模式的常用方法。

于 2013-01-25T19:55:55.373 回答