JScrollPane 内的 JLayeredPane 内的 JTable - 如何让它工作?

Nic*_*cue 5 java swing jtable jscrollpane jlayeredpane

我想将来自 JTable 的对象分层放置在 JTable 之上,因此使用 JLayeredPane 似乎很自然。然而,让它正确地绘制,正确地做标题等是非常困难的。我该如何做到这一点,以便:

  • 行标题出现并在滚动时匹配
  • 滚动时列标题会出现并匹配
  • 桌子油漆正确
  • 调整大小不会弄乱一切

请注意,由于JDesktopPaneextends JLayeredPane,此问题的答案还允许您JTable在 . 后面有一个(或任何其他组件)JDesktopPane

Nic*_*cue 5

类似但不相同的问题有助于: Java - Is it possible to put a JLayeredPane inside JScrollPane? 以及如何使用 JScrollPane 和 JLayeredPane 在 JTable 单元格Swing GUI 设计中显示动画。

要正确执行此操作,需要考虑三个单独的问题:大小调整、标题和 UI 更改。

浆纱

要正确滚动和绘制,JScrollPane需要知道其内部组件的大小和首选大小,在本例中为JLayeredPane. 但是您希望大小由表格设置,因为其他Components 将浮动在表格顶部。在这种情况下,最简单的方法是将 JLayeredPane 委托大小相关属性设置为如下JTable

final JTable table = new JTable();
JLayeredPane layers = new JLayeredPane() {
  @Override
  public Dimension getPreferredSize() {
    return table.getPreferredSize();
  }

  @Override
  public void setSize(int width, int height) {
    super.setSize(width, height);
    table.setSize(width, height);
  }

  @Override
  public void setSize(Dimension d) {
    super.setSize(d);
    table.setSize(d);
  }
};
// NB you must use new Integer() - the int version is a different method
layers.add(label, new Integer(JLayeredPane.PALETTE_LAYER), 0);
JScrollPane scrolling = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrolling.setViewportView(layers);
Run Code Online (Sandbox Code Playgroud)

如果您不希望JTable成为决定 大小的因素,JLayeredPane则需要以其他方式确定它,表的大小也是如此。两者都需要setPreferredSize()并且setSize()明确要求他们。

标头

由于 JTable 不再是视口,因此您需要自己链接标题。以下代码将起作用:

scrolling.setColumnHeaderView(table.getTableHeader());
scrolling.setRowHeaderView(rowHeader);
Run Code Online (Sandbox Code Playgroud)

用户界面

另请注意,JTable 在 `configureEnlookingScrollPane()` 和 `configureEnlookingScrollPaneUI()` 中执行了一些令人讨厌的代码。如果你想让 UI 样式更改正常工作,那么你必须重写这些方法,但我还没有弄清楚如何做到这一点。

代码示例

完整的代码示例可在 GitHub 上获取。