多个 JTables 彼此重叠,就像一个 JTable



我想让 x 个 JTables 彼此重叠,就像一个 JTable 一样。我已经创建了 x 个单独的 JScollPanes - 每个表一个,并将它们全部插入到一个 JPanel (panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));(。

我只显示最顶层表格的标题。 为了实现它们水平滚动一致,我在这里使用了。

我还剩下两个任务才能达到它看起来像一个大 JTable 的预期结果。

  1. 我想要只有一个垂直滚动条?如何实现这一点?

  2. 我希望所有表与最顶层的表共享相同的 TableColumnModel(这是唯一显示标题的表(,因此如果通过拖放标题移动列,则所有表都会反映更改...

如果有人想知道,我之前尝试将每个 JTable 添加到 JPanel 中,然后将每个 JPanel 添加到一个 JScrollPane。 该解决方案的问题在于,如果其中一个 JTable 有许多条目,则垂直滚动条不会出现以显示所有条目。

基于这个问题和您其他问题的图片,我可能会有一种方法,尽管它有点黑客。

方法:

  1. 创建多个表并将它们添加到 JScrollPane。使用 BoxLayout 将每个滚动窗格添加到面板

  2. 第一个滚动窗格将包含并清空表,因此滚动窗格中仅显示表标题。

  3. 最后一个滚动窗格将显示 JTable 和水平滚动条。

  4. 第一个和最后一个之间的任何滚动窗格将仅显示 JTable。

  5. 该代码使用自定义ScrollablePanel。此面板将强制面板的宽度等于视区的宽度。这反过来将强制每个滚动窗格的水平滚动条处于活动状态。每个水平滚动条共享相同的模型,因此即使只有一个滚动条可见,所有表也会同时滚动。

查看可滚动面板以获取要下载的代码。

这里的代码:

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableSharedHeader2 extends JPanel
{
private JTable table1;
private JTable table2;
private JPanel tablePanel;
TableSharedHeader2()
{
setLayout( new BorderLayout() );
//  Only the Table Header is displayed
JTable table0 = new JTable( 0, 10);
table0.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table0.setPreferredScrollableViewportSize(table0.getPreferredSize());
JScrollPane scrollPane0 = new JScrollPane( table0 );
scrollPane0.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
//  Only the JTable is displayed
table1 = new JTable(5, 10);
table1.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table1.setTableHeader( null );
table1.setPreferredScrollableViewportSize(table1.getPreferredSize());
JScrollPane scrollPane1 = new JScrollPane( table1 );
scrollPane1.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
// The JTable and the horizontal scrollbar is displayed.
table2 = new JTable(3, 10);
table2.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table2.setTableHeader( null );
System.out.println(table0.getTableHeader());
table2.setPreferredScrollableViewportSize(table2.getPreferredSize());
JScrollPane scrollPane2 = new JScrollPane( table2 );
scrollPane2.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
scrollPane2.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS );
// share the column model with the last two tables
table1.setColumnModel( table0.getColumnModel() );
table2.setColumnModel( table0.getColumnModel() );
// share the scrollbar model with the last two scrollbars
scrollPane1.getHorizontalScrollBar().setModel( scrollPane0.getHorizontalScrollBar().getModel());
scrollPane2.getHorizontalScrollBar().setModel( scrollPane0.getHorizontalScrollBar().getModel());
//  hide the scrollbars of the first two tables.
scrollPane0.getHorizontalScrollBar().setPreferredSize( new Dimension(0, 0) );
scrollPane1.getHorizontalScrollBar().setPreferredSize( new Dimension(0, 0) );
// add components to the panel
tablePanel = new JPanel();
ScrollablePanel tablePanel = new ScrollablePanel();
tablePanel.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
tablePanel.setLayout( new BoxLayout(tablePanel, BoxLayout.Y_AXIS) );
tablePanel.add( scrollPane0 );
tablePanel.add( new JLabel("First Label") );
tablePanel.add( scrollPane1 );
tablePanel.add( new JLabel("Second Label") );
tablePanel.add( scrollPane2 );
JScrollPane scrollPane = new JScrollPane( tablePanel );
scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
add( scrollPane );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TableSharedHeader2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableSharedHeader2());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}

这是在 camickr 的大力帮助和指导下的代码解决方案。

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableSharedHeader2 extends JPanel
{
private JTable table1;
private JTable table2;
private JPanel tablePanel;
TableSharedHeader2()
{
setLayout( new BorderLayout() );
//  Only the Table Header is displayed
JTable table0 = new JTable( 0, 10);
table0.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table0.setPreferredScrollableViewportSize(table0.getPreferredSize());
JScrollPane scrollPane0 = new JScrollPane( table0 );
scrollPane0.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
//  Only the JTable is displayed
table1 = new JTable(5, 10);
table1.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table1.setTableHeader( null );
table1.setPreferredScrollableViewportSize(table1.getPreferredSize());
JScrollPane scrollPane1 = new JScrollPane( table1 );
scrollPane1.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
// The JTable and the horizontal scrollbar is displayed.
table2 = new JTable(60, 10);
table2.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table2.setTableHeader( null );
System.out.println(table0.getTableHeader());
table2.setPreferredScrollableViewportSize(table2.getPreferredSize());
JScrollPane scrollPane2 = new JScrollPane( table2 );
scrollPane2.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
scrollPane2.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
// share the column model with the last two tables
table1.setColumnModel( table0.getColumnModel() );
table2.setColumnModel( table0.getColumnModel() );
// share the scrollbar model with the last two scrollbars
scrollPane1.getHorizontalScrollBar().setModel( scrollPane0.getHorizontalScrollBar().getModel());
scrollPane2.getHorizontalScrollBar().setModel( scrollPane0.getHorizontalScrollBar().getModel());
//  hide the scrollbars of the first two tables.
scrollPane0.getHorizontalScrollBar().setPreferredSize( new Dimension(0, 0) );
scrollPane1.getHorizontalScrollBar().setPreferredSize( new Dimension(0, 0) );
// add components to the panel
tablePanel = new JPanel();
ScrollablePanel tablePanel = new ScrollablePanel();
tablePanel.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
//changed this to stretch for Vertical Scroll Bar to appear if frame is resized and data can not fit in viewport
tablePanel.setScrollableHeight( ScrollablePanel.ScrollableSizeHint.STRETCH );
tablePanel.setLayout( new BoxLayout(tablePanel, BoxLayout.Y_AXIS) );
tablePanel.add( new JLabel("First Label") );
tablePanel.add( scrollPane1 );
tablePanel.add( new JLabel("Second Label") );
tablePanel.add( scrollPane2 );
JScrollPane scrollPane = new JScrollPane( tablePanel );
JScrollBar bar = scrollPane2.getHorizontalScrollBar();
//this removes mouse wheel listeners from all the inner scrollpanes and
//allows the main scrollpane (scrollPane) to react to mousewheel
scrollPane0.removeMouseWheelListener(scrollPane0.getMouseWheelListeners()[0]);
scrollPane1.removeMouseWheelListener(scrollPane1.getMouseWheelListeners()[0]);
scrollPane2.removeMouseWheelListener(scrollPane2.getMouseWheelListeners()[0]);
// Add header to top of border layout
add(scrollPane0,BorderLayout.PAGE_START);
//add main tablePanel which has JTables (no headers) and labels to body of border layout
add( scrollPane,BorderLayout.CENTER );
//add bottom scollpane (scrollpane2) scroll bar to bottom of border layout 
add(bar,BorderLayout.PAGE_END);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TableSharedHeader2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableSharedHeader2());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}

最新更新