将 JScrollPane 滚动到 JTable 上的特定行 [重复]
Posted
技术标签:
【中文标题】将 JScrollPane 滚动到 JTable 上的特定行 [重复]【英文标题】:Scroll a JScrollPane to a specific row on a JTable [duplicate] 【发布时间】:2011-10-26 12:40:41 【问题描述】:可能重复:JTable Scrolling to a specified row index
我有一个 JTable,我需要使用以下代码以编程方式选择一行:
myTable.setRowSelectionInterval(i, j);
(其中 i 和 j 分别是有效的行号和列号)。
问题是,当你跳转到一行时,JScrollPane 不会移动。 在这种情况下,表格很长,并且“选定的行”通常在屏幕上不可见,因此用户必须手动向上/向下滚动才能找到它。我想知道如何让 JScrollPane 自动跳转到该行的特定位置。
编辑:找到这个可以做到的班轮:
table.scrollRectToVisible(table.getCellRect(row,0, true));
【问题讨论】:
这也不能像我预期的那样工作,把它放到我发布的代码中,你必须正确移动 JViewPort 【参考方案1】:只是扩展了@Eng.Fouad +1 的帖子,没有像我预期的那样工作(在另一个 Java Swing 论坛的StanislavL 的帮助下)
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.DefaultTableModel;
public class TableSelectionGood implements ListSelectionListener
private JTable[] tables;
private boolean ignore = false;
public TableSelectionGood()
Object[][] data1 = new Object[100][5];
Object[][] data2 = new Object[50][5];
Object[][] data3 = new Object[50][5];
for (int i = 0; i < data1.length; i++)
data1[i][0] = "Company # " + (i + 1);
for (int j = 1; j < data1[i].length; j++)
data1[i][j] = "" + (i + 1) + ", " + j;
for (int i = 0; i < data2.length; i++)
data2[i][0] = "Company # " + ((i * 2) + 1);
for (int j = 1; j < data2[i].length; j++)
data2[i][j] = "" + ((i * 2) + 1) + ", " + j;
for (int i = 0; i < data3.length; i++)
data3[i][0] = "Company # " + (i * 2);
for (int j = 1; j < data3[i].length; j++)
data3[i][j] = "" + (i * 2) + ", " + j;
String[] headers = "Col 1", "Col 2", "Col 3", "Col 4", "Col 5";
DefaultTableModel model1 = new DefaultTableModel(data1, headers);
DefaultTableModel model2 = new DefaultTableModel(data2, headers);
DefaultTableModel model3 = new DefaultTableModel(data3, headers);
final JTable jTable1 = new JTable(model1);
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane sp1 = new JScrollPane();
sp1.setPreferredSize(new Dimension(600, 200));
sp1.setViewportView(jTable1);
final JTable jTable2 = new JTable(model2);
jTable2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane sp2 = new JScrollPane();
sp2.setPreferredSize(new Dimension(600, 200));
sp2.setViewportView(jTable2);
final JTable jTable3 = new JTable(model3);
jTable3.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane sp3 = new JScrollPane();
sp3.setPreferredSize(new Dimension(600, 200));
sp3.setViewportView(jTable3);
TableSelectionGood tableSelection = new TableSelectionGood(jTable1, jTable2, jTable3);
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(3, 0, 10, 10));
panel1.add(sp1);
panel1.add(sp2);
panel1.add(sp3);
JFrame frame = new JFrame("tableSelection");
frame.add(panel1);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
public TableSelectionGood(JTable... tables)
for (JTable table : tables)
table.getSelectionModel().addListSelectionListener(this);
this.tables = tables;
private JTable getTable(Object model)
for (JTable table : tables)
if (table.getSelectionModel() == model)
return table;
return null;
private void changeSelection(JTable table, String rowKey)
int col = table.convertColumnIndexToView(0);
for (int row = table.getRowCount(); --row >= 0;)
if (rowKey.equals(table.getValueAt(row, col)))
table.changeSelection(row, col, false, false);
return;
table.clearSelection();
@Override
public void valueChanged(ListSelectionEvent e)
if (e.getValueIsAdjusting() || ignore)
return;
ignore = true;
try
JTable table = getTable(e.getSource());
int row = table.getSelectedRow();
String rowKey = table.getValueAt(row, table.convertColumnIndexToView(0)).toString();
for (JTable t : tables)
if (t == table)
continue;
changeSelection(t, rowKey);
JViewport viewport = (JViewport) t.getParent();
Rectangle rect = t.getCellRect(t.getSelectedRow(), 0, true);
Rectangle r2 = viewport.getVisibleRect();
t.scrollRectToVisible(new Rectangle(rect.x, rect.y, (int) r2.getWidth(), (int) r2.getHeight()));
System.out.println(new Rectangle(viewport.getExtentSize()).contains(rect));
finally
ignore = false;
public static void main(String[] args)
TableSelectionGood tableSelection = new TableSelectionGood();
【讨论】:
【参考方案2】:我在旧项目中使用了这个:
public static void scrollToVisible(JTable table, int rowIndex, int vColIndex)
if (!(table.getParent() instanceof JViewport)) return;
JViewport viewport = (JViewport)table.getParent();
Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
Point pt = viewport.getViewPosition();
rect.setLocation(rect.x-pt.x, rect.y-pt.y);
viewport.scrollRectToVisible(rect);
参考:http://www.exampledepot.com/egs/javax.swing.table/Vis.html
【讨论】:
JTable Scrolling to a specified row index 的答案的精确副本。 @Jeffrey 感谢 Jeffery 提供的链接。我过去使用过这段代码,但我忘记了从哪里得到的 使用这段代码一段时间后,我发现它对于长表有点错误。我发现了一个不错的衬里:table.scrollRectToVisible(table.getCellRect(row,0, true));以上是关于将 JScrollPane 滚动到 JTable 上的特定行 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
JScrollPane 中的 JTable:禁用滚动条的最佳高度