Проблема с изменением размера столбцов в двойной JTable - PullRequest
2 голосов
/ 19 апреля 2010

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

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;    
public class FixedRow2Tables extends JFrame    
{  
    private static final long serialVersionUID = 4676303089799270571L;  
    Object[][] data;  
    Object[] column;  
    JTable fixedTable, 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);

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

        JScrollPane scroll = new JScrollPane(table);
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        scroll.setPreferredSize(new Dimension(400, 100));
        getContentPane().add(scroll, BorderLayout.CENTER);
        getContentPane().add(fixedTable, BorderLayout.SOUTH);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                FixedRow2Tables frame = new FixedRow2Tables();
                frame.addWindowListener(new WindowAdapter()
                {
                    public void windowClosing(WindowEvent e)
                    {
                        System.exit(0);
                    }
                });
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Ответы [ 5 ]

2 голосов
/ 19 апреля 2010
fixedTable.setColumnModel(table.getColumnModel());

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

Но, как вы добавили в свой комментарий, вы хотите синхронизировать две таблицы. Я нашел ветку форума, которая охватывает именно эту проблему:

http://forums.sun.com/thread.jspa?threadID=713021

Веселись!

П.С .: На всякий случай пропадает ветка форума (только что скопировал текст):

Сначала подключите столы. Пришлось поделиться ColumnModel, иначе это не сработало. Обе панели имеют поле JTable и методы set и get ColumnModel, делегированные JTable.

infoPanel.setColumnModel(overviewPanel.getColumnModel());
overviewPanel.getColumnModel().addColumnModelListener(infoPanel);    
infoPanel.getColumnModel().addColumnModelListener(overviewPanel);

Затем обработайте событие ChangeEvent:

public void columnMarginChanged(ChangeEvent event) {
    final TableColumnModel eventModel = (DefaultTableColumnModel)event.getSource();
    final TableColumnModel thisModel = getTable().getColumnModel();
    final int columnCount = eventModel.getColumnCount();


    for (int i = 0; i < columnCount; i++) {
      thisModel.getColumn(i).setWidth(eventModel.getColumn(i).getWidth());
    }
    repaint();
}
1 голос
/ 29 июня 2016

Мое решение для этой проблемы (код на Kotlin):

class TableHack(model: TableModel) : JXTable(model) {

    override fun columnMarginChanged(e: ChangeEvent?) {
        repaint();
        return;
    }
}

Используйте эту таблицу в качестве таблицы "summary" и установите ColumnModel из основной таблицы.

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

1 голос
/ 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){}
}
1 голос
/ 10 ноября 2011

Этот код исправил это для меня.

Обратите внимание, что 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 голосов
/ 09 июля 2015

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

package test;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;

import javax.swing.JFrame;
import javax.swing.JScrollBar;
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.TableColumn;
import javax.swing.table.TableColumnModel;

public class FixedRow2Tables extends JFrame
{

    class FixedFooterTable extends JTable {

        private TableColumnModelListener tableColumnModelListener;
        private JTable                   bindedTable;

        FixedFooterTable(Object[][] data, String[] columnNames) {
            super(data, columnNames);
            setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            setCellSelectionEnabled(true);
        }

        public void bindTableModels(final JTable table) {
            this.bindedTable = table;

            if (tableColumnModelListener == null)
                tableColumnModelListener = new TableColumnModelListener() {

                @Override
                public void columnSelectionChanged(ListSelectionEvent e) {
                }

                @Override
                public void columnRemoved(TableColumnModelEvent e) {
                    if (e.getFromIndex() < getColumnCount()) {
                        TableColumn c = getColumnModel().getColumn(e.getFromIndex());
                        getColumnModel().removeColumn(c);
                    }
                }

                @Override
                public void columnMoved(TableColumnModelEvent e) {
                    if (e.getFromIndex() < getColumnCount() && e.getToIndex() < getColumnCount()) {
                        TableColumn c = getColumnModel().getColumn(e.getFromIndex());
                        getColumnModel().moveColumn(e.getFromIndex(), e.getToIndex());
                    }
                }

                @Override
                public void columnMarginChanged(ChangeEvent e) {
                    bindColumnWidths(table.getColumnModel());
                }

                @Override
                public void columnAdded(TableColumnModelEvent e) {
                }

            };

            table.getColumnModel().addColumnModelListener(tableColumnModelListener);

        }

