在其旁边的另一个JTable上继续JTable数据而不是滚动

时间:2018-01-29 16:23:10

标签: java swing jtable jscrollpane

我有一个显示超过200行的JTable。我想在JPanel中显示所有行,以便用户不必向下滚动。

我试图在我的第一个表中获取可见行的数量,并使用视口添加另一个具有剩余行的JTable,如https://coderanch.com/t/340707/java/find-visible-row-count- JTable。
但是,该方法仅在绘制面板并对用户可见后才返回可见行数。所以我不能动态地将另一个JTable添加到同一个面板。

以下是我用来实现上述要求的代码,但只有在单击按钮时才会添加新表。我尝试根据lastTable中的可见行动态添加表,但如上所述,在表格出现在视口中之前,我没有得到正确的可见行数。


    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.List;

    import javax.swing.BoxLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JViewport;
    import javax.swing.ScrollPaneConstants;
    import javax.swing.table.AbstractTableModel;

    public class DataPanel  extends JPanel{

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        List data = new ArrayList();
        JScrollPane scrollPane;
        JTable table, lastTable;
        JPanel boxPanel;
        int rows = 0;

        public DataPanel()
        {
            for (int i = 0; i  newData = getData(rows);
                DataModel newModel = new DataModel(newData);
                JTable newTable = new JTable(newModel);
                lastTable = newTable;
                JScrollPane newScrollPane = new JScrollPane(newTable);
                newScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
                boxPanel.add(newScrollPane);
            }
        }

        private List getData(int rows) {
            // TODO Auto-generated method stub
            List newData = new ArrayList();
            for(int i=0; i= rows)
                {
                    newData.add(data.get(i));
                }
            }
            return newData;
        }

        private int getVisibleRowCount(JTable table)
        {
            JViewport viewport = (JViewport) table.getParent();
            Dimension extentSize = viewport.getExtentSize();     // JViewport
            int visibleRows = extentSize.height/table.getRowHeight();
            return visibleRows;
        }

        public static void main(String args[])
        {
            new DataPanel();
        }

        private class DataModel extends AbstractTableModel{

            static final int COL1_INDEX = 0;
            static final int COL2_INDEX = 1;

            private final String[] COLUMN_NAMES = new String[]
                    {"ID", "Name"};

            private List data = new ArrayList();

            public DataModel(List newData)
            {
                data = newData;
            }

            public List getData() {
                return data;
            }

            public void setData(List data) {
                this.data = data;
            }

            @Override
            public int getColumnCount() {
                // TODO Auto-generated method stub
                return COLUMN_NAMES.length;
            }

            @Override
            public int getRowCount() {
                // TODO Auto-generated method stub
                if (null == data)
                    return 0;
                return data.size();
            }

            @Override
            public Object getValueAt(int row, int col) {
                // TODO Auto-generated method stub
                System.out.println("Requesting Row :" + row + " and Column : " + col);
                if (col == COL1_INDEX)
                {
                    return row;
                }else
                {
                    return data.get(row);
                }
            }

            @Override
            public String getColumnName(int column) {
                // TODO Auto-generated method stub
                return COLUMN_NAMES[column];
            }

        }

    }

非常感谢您解决此问题的任何帮助。提前谢谢。

Horizontally Flowing JTable

1 个答案:

答案 0 :(得分:0)

我找到了解决上述问题的方法。我已经为框架添加了一个组件监听器,每当它的大小发生变化时,我就会遍历这些表并更改这些表的DataModel以仅显示可见的行。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.table.AbstractTableModel;

public class DataPanel  extends JPanel{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final int ROW_HEIGHT = 18;

    List<String> data = new ArrayList<String>();
    List<JTable> tables = new ArrayList<JTable>();
    JScrollPane scrollPane;
    JTable table, lastTable;
    JPanel boxPanel;
    JFrame f;
    int rows = 0;

    public DataPanel()
    {
        for (int i = 0; i < 50; i++)
            data.add("Blah " + i);
        DataModel tableData = new DataModel(data);
        tableData.setData(data);
        setLayout(new BorderLayout());
        /*JButton btn = new JButton("Action");
        btn.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                addTable();
            }

        });
        add(btn, BorderLayout.NORTH);*/
        boxPanel = new JPanel();
        boxPanel.setLayout(new BoxLayout(boxPanel, BoxLayout.X_AXIS));
        addTable();
        add(boxPanel, BorderLayout.CENTER);
        f = new JFrame();
        f.getContentPane().add(this);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(500,500);
        f.setVisible(true);
        f.addComponentListener(adapter);
    }

    protected void addTable() {
        // TODO Auto-generated method stub
        while (rows < data.size())
        {
            System.out.println("Querying " + rows);
            List<String> newData = getData(rows);
            rows += getVisibleRowCount();
            DataModel newModel = new DataModel(newData);
            JTable newTable = new JTable(newModel);
            lastTable = newTable;
            newTable.setRowHeight(ROW_HEIGHT);
            JScrollPane newScrollPane = new JScrollPane(newTable);
            tables.add(newTable);
            newScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
            boxPanel.add(newScrollPane);
            System.out.println("Now " + rows);
        }
    }

    private ComponentAdapter adapter = new ComponentAdapter()
    {

        @Override
        public void componentResized(ComponentEvent arg0) {
            // TODO Auto-generated method stub
            //super.componentResized(arg0);
            rows = 0;
            for (JTable eachTable : tables)
            {
                List<String> newData = getData(rows);
                rows += getVisibleRowCount();
                DataModel newModel = new DataModel(newData);
                eachTable.setModel(newModel);
                ((DataModel)eachTable.getModel()).fireTableDataChanged();
            }
        }

    };

    private List<String> getData(int rows) {
        // TODO Auto-generated method stub
        List<String> newData = new ArrayList<String>();
        int j = 0;
        for(int i=0; i<data.size() && j < getVisibleRowCount(); i++)
        {
            if (i >= rows)
            {
                newData.add(data.get(i));
                j++;
            }
        }
        return newData;
    }

    private int getVisibleRowCount()
    {
        Dimension extentSize = null;
        int visibleRows = 12;
        if (null != f)
        {
            extentSize = f.getSize();
            visibleRows = (extentSize.height - 50)/ROW_HEIGHT;
        }
        return visibleRows;
    }

    public static void main(String args[])
    {
        new DataPanel();
    }

    private class DataModel extends AbstractTableModel{

        static final int COL1_INDEX = 0;
        static final int COL2_INDEX = 1;

        private final String[] COLUMN_NAMES = new String[]
                //LM2 - B & O abbreviations to be replaced by B & S. - HP   17e9355d63
                //LM2 - brokers should be able to see trader names in the order panel - HP  e4fbaa791a
                {"ID", "Name"};

        private List<String> data = new ArrayList<String>();

        public DataModel(List<String> newData)
        {
            data = newData;
        }

        public List<String> getData() {
            return data;
        }

        public void setData(List<String> data) {
            this.data = data;
        }

        @Override
        public int getColumnCount() {
            // TODO Auto-generated method stub
            return COLUMN_NAMES.length;
        }

        @Override
        public int getRowCount() {
            // TODO Auto-generated method stub
            if (null == data)
                return 0;
            return data.size();
        }

        @Override
        public Object getValueAt(int row, int col) {
            // TODO Auto-generated method stub
            if (col == COL1_INDEX)
            {
                return row;
            }else
            {
                return data.get(row);
            }
        }

        @Override
        public String getColumnName(int column) {
            // TODO Auto-generated method stub
            return COLUMN_NAMES[column];
        }

    }

}

我不确定这是否是一种有效的方式,但它有效,这就是我现在所需要的。如果有更好的方法可以解决这个问题,请告诉我 再次感谢。