Swing 外行分页 [英] Swing layman pagination

查看:29
本文介绍了Swing 外行分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Before I start, similar question (of mine) exists, I'd like that one to be deleted since I didn't explain my point well there, but not this one. Thank you.

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

First of all, I have no code, this is only a concept that I can't figure out. But it's interesting (at least to me).

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

You all know how MSWord works. You write stuff. Then, when you fill a page it will create a new page and start writing on that page. If you paste some more text to the first page, everything will be pushed down. If you delete a large chunk of text on a page, it will suck up some of the text on the previous page. If you're dealing with e.g. pictures and you have one on top of a page, reducing it's size my cause it to get sucked up to the previous page, if there is enough room for the reduced version of the picture.

既然你这么想,我想把这个概念转移到 Java Swing 中.页面是JPanel,图片和文本块(或行)是安装在页面JPanel上的JPanel.

Now that you're thinking this way, I want to transfer that concept into Java Swing. Pages are JPanels, and pictures and chunks (or lines) of text are JPanels fitted onto the page JPanel.

我提出了(好吧,我撒谎了,我有一些代码,但它很混乱,无论如何它都不起作用)使用填充器的方法,该方法并非在所有情况下都有效.如果您想知道原因,请阅读两行之间的内容,否则直接跳过.

I have come up (okay, I lied, I have some code, but it's a mess and it doesn't work anyway) with a method using a Filler, which doesn't work in all cases. If you want to know why, read between the two lines, otherwise just skip it.

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

So, the structure itself is easy to replicate, but maintaining it is a pain in the neck. You see, there are two main types of events that can occur:

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

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

By using a Filler as the last component of a page, and having a componentAdapter (componentResized) attached to it, you can monitor those changes.

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

These changes can further be dividet into:

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

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

Taking those events into consideration many things can happen. Skipping the simple cases, look at this example:

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 个吸起的行)行的可用空间.这将吸收第三页上的所有五个元素,并将第三页留空(现在应该删除).

Each page has a height of 15 rows. Look now what happens if you reduce the height of the element 1 of the second page by one row. It will become 4 rows high, making it fit to the previous page, being sucked up. That will create 5(1 deleted row + 4 sucked up rows) rows worth of free space on the second page. That will suck up all the five elements on the third page and leave the third page blank (which should now be deleted).

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

The reason this wouldn't work is because upon deletion, a listener is triggered for the second page and it has to both push the top element up, and suck up the elements from the previous page. Since it's all done in a listener, I have to wait for it to execute in order to register visual change in my program. Since it has to change two thing on a page, it comes to somekind of listener chaos. Page height is reduced twice but is registered only once and in the end I can fully move only thr top part or the bottom part, or a single component on each side. This isn't really a good explenation, but if you understand how swing works, you should be able to connect the dots yourself.

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

As I mentioned before, I have written the code for that, but it's long and hard to follow, and I can post it here, if anyone shows the desire to see it. And I'm talking about SSCCE itself. It really can't be shortened into couple of 10s of rows of code.

我想要的是跳过编写一个算法来维护文档"的结构并移动所有元素,因为这是一件非常复杂的事情,需要处理大量案例.

What I would want is to skip writting an algorithm that would maintain the structure of the "document" and move all the elements around, since it's a really complicated thing to do, taking all the numerous cases.

我想要的是一个替代方案,我问你是否有任何想法.我想到的一件事是有一个类似于 JPanel 的组件.它将具有可以填充其他组件的固定高度部分,以及它们之间不可填充(?)或实心"的固定高度部分.

What I want is an alternative and I'm asking you if you have any ideas. One thing that came to my mind is having a component similar to JPanel. It would have fixed height-parts that can be populated with other components, and between them fixed height-parts that are unpopulable(?) or "solid".

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

Way it would work would be that everytime you add something to populable(?) parts, they would be automatically rearanged. If something doesn't fit to the current populable part, it's just moved to the next one (similar to how verticall box layout works, adding one thing to a spot pushes all the others down), but skiping the solid part.

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

Since I would also have to be able to tell in which populable part a certain component is, I don't know if creating a such structure is possible in Java swing.

好吧,欢迎提供任何建议,包括外部库.

Well, any advice is welcome, external libaries included.

请记住,整个文档是包含页面的文档,页面将一个接一个地放置在 JScrollPane 的视口中,这是对它应该是什么样子的唯一限制.

Just keep in mind that this whole document is document with pages that would be placed one after another in a JScrollPane's viewport, and that is the only limit to what it should look like.

推荐答案

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

Let the layout do the work: add() instances of JPanel, each having its own preferred size based on content, to a Box having a vertical layout. Put the Box in a JScrollPane, optionally implementing Scrolable. Use the scroll pane's row and column headers as needed; JTable is an example. You can remove() a panel from the Box, revalidate() and repaint() as required.

附录:最初的答案仅解决了问题的视图方面.它可能有助于更严格地分离模型和查看,如 文本组件 做;从模型中删除内容并通知视图相应地更新自身.为了实现这一点,此处提到了几种常见的实现观察者模式的方法.

Addendum: The initial answer addressed only the view aspect of the problem. It may help to separate the model and view more rigorously, as the text components do; remove content from the model and signal the view to update itself accordingly. To achieve this, several common approaches to implementing the observer pattern are mentioned here.

这篇关于Swing 外行分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