java JTable 和 JScrollpane 大小的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6234530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Problems with JTable and JScrollpane size
提问by Wolfgang Adamec
I have a JScrollPane
with a JTable
in it. In the JTable
I have initially 3 rows. Later on rows get added.
我有JScrollPane
一个JTable
在里面。在JTable
我最初有 3 行。稍后添加行。
The default JTable
with my 3 rows is ugly because JScrollPane
calls getPreferredScrollableViewportSize
from the client (JTable
) and the return value is always the same. That's why my JTable
/JScrollpane
with 3 rows has this free space, JScrollpane and
JTable do not have the same size.
JTable
我的 3 行的默认值很难看,因为来自客户端 ( ) 的JScrollPane
调用和返回值始终相同。这就是为什么我的/有 3 行有这个可用空间,JTable 没有相同的大小。getPreferredScrollableViewportSize
JTable
JTable
JScrollpane
JScrollpane and
My solution is to make a subclass JTabl
e, override getPreferredScrollableViewportSize
and return in this function getPreferredSize();
. Now the whole JScrollPane
has exactly the size of the 3 row `JTable!
我的解决方案是在这个函数中创建一个子类JTabl
e,覆盖getPreferredScrollableViewportSize
并返回getPreferredSize();
。现在整个JScrollPane
有3行`JTable的大小!
When a row gets added I have the command ((JComponent) scrollPane.getParent()).revalidate();
当添加一行时,我有命令 ((JComponent) scrollPane.getParent()).revalidate();
The scrollpane grows with the table.
滚动窗格随表格一起增长。
Everything works fine!
一切正常!
But now I want to set a certain layout for the container of the scrollpane (panel):
myjpanel.setLayout (new BoxLayout(contentPane, BoxLayout.Y_AXIS));
但是现在我想为滚动窗格(面板)的容器设置某个布局:
myjpanel.setLayout (new BoxLayout(contentPane, BoxLayout.Y_AXIS));
When I add this command my whole solution doesn't work anymore. The scrollpane hasn't the size of the 3 row table, this free space is there again.
当我添加此命令时,我的整个解决方案不再起作用。滚动窗格没有 3 行表的大小,这个可用空间又出现了。
Why is this?
为什么是这样?
Does anybody have a solution?
有人有解决方案吗?
CONTINUED
继续
Thank you camickr for pointing me in the right direction. My solution is the following:
感谢 camickr 为我指明了正确的方向。我的解决方案如下:
scrollPane = new JScrollPane (table) {
public Dimension getMaximumSize () {
double height = 0;
double width = super.getMaximumSize().getWidth();
height += columnHeader.getViewSize().getHeight();
height += viewport.getView().getPreferredSize().getHeight();
height += (getViewportBorderBounds().getHeight() * -1);
Dimension returnValue = new Dimension ((int) width, (int) height);
return returnValue;
}
};
It works now at the beginning. But when a row is added to the jtable and I call revalidate(); on the jpanel (parent container of the scrollpanel) the jscrollpanel shrinks in height to 1 row + header! Has anyone got an idea what is to do in this situation.
它现在开始工作。但是当一行被添加到 jtable 并且我调用 revalidate(); 在 jpanel(滚动面板的父容器)上,jscrollpanel 的高度缩小到 1 行 + 标题!有没有人知道在这种情况下该怎么做。
CONTINUED
继续
Now I know the problem. It is the viewportBorder. In order to get the whole, exact height I have to total the height of the view (Jtable), the height of the column header and the height of the viewportBorder. The first time getViewportBorderBounds().getHeight()
returns -3, next time - after a new row is inserted in the table model - the function returns 48. I do not understand why this function returns 48 now.
Another point is that camickr says that changing the size of the jscrollpane defeats the purpose of the scrollpane. I do not understand this. How can anyone be satisfied with a default jscrollpane size of 450 x 400 (http://www.javalobby.org/java/forums/t19559.html) even when the jtable has only 3 lines at the beginning. This unfilled extra space does not look very professional in my eyes. Has anyone got a better solution for this.
现在我知道问题所在了。它是视口边框。为了获得完整的准确高度,我必须将视图(Jtable)的高度、列标题的高度和 viewportBorder 的高度相加。第一次getViewportBorderBounds().getHeight()
返回 -3,下次 - 在表模型中插入新行后 - 函数返回 48。我不明白为什么这个函数现在返回 48。另一点是 camickr 说改变 jscrollpane 的大小违背了滚动窗格的目的。我不明白。即使 jtable 开头只有 3 行,怎么会有人对 450 x 400 (http://www.javalobby.org/java/forums/t19559.html) 的默认 jscrollpane 大小感到满意。这个未填充的额外空间在我看来不是很专业。有没有人对此有更好的解决方案。
Thank you very much for your answers
非常感谢您的回答
CONTINUED
Now everything works!
At the beginning I simply set the jscrollpane border to 0 ... sp.setBorder(createEmptyBorder());
In this way I avoid having these strange return values of getViewportBorderBounds().getHeight()
Wolfgang
续 现在一切正常!一开始我只是将 jscrollpane 边框设置为 0 ...sp.setBorder(createEmptyBorder());
这样我就避免了getViewportBorderBounds().getHeight()
Wolfgang 的这些奇怪的返回值
采纳答案by camickr
The BoxLayout allows the component to grow up to the maximum size of the component. I guess you need to override the getMaximumSize() of the scrollpane to return the preferred size.
BoxLayout 允许组件增长到组件的最大大小。我想您需要覆盖滚动窗格的 getMaximumSize() 以返回首选大小。
When a row gets added I have the command "((JComponent) scrollPane.getParent()).revalidate();" The scrollpane grows with the jtable.
当添加一行时,我有命令“((JComponent) scrollPane.getParent()).revalidate();” 滚动窗格随着 jtable 增长。
That kind of defeats the purpose of the scrollpane. The scrollbar is supposed to stay at a fixed size and then scrollbars will appear if necessary.
这违背了滚动窗格的目的。滚动条应该保持固定大小,然后在必要时会出现滚动条。
回答by S. Hayes
I had a similar problem - the basic upshot is that I wanted a JTable in a scroll pane that had a minimum and maximum size: when there was no data in the table, it should have a one-row-height pane background displayed (not a fake row, obviously), and when it was over 10 rows to limit the displayed table size to those 10 rows plus scrollbars. Any size between 1 and 10 should display the table at full height. The situation was a parent-child table, and this was the child table, so I had to trigger the child table resize depending on which parent table row was clicked. A fixed pane size looked ugly in that it took up unnecessary space to push other potentially viewable info under the child table out of view with just blank space.
我有一个类似的问题 - 基本结果是我想要一个滚动窗格中的 JTable 具有最小和最大大小:当表中没有数据时,它应该显示一行高的窗格背景(不是一个假行,显然),当它超过 10 行时,将显示的表格大小限制为这 10 行加上滚动条。1 到 10 之间的任何尺寸都应以全高显示表格。情况是一个父子表,这是子表,所以我必须根据单击的父表行来触发子表调整大小。固定的窗格大小看起来很丑陋,因为它占用了不必要的空间来将子表下的其他可能可见的信息推出视图之外,而只有空白空间。
Using the setPreferredScrollableViewportSize after updating the model with the child rows (and setFillsViewportHeight(true) of course) gave me almost everything I needed. Except that the viewport wouldn't redraw until I clicked on it, or took focus from the window then flicked back, it was most annoying.
在使用子行更新模型后使用 setPreferredScrollableViewportSize(当然还有 setFillsViewportHeight(true))给了我几乎所有我需要的东西。除了视口在我点击它之前不会重绘,或者从窗口获取焦点然后轻弹回来,这是最烦人的。
The solution was super-simple after reading this post: I just had to call revalidate on the scrollpane's parent, as pointed out in the solution. Fixed it perfectly. Mostly I just wanted to share a use case where you want the scrollpane size to change dynamically up toa maximum size. Swing is so much simpler if everything is created at a fixed size forever... unlike pretty much every real-life use case I've ever encountered :-)
阅读这篇文章后,解决方案非常简单:正如解决方案中所指出的,我只需要在滚动窗格的父级上调用 revalidate 即可。完美地修复了它。主要是我只是想分享你想要滚动窗格的大小来改变动态用例最多的最大尺寸。如果一切都永远以固定大小创建,那么 Swing 就会简单得多……这与我遇到的几乎每个现实生活中的用例都不一样:-)