2011-08-13 44 views
8

可能重复:
JTable Scrolling to a specified row index滚动一个JScrollPane到一个特定的行的JTable中

我有一个JTable,我编程需要使用此代码选择一行:

myTable.setRowSelectionInterval(i, j); 

(其中i和j分别是有效的行号和列号)。

问题是,当您跳转到某一行时,JScrollPane不会移动。 在这种情况下,表格很长,并且通常“选定的行”在屏幕上不可见,所以用户必须手动向上/向下滚动才能找到它。我想知道如何让JScrollPane自动跳转到该行的特定位置。

编辑:发现这一个衬垫,可以做到这一点:

table.scrollRectToVisible(table.getCellRect(row,0, true)); 
+0

不符合我的预期,把它放到我发布的代码中,您必须正确移动JViewPort – mKorbel

回答

6

只是@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(); 
    } 
} 
6

我在老项目中使用这样的:

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

+0

[JTable滚动到指定行索引]的精确副本(http://stackoverflow.com/ question/853020/jtable-scrolling-to-a-specified-row-index)的答案。 – Jeffrey

+0

@Jeffrey谢谢Jeffery的链接。我过去使用过这个代码,并且忘记了从哪里得到它 –

+5

使用这段代码一段时间后,我发现它与长表有点儿差错。我发现,虽然一个不错的一个班轮: \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t table.scrollRectToVisible(table.getCellRect(行,0,TRUE)); – David

相关问题