简体   繁体   中英

How can i create two Jtables which have same Columnmodel, but they have different models

I design two jtables who have same columnmodel , so they resize accordingly, these two jtables should have same column number, i want them to behave in the same manner, when we resize columns or change scrollbar. now i have problem that when i resize second table, columns on rows does not change their size and scrollbars do not behave accordingly.

My code is like that

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.JScrollPane;

public class CompFilteredTable extends JPanel{
    private JTable tblFilter;
    private JTable tblData;
    private JScrollPane scrollPane;
    private JScrollPane scrollPane_1;
    public CompFilteredTable() {
        setLayout(new BorderLayout(0, 0));
        add(getScrollPane_1(), BorderLayout.NORTH);
        add(getScrollPane(), BorderLayout.CENTER);
    }



    public JTable getTblFilter() {
        if (tblFilter == null) {
            tblFilter = new MyTable(new TestTableModel2());
            tblFilter.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            tblFilter.setTableHeader (null);
        }
        return tblFilter;
    }
    public JTable getTblData() {
        if (tblData == null) {
            tblData = new MyTable(new TestTableModel());
            tblData.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

            tblFilter.setColumnModel(tblData.getColumnModel());
        }   
        return tblData;
    }

    private class MyTable extends JTable {
        private MyTable (final TableModel model) {
            super (model);
        }

        private boolean isColumnMarginChangeInProgress=false;
        @Override
        public void columnMarginChanged(final ChangeEvent e) {
            if (isColumnMarginChangeInProgress) {
                return;
            }
            isColumnMarginChangeInProgress = true;

            if (isEditing()) {
                removeEditor();
            }
            TableColumn resizingColumn = null;
            if (tableHeader != null) {
                resizingColumn = tableHeader.getResizingColumn();
            }
            if (resizingColumn != null) {
                if (autoResizeMode == AUTO_RESIZE_OFF) {
                    resizingColumn.setPreferredWidth(resizingColumn.getWidth());
                } else {    // this else block is missing in jdk1.4 as compared to 1.3
                    doLayout();
                    repaint();
                }
            } else {
                resizeAndRepaint();
            }
            isColumnMarginChangeInProgress = false;
        }
    }



    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(600, 400));

        CompFilteredTable compFilteredTable = new CompFilteredTable();

        frame.getContentPane().add(compFilteredTable);
        frame.pack();
        frame.setVisible(true);

    }

    private class TestTableModel extends DefaultTableModel {
        @Override
        public int getRowCount () {
            return 10;
        }
        @Override
        public int getColumnCount () {
            return 10;
        }
        @Override
        public String getColumnName (final int column) {
            return "Col-"+column;
        }

        @Override
        public Object getValueAt (final int row, final int column) {
            return (row * column) + "";
        }
    }

    private class TestTableModel2 extends DefaultTableModel {
        @Override
        public int getRowCount () {
            return 1;
        }
        @Override
        public int getColumnCount () {
            return 10;
        }
        @Override
        public String getColumnName (final int column) {
            return "Col-"+column;
        }

        @Override
        public Object getValueAt (final int row, final int column) {
            return (row * column) + "";
        }
    }



    private JScrollPane getScrollPane() {
        if (scrollPane == null) {
            scrollPane = new JScrollPane();
            scrollPane.setViewportView(getTblData());
        }
        return scrollPane;
    }
    private JScrollPane getScrollPane_1() {
        if (scrollPane_1 == null) {
            scrollPane_1 = new JScrollPane();
            scrollPane_1.setViewportView(getTblFilter());
        }
        return scrollPane_1;
    }
}

Updated Code after the contribution deepak ( i dont know how can i show my updates, therefore i added below )

i updated code , now there are two problems that are seen on the picture. header of the second table is not seen , and there is a big gap between tables.

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.JScrollPane;
import java.awt.GridLayout;

public class CompFilteredTable extends JPanel{
    private JTable tblFilter;
    private JTable tblData;
    private JScrollPane scrollPane;
    private JPanel panel;

    public CompFilteredTable() {
        setLayout(new BorderLayout(0, 0));
        add(getScrollPane(), BorderLayout.CENTER);
    }


    public JTable getTblFilter() {
        if (tblFilter == null) {
            tblFilter = new MyTable(new TestTableModel2());
            tblFilter.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            tblFilter.setTableHeader (null);
        }
        return tblFilter;
    }
    public JTable getTblData() {
        if (tblData == null) {
            tblData = new MyTable(new TestTableModel());
            tblData.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

            tblFilter.setColumnModel(tblData.getColumnModel());
        }   
        return tblData;
    }

