繁体   English   中英

动态为JTable行着色,移动行时出现行选择问题

[英]Coloring JTable row dynamicaly, row selection issue on moving row

我遇到了JTable问题。

我正在做的是:动态移动表行并动态更改行的颜色。 我面临以下一些问题:

  1. 对于移动的行,行选择不会移动。 因此,问题是,用户将选择行并执行某项操作,同时行将移动,而所选行将是其他行,并且用户操作将在除所需行之外的其他行上执行。
  2. 有时只有部分行(很少的几列)变色,有时整个行都会变色。

因此,我希望对整个行进行动态着色,并且行选择应随行移动而移动。

我设法以某种方式更新了整行的颜色,

但仍然有行选择的问题。

下面是代码:

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

public class NewClass extends JFrame {

    private JTable table;
    private JScrollPane scrollPane;
    private DefaultTableModel defaultTableModel;

    public NewClass() {
        setLocationByPlatform(true);
        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(1000, 700));
        setTitle("Table Issues");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        createTableModel();
        createTable();
        table.setModel(defaultTableModel);

        scrollPane = new JScrollPane(table);

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

        pack();
    }

    private void createTable() {
        table = new JTable() {

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component comp = super.prepareRenderer(renderer, row, column);
                JComponent jc = (JComponent) comp;
                if (!isRowSelected(row)) {
                    int modelRow = convertRowIndexToModel(row);
                    int i = Integer.parseInt((String) getModel().getValueAt(modelRow, 2));
                    if (i == 0) {
                        jc.setBackground(Color.orange);
                    } else if (i == 1 || i == 2) {
                        jc.setBackground(Color.yellow);
                    } else if (i == 3) {
                        jc.setBackground(Color.green);
                    } else {
                        jc.setBackground(Color.white);
                    }
                }
                return comp;
            }
        };
    }

    private void createTableModel() {
        Vector cols = new Vector();
        cols.add("1");
        cols.add("2");
        cols.add("3");
        cols.add("4");
        cols.add("5");

        Vector rows = new Vector();

        for (int i = 0; i < 50; i++) {
            Vector row = new Vector();
            row.add((i + 1) + "");
            row.add("B");
            int r = (int) (Math.random() * 5);
            row.add(r + "");
            row.add("D");
            row.add("E");
            rows.add(row);
        }

        defaultTableModel = new DefaultTableModel(rows, cols) {

            Class[] types = new Class[]{
                String.class, String.class, String.class, String.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 Object lock = new Object();
        final NewClass nc = new NewClass();
        nc.setVisible(true);

        new Thread(new Runnable() {

            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                    }
                    synchronized (lock) {
                        int i = (int) (Math.random() * 5);
                        int row = (int) (Math.random() * 50);
                        int move = (int) (Math.random() * 50);

                        nc.defaultTableModel.setValueAt(i + "", row, 2);
                        nc.defaultTableModel.moveRow(row, row, move);
                        nc.defaultTableModel.setValueAt(i + "", row, 2);
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {

            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                    }
                    synchronized (lock) {
                        int i = (int) (Math.random() * 5);
                        int row = (int) (Math.random() * 50);
                        int move = (int) (Math.random() * 50);

                        nc.defaultTableModel.setValueAt(i + "", row, 2);
                        nc.defaultTableModel.moveRow(row, row, move);
                        nc.defaultTableModel.setValueAt(i + "", row, 2);
                    }
                }
            }
        }).start();

        while (true) {
            synchronized (lock) {
                int i = (int) (Math.random() * 5);
                int row = (int) (Math.random() * 50);
                int move = (int) (Math.random() * 50);

                nc.defaultTableModel.setValueAt(i + "", row, 2);
                nc.defaultTableModel.moveRow(row, row, move);
                nc.defaultTableModel.setValueAt(i + "", row, 2);
                if (i % 2 == 1) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                    }
                }
            }
        }
    }
}

在此代码中,当您选择行时,在行中移动之后,所选行将是其他行,即,行选择不随行移动而移动。

请帮我。

我通过重写DefaultTableModel setValueAt方法解决了为行着色的问题。 覆盖的方法是:

@Override
public void setValueAt(Object aValue, int row, int column) {
    Vector rowVector = (Vector)dataVector.elementAt(row);
    rowVector.setElementAt(aValue, column);
    // update whole row instead of single cell
    fireTableRowsUpdated(row, row);
}

问题可能是由于多个线程的工作量很大,EDT可能没有时间更新整个行。 使用DefaultTableModelsetValueAt方法设置值时,该列肯定会由于单元更新事件的触发而着色。

但是我仍然有选择不随表中的行移动而移动的问​​题。

打开新线程以解决行选择问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM