Строка нижнего колонтитула в JTable - PullRequest
4 голосов
/ 11 июня 2009

Каков наилучший способ поместить строку нижнего колонтитула в JTable? У кого-нибудь есть пример кода для этого?

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


Вот что я закончил:

JTable mainTable = new JTable(mainTableModel);
JTable footerTable = new JTable(footerModel);
footerTable.setColumnModel(mainTable.getColumnModel());

// Disable selection in the footer. Otherwise you can select the footer row
// along with a row in the table and that can look quite strange.
footerTable.setRowSelectionAllowed(false);
footerTable.setColumnSelectionAllowed(false);

JPanel tablePanel = new JPanel();
BoxLayout boxLayout = new BoxLayout(tablePanel, BoxLayout.Y_AXIS);
tablePanel.setLayout(boxLayout);
tablePanel.add(mainTable.getTableHeader()); // This seems like a bit of a WTF
tablePanel.add(mainTable);
tablePanel.add(footerTable);

Сортировка работает нормально, но выбор строки нижнего колонтитула немного странный.

Ответы [ 8 ]

5 голосов
/ 11 июня 2009

Попробуйте использовать вторую JTable, которая использует ту же модель столбца, что и ваша таблица данных, и добавьте в нее данные нижнего колонтитула. Добавьте вторую (нижнюю) нижнюю таблицу под исходной таблицей.

JTable footer = new JTable(model, table.getColumnModel());
panel.add(BorderLayout.CENTER, table);
panel.add(BorderLayout.SOUTH, footer);
2 голосов
/ 24 августа 2012

Похоже, что проект имеет компонент с именем JideScrollPane, который объявляет о поддержке нижнего колонтитула строки. Я сам не пробовал, но похоже, что он делает именно то, что вы хотите! На сайте также есть демонстрационное приложение, в котором вы можете увидеть его в действии, и оно выглядит довольно неплохо.

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

1 голос
/ 11 ноября 2011

Хороший подход - использовать 2 таблицы друг под другом.

Если вы хотите иметь возможность изменять размер / перемещать / удалять столбцы, ключ НЕ должен повторно использовать одну и ту же columnModel между таблицами. Попросите слушателя изменить размер. Смотрите пример:

package snippet;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.TableColumnModel;

public class FixedRow2Tables extends JFrame {
    private static final long serialVersionUID = 4676303089799270571L;
    Object[][] data;
    Object[] column;
    JTable footerTable, table;

    public FixedRow2Tables() {
        super("Fixed Row Example");

        Object[][] mainData = new Object[][] { { "a", "", "", "", "", "" },
                { "", "b", "", "", "", "" }, { "", "", "c", "", "", "" },
                { "", "", "", "d", "", "" }, { "", "", "", "", "e", "" },
                { "", "", "", "", "", "f" } };
        Object[][] summaryData = { { "fixed1", "", "", "", "", "" },
                { "fixed2", "", "", "", "", "" } };
        column = new Object[] { "A", "B", "C", "D", "E", "F" };

        table = new JTable(mainData, column);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        footerTable = new JTable(summaryData, column);
        footerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        footerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        footerTable.setTableHeader(null);
        // footerTable.setColumnModel(table.getColumnModel());

        table.getColumnModel().addColumnModelListener(
                new TableColumnModelListener() {

                    @Override
                    public void columnSelectionChanged(ListSelectionEvent e) {
                    }

                    @Override
                    public void columnRemoved(TableColumnModelEvent e) {
                    }

                    @Override
                    public void columnMoved(TableColumnModelEvent e) {
                    }

                    @Override
                    public void columnMarginChanged(ChangeEvent e) {
                        final TableColumnModel tableColumnModel = table
                                .getColumnModel();
                        TableColumnModel footerColumnModel = footerTable
                                .getColumnModel();
                        for (int i = 0; i < tableColumnModel.getColumnCount(); i++) {
                            int w = tableColumnModel.getColumn(i).getWidth();
                            footerColumnModel.getColumn(i).setMinWidth(w);
                            footerColumnModel.getColumn(i).setMaxWidth(w);
                            // footerColumnModel.getColumn(i).setPreferredWidth(w);
                        }
                        footerTable.doLayout();
                        footerTable.repaint();
                        repaint();
                    }

                    @Override
                    public void columnAdded(TableColumnModelEvent e) {
                    }
                });

        JScrollPane scroll = new JScrollPane(table);
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scroll.setPreferredSize(new Dimension(400, 100));
        getContentPane().add(scroll, BorderLayout.CENTER);
        getContentPane().add(footerTable, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                FixedRow2Tables frame = new FixedRow2Tables();
                frame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.exit(0);
                    }
                });
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
0 голосов
/ 29 сентября 2014
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;