    private class MyTable extends JTable {
        private MyTable (final TableModel model) {
            super (model);
        }

        private boolean isColumnMarginChangeInProgress=false;
        @Override
        public void columnMarginChanged(final ChangeEvent e) {
            if (isColumnMarginChangeInProgress) {
                return;
            }
            isColumnMarginChangeInProgress = true;

            if (isEditing()) {
                removeEditor();
            }
            TableColumn resizingColumn = null;
            if (tableHeader != null) {
                resizingColumn = tableHeader.getResizingColumn();
            }
            if (resizingColumn != null) {
                if (autoResizeMode == AUTO_RESIZE_OFF) {
                    resizingColumn.setPreferredWidth(resizingColumn.getWidth());
                } else {    // this else block is missing in jdk1.4 as compared to 1.3
                    doLayout();
                }
                repaint();
            } else {
                resizeAndRepaint();
            }
            isColumnMarginChangeInProgress = false;
        }
    }



    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(600, 400));

        CompFilteredTable compFilteredTable = new CompFilteredTable();

        frame.getContentPane().add(compFilteredTable);
        frame.pack();
        frame.setVisible(true);

    }

    private class TestTableModel extends DefaultTableModel {
        @Override
        public int getRowCount () {
            return 10;
        }
        @Override
        public int getColumnCount () {
            return 10;
        }
        @Override
        public String getColumnName (final int column) {
            return "Col-"+column;
        }

        @Override
        public Object getValueAt (final int row, final int column) {
            return (row * column) + "";
        }
    }

    private class TestTableModel2 extends DefaultTableModel {
        @Override
        public int getRowCount () {
            return 1;
        }
        @Override
        public int getColumnCount () {
            return 10;
        }
        @Override
        public String getColumnName (final int column) {
            return "Col-"+column;
        }

        @Override
        public Object getValueAt (final int row, final int column) {
            return (row * column) + "";
        }
    }

    private JScrollPane getScrollPane() {
        if (scrollPane == null) {
            scrollPane = new JScrollPane();
            scrollPane.setViewportView(getPanel());
        }
        return scrollPane;
    }

    private JPanel getPanel() {
        if (panel == null) {
            panel = new JPanel();
            panel.setLayout(new GridLayout(2, 1, 0, 0));
            panel.add(getTblFilter());
            panel.add(getTblData());
        }
        return panel;
    }

}

the output screen

表输出

Setting the preferred width of the TableColumn using the method setPreferredWidth on the columnMarginChanged event will update the JTableHeader component. So the table header is getting resized as observed. An explicit call to repaint() after setting the desired properties will trigger the changes to be applied on each of the components of the table as well.

