简体   繁体   English

我如何创建两个具有相同Columnmodel但具有不同模型的Jtables

[英]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. 我设计了两个具有相同columnmodel的jtable,因此它们会相应地调整大小,这两个jtable应该具有相同的列号,当我们调整列大小或更改滚动条时,我希望它们以相同的方式表现。 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 ) 贡献Deepak之后更新了代码 (我不知道如何显示我的更新,因此在下面添加了)

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. 使用columnMarginChanged事件上的setPreferredWidth方法设置TableColumn的首选宽度将更新JTableHeader组件。 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. 设置所需的属性后,显式调用repaint()也会触发将更改应用于表的每个组件。

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. 同样, repaint()也可以移出条件块。

Problem 1 : header of the second table is not seen. 问题1:看不到第二个表的标题。

Why : The table header is being set to null as seen in the code posted. 原因:如表中的代码所示,表头被设置为null

    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. 解决方案是不要将表头设置为null。 Removing part of the code tblFilter.setTableHeader (null); 删除部分代码tblFilter.setTableHeader (null); should work. 应该管用。

Problem 2: there is a big gap between tables. 问题2:表格之间的差距很大。

There are different LayoutManagers available which can be used to design the UI as per your need. 有各种可用的LayoutManager,可用于根据需要设计UI。 Using GridLayout with 2 rows and 1 column should help here. 在这里使用带有2行1列的GridLayout应该会有所帮助。

    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. 可以将单个JTable添加到单个JScrollPane中,以解决表头未在UI中显示的问题。

To manage the gap between the tables, GridBagLayout can be of help. 要管理表之间的间隙,GridBagLayout会有所帮助。 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. GridBagLayout是最灵活的布局管理器类。GridBagLayout的对象使组件垂直,水平或沿其基线对齐, 而不需要相同大小的组件。

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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 相同的数据集,两个不同的JTable - Same dataset, two different JTables Java:显示从同一AbstractTableModel创建的两个不同的JTable - Java: Display two different JTables which are created from the same AbstractTableModel 我怎样才能让 JooQ 联合两个不同的表,它们具有相同的列和数据类型? - How can I have JooQ union two different tables, that have the same columns and datatypes? 如何同时工作具有相同优先级的两个不同线程? - How to work concurrently two different threads which have the same priority? 如何解析具有相同名称但父母不同的两个节点? - How do I resolve two nodes which have the same name but under different parents? 如何使用具有不同命名空间和相同JAXB类的两个不同端点? - How can I have two different endpoint with different namespace and same JAXB class? 我有两种几乎相同的方法,如何重构它们? - I have two methods which are nearly the same, how to refactor them? Maven:如何在两个不同的模块下有一个同名的模块? - Maven: How can I have a module with same name under two different modules? 购买两个相同但组件顺序不同的混合数字时,如何返回 true? - How can I return true when buying two mixed figures that are the same but have the components in a different order? 我有两个使用 @EnableScheduling 的不同类,但它们使用相同的执行程序服务 - I have two different classes which uses @EnableScheduling but they are using same executor service
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM