我有一个显示超过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]; } } }
非常感谢您解决此问题的任何帮助。提前谢谢。
答案 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];
}
}
}
我不确定这是否是一种有效的方式,但它有效,这就是我现在所需要的。如果有更好的方法可以解决这个问题,请告诉我 再次感谢。