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

Posted

技术标签:

【中文标题】在旁边的另一个 JTable 上继续 JTable 数据而不是滚动【英文标题】:Continue JTable data on another JTable beside it instead of scrolling 【发布时间】:2018-07-08 09:53:51 【问题描述】:

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

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

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

导入 java.awt.BorderLayout; 导入 java.awt.Dimension; 导入 java.awt.event.ActionEvent; 导入 java.awt.event.ActionListener; 导入 java.util.ArrayList; 导入 java.util.List; 导入 javax.swing.BoxLayout; 导入 javax.swing.JButton; 导入 javax.swing.JFrame; 导入 javax.swing.JPanel; 导入 javax.swing.JScrollPane; 导入 javax.swing.JTable; 导入 javax.swing.JViewport; 导入 javax.swing.ScrollPaneConstants; 导入 javax.swing.table.AbstractTableModel; 公共类 DataPanel 扩展 JPanel /** * */ 私有静态最终长序列版本UID = 1L; 列表数据 = new ArrayList(); JScrollPane 滚动窗格; JTable 表,最后一个表; JPanel boxPanel; 整数行 = 0; 公共数据面板() for (int i = 0; i newData = getData(rows); 数据模型 newModel = new DataModel(newData); JTable newTable = new JTable(newModel); 最后一个表 = 新表; JScrollPane newScrollPane = new JScrollPane(newTable); newScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_​​NEVER); boxPanel.add(newScrollPane); 私有列表 getData(int rows) // TODO 自动生成的方法存根 列表 newData = new ArrayList(); for(int i=0; i= 行) newData.add(data.get(i)); 返回新数据; 私有 int getVisibleRowCount(JTable 表) JViewport 视口 = (JViewport) table.getParent(); 维度 extentSize = viewport.getExtentSize(); // JViewport int visibleRows = extentSize.height/table.getRowHeight(); 返回可见行; 公共静态无效主(字符串参数 []) 新数据面板(); 私有类 DataModel 扩展 AbstractTableModel 静态最终 int COL1_INDEX = 0; 静态最终 int COL2_INDEX = 1; 私有最终字符串 [] COLUMN_NAMES = 新字符串 [] "ID", "姓名"; 私有列表数据 = new ArrayList(); 公共数据模型(列出新数据) 数据=新数据; 公共列表 getData() 返回数据; 公共无效setData(列表数据) this.data = 数据; @覆盖 公共 int getColumnCount() // TODO 自动生成的方法存根 返回 COLUMN_NAMES.length; @覆盖 公共 int getRowCount() // TODO 自动生成的方法存根 如果(空 == 数据) 返回0; 返回数据.size(); @覆盖 公共对象 getValueAt(int row, int col) // TODO 自动生成的方法存根 System.out.println("请求行:" + row + " 和列:" + col); if (col == COL1_INDEX) 返回行; 别的 返回数据.get(行); @覆盖 公共字符串 getColumnName(int column) // TODO 自动生成的方法存根 返回 COLUMN_NAMES[列];

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

【问题讨论】:

【参考方案1】:

我已经找到了解决上述问题的方法。我在框架中添加了一个组件侦听器,每当它的大小发生变化时,我都会遍历表并更改这些表的 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];
        

    


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

【讨论】:

以上是关于在旁边的另一个 JTable 上继续 JTable 数据而不是滚动的主要内容,如果未能解决你的问题,请参考以下文章

如何在空间可用时将多个JTable打印到单个页面

如何将工具提示添加到 jtable 中的单元格?

从 RestulSet 表编辑 JTable

如何在 DragAndDrop 期间在 Main-JTable 上绘制 RowHeader-JTable 的 Dropline?

在 JTable 上显示特定用户的数据

JTable 不会显示在 JPanel 上