多个 JTable 相互叠加,就像一个 JTable
Multiple JTables on top of each other acting like one JTable
我想要 x 个 JTables 在彼此之上,就像一个 JTable 一样。我创建了 x 个单独的 JScollPanes - 每个 table 一个,并将它们全部插入到一个 JPanel (panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
) 中。
我只显示最顶部 table 的 header。为了使它们一致地水平滚动,我使用了 here.
我还需要完成两个任务才能实现它看起来像一个大 JTable 的预期结果。
我希望只有一个垂直滚动条?如何实现?
我希望所有 table 共享同一个 TableColumnModel 作为最上面的 table(这是唯一显示 header 的)因此,如果通过拖放 header 移动列,则所有 table 都会反映更改...
如果有人想知道,我以前尝试将每个 JTable 添加到一个 JPanel,然后将每个 JPanel 添加到一个 JScrollPane。该解决方案的问题是,如果其中一个 JTable 有很多条目,垂直滚动条将不会显示所有条目....
基于这个问题和你其他问题的图片,我可能有一个方法,虽然它有点 hack。
方法:
创建多个 table 并将它们添加到 JScrollPane。使用 BoxLayout
将每个滚动窗格添加到面板
第一个滚动窗格将包含并清空 table,因此只有 table header 在滚动窗格中可见。
最后一个滚动窗格将显示 JTable 和水平滚动条。
第一个和最后一个之间的任何滚动窗格将只显示 JTable。
代码使用自定义 ScrollablePanel
。此面板将强制面板的宽度等于视口的宽度。这将反过来强制每个滚动窗格的水平滚动条处于活动状态。每个水平滚动条共享相同的模型,因此即使只有一个滚动条可见,所有 table 也会同时滚动。
查看 Scrollable Panel 下载代码。
这里是代码:
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();
}
});
*/
}
}
我想要 x 个 JTables 在彼此之上,就像一个 JTable 一样。我创建了 x 个单独的 JScollPanes - 每个 table 一个,并将它们全部插入到一个 JPanel (panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
) 中。
我只显示最顶部 table 的 header。为了使它们一致地水平滚动,我使用了 here.
我还需要完成两个任务才能实现它看起来像一个大 JTable 的预期结果。
我希望只有一个垂直滚动条?如何实现?
我希望所有 table 共享同一个 TableColumnModel 作为最上面的 table(这是唯一显示 header 的)因此,如果通过拖放 header 移动列,则所有 table 都会反映更改...
如果有人想知道,我以前尝试将每个 JTable 添加到一个 JPanel,然后将每个 JPanel 添加到一个 JScrollPane。该解决方案的问题是,如果其中一个 JTable 有很多条目,垂直滚动条将不会显示所有条目....
基于这个问题和你其他问题的图片,我可能有一个方法,虽然它有点 hack。
方法:
创建多个 table 并将它们添加到 JScrollPane。使用 BoxLayout
将每个滚动窗格添加到面板
第一个滚动窗格将包含并清空 table,因此只有 table header 在滚动窗格中可见。
最后一个滚动窗格将显示 JTable 和水平滚动条。
第一个和最后一个之间的任何滚动窗格将只显示 JTable。
代码使用自定义
ScrollablePanel
。此面板将强制面板的宽度等于视口的宽度。这将反过来强制每个滚动窗格的水平滚动条处于活动状态。每个水平滚动条共享相同的模型,因此即使只有一个滚动条可见,所有 table 也会同时滚动。
查看 Scrollable Panel 下载代码。
这里是代码:
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();
}
});
*/
}
}