2013-05-03 73 views
1

我有下面的代码行移动移动:行选择不与JTable中

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.util.Vector; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.plaf.nimbus.NimbusLookAndFeel; 
import javax.swing.table.DefaultTableModel; 

public class NewClass1 extends JFrame { 
    private JTable table; 
    private JScrollPane scrollPane; 
    private DefaultTableModel defaultTableModel; 

    public NewClass1() { 
     setLocationByPlatform(true); 
     setLayout(new BorderLayout()); 
     setPreferredSize(new Dimension(600, 400)); 
     setTitle("Table Issues"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     createTableModel(); 
     table = new JTable(defaultTableModel); 

     scrollPane = new JScrollPane(table); 

     getContentPane().add(scrollPane, BorderLayout.CENTER); 

     pack(); 
    } 

    private void createTableModel() { 
     Vector cols = new Vector(); 
     cols.add("A"); 

     Vector rows = new Vector(); 
     for (int i = 0; i < 50; i++) { 
      Vector row = new Vector(); 
      row.add((i + 1) + ""); 
      rows.add(row); 
     } 

     defaultTableModel = new DefaultTableModel(rows, cols) { 
      Class[] types = new Class[]{ 
       String.class 
      }; 

      @Override 
      public Class getColumnClass(int columnIndex) { 
       return types[columnIndex]; 
      } 

      @Override 
      public boolean isCellEditable(int row, int column) { 
       return false; 
      } 
     }; 
    } 

    public static void main(String[] args) { 
     try { 
      UIManager.setLookAndFeel(new NimbusLookAndFeel()); 
     } catch (Exception e) { 
     } 

     final NewClass1 nc = new NewClass1(); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       nc.setVisible(true); 
      } 
     }); 

     while (true) { 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        int row = (int) (Math.random() * 50); 
        int move = (int) (Math.random() * 50); 

        nc.defaultTableModel.moveRow(row, row, move); 
       } 
      }); 
      try{ 
       Thread.sleep(1000); 
      }catch(Exception e){ 
      } 
     } 
    } 
} 

请运行上面的代码,然后选择行。

我的问题是与行移动,行选择是不动的。它停留在固定位置。假设我选择了列值为25的行,在行移动后所选行必须是列值为25的行。

请帮我解决这个问题。

我真正的问题是,用户将选择行并点击菜单执行操作,同时其他线程可能已移动行,并执行活动将存在于其他行比实际之一。

+1

[see post](http://stackoverflow.com/a/14633962/714968),作者:@Guillaume Polet – mKorbel 2013-05-03 16:03:33

+0

@mKorbel这里的问题是模型的内容在改变,所以'convertRowIndexToModel'本身并不做的工作,但我同意在使用'javax.swing.RowSorter'会是一个更好的方法,如果'javax.swing.table.DefaultTableModel.moveRow'就是一切正在发生 - 我明白这是一个例子通用模型的变化。 – Tilo 2013-05-03 17:13:27

回答

2

最简单的方法是记住ListSelectionModel之外某处的选定行,并在TableModel更改时调整选择。然而

public class NewClass1 extends JFrame { 
    private JTable table; 
    private DefaultTableModel defaultTableModel; 
    private JScrollPane scrollPane; 

    private class SelectionHelper implements ListSelectionListener, TableModelListener { 
     private Object selectedRow; 

     @Override 
     public void valueChanged(ListSelectionEvent event) { 
      if (!event.getValueIsAdjusting()) return; 
      int selectedIndex = table.getSelectedRow(); 
      if (selectedIndex >= 0) { 
       selectedRow = defaultTableModel.getDataVector().get(selectedIndex); 
      } else { 
       selectedRow = null; 
      } 
     } 

     @Override 
     public void tableChanged(TableModelEvent event) { 
      if (selectedRow == null) return; 
      int selectedIndex = defaultTableModel.getDataVector().indexOf(selectedRow); 
      table.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); 
     } 
    } 

    public NewClass1() { 
     // ... 
     createTableModel(); 
     table = new JTable(defaultTableModel); 

     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     SelectionHelper helper = new SelectionHelper(); 
     table.getModel().addTableModelListener(helper); 
     table.getSelectionModel().addListSelectionListener(helper); 
     // ... 
    } 
    // ... 
} 

注意,你应该在关于调整生产使用这个代码,例如线程安全或可移植性(使用tabledefaultTableModel属性的内部类是不好的风格:例如,你可以这样做)。

+0

请问一个问题,为什么我们用if(!event.getValueIsAdjusting())返回; – UDPLover 2013-05-03 18:51:25

+0

这是不是真的有必要,但清洁:一旦让你知道,旧行是选择,而一旦让你知道了新的行选择:当您选择一个新行的“的valueChanged”事件被炒鱿鱼的两倍。只需评论该行,并在其中放入一个“print”语句,这将变得清晰。 – Tilo 2013-05-03 19:40:36