先说行移动问题,我希望在jTable中能够将选中行进行上下移动,想的方法是加2个jButton,一个是向上移动,一个是向下移动,然后响应事件中通过获取选中行的index,进行moveRow,并将上(或下)一行同时向下(或上)移,这个应该能实现。再说行的颜色,我现在的jTable是取另外2个jTable的值而得到的数据,其中1个jTable固定取90行,另一个则取任意行,我现在想在新的jTable中将第一个取到的90行的行颜色设为绿色,将第二个取到的任意行的行颜色设为蓝色,这个可以在DefaultTableCellRenderer里面改,但是问题是如果我进行上下行的移动后,如何保证行的颜色也同时改变?举个例子,我现在的第90行是绿色,第91行是蓝色,如何保证第90行向下移后(同时第91行会向上移),新的第90行变成了蓝色,第91行变成绿色,就是想行移动时颜色随着移动。最后列值,新jTable中第一列是id,固定了前90行是数字1-90,后面全部为空,如何保证我在行移动时id值保持不变,不管怎么移动,id值永远是前面90行1-90,后面的为空。因为还没写程序,这些都是暂时的想法,所以希望大家能耐心看完帮帮偶~

解决方案 »

  1.   

    郁闷,怎么没人啊~移动已经可以了,
    jb.addActionListener(new ActionListener()
    {
          public void actionPerformed(ActionEvent e)
               {
                   int sRow = myTable.getSelectedRow();
                   if (sRow > 0)
                     {
                       dtm.moveRow(sRow, sRow, sRow - 1);
                       dtm.fireTableStructureChanged();
                       myTable.changeSelection(sRow - 1, 0, false, false);
                     }
                   if (sRow <= 0)
                       JOptionPane.showMessageDialog(null, "不可能", "错误", JOptionPane.ERROR_MESSAGE);
                }
    });
    如果用MouseDrag实现拖动估计更方便。id值不变只要在defalutTableModel里加上getValueAt()方法,if(row<90){return (row+1)},else return "";(能在setValueAt里改么?这两个主要什么区别,什么时候用哪个比较好啊?还有在getValueAt里改了后,那一列编辑时为什么无法改值了)。至于颜色想跟随着变,我想的方法是建表时弄个map,将1-90的值设为0,后面的设为1,然后在移动行时对HashMap进行同样的操作,在画单元格时对HashMap进行判断,HashMap里的值为0就是绿色,1就是蓝色。不知道这样可不可以?
      

  2.   

    汗,hashmap可以上下移动么?找不到啊~~
      

  3.   

    什么都不用 在model里加一个隐藏列 初始化的时候给索引 1- 90 and > 90移动的时候值是不变的  render里面就根据这个cell的值确定行的颜色。。
      

  4.   

    用Hashmap实现了
    只要在移动时,就是jb的事件中加入:
    int oldValue = iMap.get(String.valueOf(sRow));
    int oldValue_ = iMap.get(String.valueOf(sRow - 1));
    iMap.put(String.valueOf(sRow - 1), oldValue);
    iMap.put(String.valueOf(sRow), oldValue_);
    然后在渲染颜色时:
    if (iMap.get(String.valueOf(row)) == 1) cell.setBackground(Color.blue);
    else cell.setBackground(Color.green);不过又有新的想法,如果我要让后加的90行后的蓝色行移动到90行内就变成红色,在90行外移动都是蓝色要怎么实现?貌似很乱~~
      

  5.   

    恩,又实现了,呵呵,汗死,最近都开始自问自答了~
    还是用HashMap,主要在第90行处进行判断,后面的移上来设为2,不过判断比较麻烦,分了4,5种情况~~3楼的我本来也是这么想的,不过隐藏列要怎么实现,设置列宽为0么?我是想把列宽限定了,再把jScrollPane的size限定死,把表格多出的这列显示到size之外就看不到了~
    不过用哈希表也不太烦~
      

  6.   

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Container;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.HashMap;
    import java.util.Vector;import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableColumnModel;public class ExchangeDemo extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Vector<Vector<Object>> data = new Vector<Vector<Object>>();
    private static final Vector<String> COLUMN_NAMES = new Vector<String>();
    private JTable table;
    private int iCount = 0;
    // 用来存储id和行的对应关系,看着方便一点
    private HashMap<String, Integer> idToRowMap = new HashMap<String, Integer>(); DefaultTableCellRenderer render = new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus, int row,
    int column) { Component c = super.getTableCellRendererComponent(table, value,
    isSelected, hasFocus, row, column);
    if (row < 10) {
    setBackground(row % 2 == 0 ? Color.green : Color.blue);
    } else {
    setBackground(Color.red);
    }
    return c;
    }
    }; public ExchangeDemo() {
    super();
    initData();
    Container c = getContentPane();
    table = new JTable();
    table.setModel(new DefaultTableModel(data, COLUMN_NAMES) { /**
     * 
     */
    private static final long serialVersionUID = 1L; @Override
    public void setValueAt(Object value, int row, int column) {
    Object oValue = getValueAt(row, column);
    if (value.equals(oValue)) {
    return;
    } if (column == 0) {
    int iValue;
    try {
    iValue = Integer.parseInt(value.toString());
    } catch (Exception e) {
    // TODO: 这地方的判断小子自己做吧
    e.printStackTrace();
    return;
    } if (iValue - 1 >= data.size()) {
    // 这地方通常好的软件有一些比较强的处理,我就先拿这个顶了
    JOptionPane.showMessageDialog(table, "error");
    return;
    }
    if (row < data.size() && column < COLUMN_NAMES.size()) { Object oldValue = data.get(row).get(column); data.get(row).set(column,
    value == null ? "" : value.toString());
    data.get(idToRowMap.get(String.valueOf(value))).set(
    column, oldValue);
    //
    updateMapInfo(value, oldValue);
    fireTableDataChanged();
    }
    } else if (column == 3) {
    Boolean b = (Boolean) value; if (b && iCount == data.size() - 1) {
    return;
    }
    if (!b && iCount == 0) {
    return;
    } iCount += b ? 1 : -1;
    JOptionPane.showMessageDialog(table, "选中个数:" + iCount);
    super.setValueAt(value, row, column); } else { super.setValueAt(value, row, column);
    }
    } @Override
    public Class<?> getColumnClass(int columnIndex) {
    return data.get(0).get(columnIndex).getClass();
    }
    }); refreshTable(); c.setLayout(new BorderLayout());
    c.add(new JScrollPane(table));
    c.add(createButtonPanel(), BorderLayout.SOUTH);
    setSize(600, 400);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
    } // private JPanel createButtonPanel() {
    JPanel panel = new JPanel();
    panel.setLayout(new FlowLayout()); JButton upButton = new JButton("向上");
    JButton downButton = new JButton("向下"); upButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    int r = table.getSelectedRow();
    if (r <= 0) {
    return;
    } swapData(r, true); //
    Object value = data.get(r).get(0);
    Object value2 = data.get(r - 1).get(0);
    updateMapInfo(value, value2);
    ((DefaultTableModel) table.getModel()).fireTableRowsUpdated(
    r - 1, r);
    table.changeSelection(r - 1, 0, false, false); }
    }); downButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    int r = table.getSelectedRow();
    if (r < 0 || r >= data.size()) {
    return;
    }
    swapData(r, false); //
    Object value = data.get(r).get(0);
    Object value2 = data.get(r + 1).get(0);
    updateMapInfo(value, value2);
    ((DefaultTableModel) table.getModel()).fireTableRowsUpdated(
    r - 1, r);
    table.changeSelection(r + 1, 0, false, false);
    } }); panel.add(upButton);
    panel.add(downButton); return panel;
    } private void swapData(int r, boolean isUp) {
    Vector<Object> obj = data.get(r); int newIndex = isUp ? r - 1 : r + 1;
    data.set(r, data.get(newIndex));
    data.set(newIndex, obj);
    } private void updateMapInfo(Object value, Object oldValue) {
    Integer row1 = idToRowMap.get(value);
    Integer row2 = idToRowMap.get(String.valueOf(oldValue));
    idToRowMap.put(value.toString(), row2);
    idToRowMap.put(String.valueOf(oldValue), row1);
    } private void refreshTable() {
    TableColumnModel columnModel = table.getColumnModel();
    for (int i = 0; i < columnModel.getColumnCount() - 1; i++) {
    columnModel.getColumn(i).setCellRenderer(render);
    }
    } private void initData() {
    for (int i = 0; i < 4; i++) {
    COLUMN_NAMES.add("column" + (i + 1));
    }
    for (int i = 0; i < 20; i++) {
    Vector<Object> record = new Vector<Object>();
    String id = String.valueOf(i + 1);
    record.add(id);
    record.add("aa");
    record.add("bb");
    record.add(new Boolean(false));
    data.add(record);
    idToRowMap.put(id, new Integer(i));
    }
    } public static void main(String args[]) {
    new ExchangeDemo();
    }
    }
      

  7.   

    这说法怎么这么别扭?是不跟着移动才对吧~~也就是说,颜色是相对于行来说的,而与里面是什么数据无关,相互独立。这个是最简单当然也是最为常见的做法了。上面那段程序我得交代几句:
    第一,你说要90行。我比较懒,20行。10行以前蓝绿交替,10行以后全红。你自己按照需要改render里面的东西。
    第二,颜色,你自己喜欢的自己换吧。
    第三,前两天你说的那个bug,你再简单测试一下,我修正了。不知道有没有遗漏。
      

  8.   


    我没做鼠标拖动,不过也很简单。JTable有一个rowAtPoint方法,提供了很大的方便。
    唉,你怎么不早点来灌水。一个人只能连续回复三次,无奈我把修改过的回到lz的另外一个帖子里了~~
    呵呵。
    友情提示,上面我的代码有问题,~~两处小地方的逻辑问题,就是两个按钮的操作~~
      

  9.   

    恩,不好意思,呵呵 这么正来了,对JTable了解的也不深入。
    一个人一天可以回复多次的吧。
      

  10.   

    [Quote=引用 9 楼 gentalguo 的回复:]
    引用楼主 w2020520 的帖子:
    举个例子,我现在的第90行是绿色,第91行是蓝色,如何保证第90行向下移后(同时第91行会向上移),新的第90行变成了蓝色,第91行变成绿色,就是想行移动时颜色随着移动。 
    这说法怎么这么别扭?是不跟着移动才对吧~~也就是说,颜色是相对于行来说的,而与里面是什么数据无关,相互独立。这个是最简单当然也是最为常见的做法了。 刚回来看到了,还没看你的程序,不过我用哈希表已经实现了,就是前90行赋为0,90行后赋为1,然后在第90处做判断,使得原来1的移上去变2,不过判断稍微烦了点,因为情况有4,5种,都判断一下就好了,再在渲染类里0,1,2进行判断就行了,郁闷的是移动后列宽就自动变回来了,还有就是jComboBox的变成jLabel形式的了,只好判断完把这两个又重新设了1遍。鼠标拖动我也没做,感觉上下移差不多够了~有空再加上去吧。拖动我想用MouseDrag处理拖动,MouseReleased来取释放时的row的index,再用moveRow就行了吧~