Reputation: 3
I'd like to have x JTables on top of each other acting like one JTable. I have created x separate JScollPanes - one for each table and inserted them all into one JPanel (panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
).
I only show the header for the top most table. In order to achieve them scrolling horizontally in unison, I have used here.
I need two more tasks left to achieve the desired result of it looking like one big JTable.
I'd like there to only be one vertical scroll bar? How to achieve this?
I'd like all tables to share the same TableColumnModel as the top most table (which is the only one that shows the header) so if a column is moved via drag drop header, all tables reflect the change...
In case anyone is wondering, I previously tried to add each JTable to a JPanel and then add each JPanel to one JScrollPane. The problem with that solution is that if one of the JTable's has many entries, a vertical scroll bar won't appear to show all the entries....
Upvotes: 0
Views: 542
Reputation: 3
Here is the code solution after great help and guidance from 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();
}
});
*/
}
}
Upvotes: 0
Reputation: 324108
Based on this question and pictures from your other questions I might have an approach, although it is a bit of a hack.
The approach:
Create multiple tables and add them to a JScrollPane. Add each scroll pane to the panel using the BoxLayout
The first scroll pane will contain and empty table so only the table header will be visible in the scroll pane.
The last scroll pane will display the JTable and the horizontal scrollbar.
Any scroll pane between the first and last will only display the JTable.
The code uses a custom ScrollablePanel
. This panel will force the width of the panel to be equal to the width of the viewport. This will in turn force the horizontal scroll bars of each scroll pane to be active. Each horizontal scrollbar shares the same model, so even though only one scrollbar is visible all tables will scroll at the same time.
Check out Scrollable Panel for the code to download.
Here the code:
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();
}
});
*/
}
}
Upvotes: 1