class Application extends JFrame
{
    public Application()
    {
        this.setBounds(100,100,500,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        String data[][] = {{"a1","b1","c1"},{"a2","b2","c2"},{"a3","b3","c3"}};
        String columnNames[] = {"a","b","c"};

        JTable jtable = new JTable(new DefaultTableModel(data,columnNames));

        JScrollPane jscrollPane = new JScrollPane(jtable,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        jscrollPane.setBorder(new CompoundBorder(new MatteBorder(0,0,1,0,Color.gray),new EmptyBorder(0,0,0,0)));

        this.add(jscrollPane,BorderLayout.CENTER);


        JTable jtable_footer = new JTable(new DefaultTableModel(3,columnNames.length),jtable.getColumnModel());

        SyncListener syncListener = new SyncListener(jtable,jtable_footer);

        this.add(jtable_footer,BorderLayout.SOUTH);
    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Application application = new Application();

                application.setVisible(true);
            }
        });
    }
}

class SyncListener implements TableColumnModelListener
{
    JTable jtable_data;
    JTable jtable_footer;

    public SyncListener(JTable main, JTable footer)
    {
        jtable_data = main;
        jtable_footer = footer;

        DefaultTableColumnModel dtcm = (DefaultTableColumnModel)jtable_data.getColumnModel();

        dtcm.removeColumnModelListener(dtcm.getColumnModelListeners()[1]);
        dtcm.addColumnModelListener(this);
    }

    public void columnMarginChanged(ChangeEvent changeEvent)
    {
        for (int column = 0; column < jtable_data.getColumnCount(); column++)
        {
            jtable_footer.getColumnModel().getColumn(column).setWidth(jtable_data.getColumnModel().getColumn(column).getWidth());
        }

        jtable_footer.repaint();
    }

    public void columnAdded(TableColumnModelEvent e){}
    public void columnMoved(TableColumnModelEvent e){}
    public void columnRemoved(TableColumnModelEvent e){}
    public void columnSelectionChanged(ListSelectionEvent e){}
}
0 голосов
/ 18 декабря 2009

Вот еще одно решение, упомянутое в базе данных ошибок Java

Решение, которое работает для меня, это нарисовать границу для области просмотра (ваш JTable должен быть внутри JScrollPane) ....

0 голосов
/ 11 июня 2009

Полагаю, что лучший подход (но, конечно, не самый простой) заключается в том, чтобы взглянуть на исходный код компонента JTableHeader, посмотреть, как он работает, а затем создать собственный компонент JTableFooter. Вы можете повторно использовать делегат пользовательского интерфейса JTableHeader для нижнего колонтитула, я думаю, что основные различия будут заключаться в методе getHeaderRect(), где он определяет границы данной плитки заголовка столбца.

0 голосов
/ 11 июня 2009

Вы можете попробовать реализовать свой собственный TableCellRenderer , который заменяет отображаемый контент последней видимой строки на ваш нижний колонтитул. Однако это не будет исправлено в нижней части таблицы, скорее всего, вы будете перемещаться вверх и вниз при прокрутке.

0 голосов
/ 11 июня 2009

Единственный раз, когда я сделал это, я просто добавил в модель строку примерно так:

    @Override
    public int getRowCount() {
        return _tableContents.size() + 1;
    }

_tableContents - это, конечно, фактические данные за моей моделью. Вам, конечно, нужно знать о дополнительной строке в модели (в таких вызовах, как setValueAt (...))

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...