        private void bindColumnWidths(final TableColumnModel columnModel) {
            TableColumnModel fixedColumnModel = getColumnModel();
            Enumeration<TableColumn> enumerator = columnModel.getColumns();

            while (enumerator.hasMoreElements()) {
                TableColumn c = enumerator.nextElement();
                if (c.getModelIndex() >= fixedColumnModel.getColumnCount())
                    break;
                TableColumn destColumn = fixedColumnModel.getColumn(c.getModelIndex());
                System.out.println("columnMarginChanged c" + c.getModelIndex() + " : " + c.getWidth() + " - " + destColumn.getWidth() + " : "
                        + (destColumn.getWidth() - c.getWidth()));
                destColumn.setPreferredWidth(c.getWidth());
                System.out.println("columnMarginChanged c" + c.getModelIndex() + " : " + c.getWidth() + " - " + destColumn.getWidth());
            }
            revalidate();
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        public void bindViews(final JScrollPane scrollPane, final JScrollPane fixedScrollPane) {
            final JScrollBar fixedHorScrollBar = fixedScrollPane.getHorizontalScrollBar();
            final JScrollBar horScrollBar = scrollPane.getHorizontalScrollBar();
            final JScrollBar verScrollBar = scrollPane.getVerticalScrollBar();

            fixedScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
            fixedScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

            horScrollBar.addAdjustmentListener(new AdjustmentListener() {

                @Override
                public void adjustmentValueChanged(AdjustmentEvent e) {
                    fixedHorScrollBar.setValue(e.getValue());
                }
            });

            verScrollBar.addAdjustmentListener(new AdjustmentListener() {

                @Override
                public void adjustmentValueChanged(AdjustmentEvent e) {
                    Dimension d = fixedScrollPane.getSize();
                    Dimension d1 = scrollPane.getSize();
                }
            });
        }

        public JTable getBindedTable() {
            return bindedTable;
        }
    }

    private static final long serialVersionUID = 4676303089799270571L;
    Object[][] data;
    String[]                  columnNames;
    FixedFooterTable          fixedTable;
    JTable                    table;

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

        Object[][] mainData = new Object[][] { { "a", "", "", "", "", "" },
                { "", "b", "", "", "", "" }, { "", "", "c", "", "", "" },
                { "", "", "", "d", "", "" }, { "", "", "", "", "e", "" },
                { "", "", "", "", "", "f" },
                { "a", "b", "c", "d", "e", "f" },
                { "a", "b", "c", "d", "e", "f" },
                { "a", "b", "c", "d", "e", "f" },
                { "a", "b", "c", "d", "e", "f" },
                { "a", "b", "c", "d", "e", "f" } };
        Object[][] summaryData = { { "fixed1", "", "", "", "", "" },
                { "fixed2", "b", "c", "d", "e", "f" } };
        columnNames = new String[] { "Ala", "Bardzo", "Chciala", "Dostac", "Eskimoska", "Franciszki Genowefy Pigwy" };

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


        fixedTable = new FixedFooterTable(summaryData, columnNames);
        fixedTable.setTableHeader(null);

        final JScrollPane scroll = new JScrollPane(table);
        final JScrollPane fixedscroll = new JScrollPane(fixedTable);

        Dimension preferredSize = fixedTable.getPreferredSize();
        fixedscroll.setPreferredSize(preferredSize);

        fixedTable.bindTableModels(table);
        fixedTable.bindViews(scroll, fixedscroll);

        getContentPane().add(scroll, BorderLayout.CENTER);
        getContentPane().add(fixedscroll, 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);
            }
        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...