在旁边的另一个 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 数据而不是滚动的主要内容,如果未能解决你的问题,请参考以下文章
如何在 DragAndDrop 期间在 Main-JTable 上绘制 RowHeader-JTable 的 Dropline?