Несколько JTables друг над другом действуют как один JTable - PullRequest
0 голосов
/ 27 мая 2020

Я бы хотел, чтобы x JTables располагались друг над другом, как один JTable. Я создал x отдельных JScollPanes - по одному для каждой таблицы и вставил их все в одну JPanel (panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));).

Я показываю только заголовок для самой верхней таблицы. Чтобы добиться их одновременной горизонтальной прокрутки, я использовал здесь .

Мне нужно еще две задачи, чтобы достичь желаемого результата, чтобы он выглядел как одна большая JTable.

  1. Я бы хотел, чтобы была только одна вертикальная полоса прокрутки? Как этого добиться?

  2. Я бы хотел, чтобы все таблицы использовали одну и ту же модель TableColumnModel, что и самая верхняя таблица (которая является единственной, которая показывает заголовок), поэтому, если столбец перемещается через заголовок перетаскивания, все таблицы отражают изменение ...

Если кому-то интересно, я ранее пытался добавить каждую JTable в JPanel, а затем добавить каждую JPanel в одну JScrollPane. Проблема с этим решением заключается в том, что если в одной из таблиц JTable много записей, вертикальная полоса прокрутки не будет отображать все записи ....

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Основываясь на этом вопросе и изображениях из других ваших вопросов, у меня может быть подход, хотя это немного похоже на взлом.

Подход:

  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();
            }
        });
*/
    }
}
0 голосов
/ 28 мая 2020

Вот решение кода после большой помощи и рекомендаций 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();
            }
        });
*/
    }
}
...