So here is the change required to make this behave as you expect it to.

            if (autoResizeMode == AUTO_RESIZE_OFF) {
                resizingColumn.setPreferredWidth(resizingColumn.getWidth());
                repaint();
            } else {    // this else block is missing in jdk1.4 as compared to 1.3

Also, repaint() can be moved out of the conditional block as well.

Problem 1 : header of the second table is not seen.

Why : The table header is being set to null as seen in the code posted.

    public JTable getTblFilter() {
        if (tblFilter == null) {
            tblFilter = new MyTable(new TestTableModel2());
            tblFilter.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            tblFilter.setTableHeader (null);
        }
        return tblFilter;
    }

Solution is to not set the table header to null. Removing part of the code tblFilter.setTableHeader (null); should work.

Problem 2: there is a big gap between tables.

There are different LayoutManagers available which can be used to design the UI as per your need. Using GridLayout with 2 rows and 1 column should help here.

    public CompFilteredTable() {
        setLayout(new GridLayout(2, 1));
        add(getScrollPane_1());
        add(getScrollPane());
    }

这是工作程序

Single JTable can be added to a single JScrollPane to solve the problem of table headers not showing up in the UI.

To manage the gap between the tables, GridBagLayout can be of help. GridBagLayout is the most flexible layout manager class.The object of GridBagLayout aligns the component vertically,horizontally or along their baseline without requiring the components of same size.

I solved all my problems, there is a little gap between tables. I want to use this as a component to filter table according to value from the upper table. Is there any improvement for this component ? maybe filtered functions can be added to this component.

Output screen of the component :

过滤表

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

public class CompFilteredTable extends JPanel{
    private JTable tblFilter;
    private JTable tblData;
    private JScrollPane scrollPane;
    private JPanel panel;
    private JScrollPane scrollPane_1;
    private JScrollPane scrollPane_2;

    public CompFilteredTable() {
        setLayout(new BorderLayout(0, 0));
        add(getScrollPane(), BorderLayout.CENTER);
    }


    public JTable getTblFilter() {
        if (tblFilter == null) {
            tblFilter = new FilteredTable(new TestTableModel2());
            tblFilter.setPreferredScrollableViewportSize(new Dimension(0, 0));
            tblFilter.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            tblFilter.setTableHeader (null);

        }
        return tblFilter;
    }
    public JTable getTblData() {
        if (tblData == null) {
            tblData = new FilteredTable(new TestTableModel());
            tblData.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

            tblFilter.setColumnModel(tblData.getColumnModel());
        }   
        return tblData;
    }


    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(600, 400));

        CompFilteredTable compFilteredTable = new CompFilteredTable();

        frame.getContentPane().add(compFilteredTable);
        frame.pack();
        frame.setVisible(true);

    }

    private class TestTableModel extends DefaultTableModel {
        @Override
        public int getRowCount () {
            return 10;
        }
        @Override
        public int getColumnCount () {
            return 10;
        }
        @Override
        public String getColumnName (final int column) {
            return "Col-"+column;
        }

        @Override
        public Object getValueAt (final int row, final int column) {
            return (row * column) + "";
        }
    }

    private class TestTableModel2 extends DefaultTableModel {
        @Override
        public int getRowCount () {
            return 1;
        }
        @Override
        public int getColumnCount () {
            return 10;
        }
        @Override
        public String getColumnName (final int column) {
            return "Col-"+column;
        }

        @Override
        public Object getValueAt (final int row, final int column) {
            return (row * column) + "";
        }
    }

    private JScrollPane getScrollPane() {
        if (scrollPane == null) {
            scrollPane = new JScrollPane();
            scrollPane.setViewportView(getPanel());
        }
        return scrollPane;
    }

    private JPanel getPanel() {
        if (panel == null) {
            panel = new JPanel();
            panel.setLayout(new BorderLayout(0, 0));
            panel.add(getScrollPane_2(), BorderLayout.NORTH);
            panel.add(getScrollPane_1());
        }
        return panel;
    }



    private JScrollPane getScrollPane_1() {
        if (scrollPane_1 == null) {
            scrollPane_1 = new JScrollPane();
            scrollPane_1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
            scrollPane_1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
            scrollPane_1.setViewportView(getTblData());
            Dimension d = tblData.getPreferredSize();
            scrollPane_1.setPreferredSize(new Dimension(d.width,tblData.getRowHeight()*tblData.getRowCount()+1));

        }
        return scrollPane_1;
    }
    private JScrollPane getScrollPane_2() {
        if (scrollPane_2 == null) {
            scrollPane_2 = new JScrollPane();
            scrollPane_2.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
            scrollPane_2.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
            scrollPane_2.setViewportView(getTblFilter());
            Dimension d = tblFilter.getPreferredSize();
            scrollPane_2.setPreferredSize(new Dimension(d.width,tblFilter.getRowHeight()*tblFilter.getRowCount()+1));

        }
        return scrollPane_2;
    }
}

class FilteredTable extends JTable {

    FilteredTable (final TableModel model) {
        super (model);
    }

    private boolean isColumnMarginChangeInProgress=false;
    @Override
    public void columnMarginChanged(final ChangeEvent e) {
        if (isColumnMarginChangeInProgress) {
            return;
        }
        isColumnMarginChangeInProgress = true;

        if (isEditing()) {
            removeEditor();
        }
        TableColumn resizingColumn = null;
        if (tableHeader != null) {
            resizingColumn = tableHeader.getResizingColumn();
        }
        if (resizingColumn != null) {
            if (autoResizeMode == AUTO_RESIZE_OFF) {
                resizingColumn.setPreferredWidth(resizingColumn.getWidth());
            } else {    // this else block is missing in jdk1.4 as compared to 1.3
                doLayout();
            }
            repaint();
        } else {
            resizeAndRepaint();
        }
        isColumnMarginChangeInProgress = false;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM