加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – JTable中带复选框的多行选择

发布时间:2020-12-14 19:19:40 所属栏目:Java 来源:网络整理
导读:我有一个带复选框的JTable作为列之一.我还在标题中有一个复选框来检查/取消选中所有. AFAIK JTable的默认行为是,如果选择新行,它将取消选择之前选择的所有行.但是我们可以通过复选框实现CTRL点击行为.保留以前选定的行. 我面临的主要问题是使用复选框启用多

我有一个带复选框的JTable作为列之一.我还在标题中有一个复选框来检查/取消选中所有.
AFAIK JTable的默认行为是,如果选择新行,它将取消选择之前选择的所有行.但是我们可以通过复选框实现CTRL点击行为.保留以前选定的行.
我面临的主要问题是使用复选框启用多个JTable行选择.

预期产出

检查第一行然后选择第一行,如果选中第三行,则选择第三行以及第一行(已经选中并选中)

实际输出

检查并选择第一行时,如果选择第三行,则取消选择先前选择的所有行,仅选择第三行.

我有一个示例代码,它模拟我想要实现的场景,与Add Another One按钮相同,但有复选框选择.

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumn;
import javax.swing.event.CellEditorListener;

public class JTableRowSelectProgramatically extends JPanel {

final JTable table = new JTable(new MyTableModel());

public JTableRowSelectProgramatically() {
    initializePanel();
}

private void initializePanel() {
    setLayout(new BorderLayout());
    setPreferredSize(new Dimension(475,150));


    table.setFillsViewportHeight(true);
    JScrollPane pane = new JScrollPane(table);

    JLabel label2 = new JLabel("Row: ");
    final JTextField field2 = new JTextField(3);
    JButton add = new JButton("Select");

    table.setRowSelectionAllowed(true);
    table.setColumnSelectionAllowed(false);
    table.getSelectionModel().addListSelectionListener(new ListSelectionListenerImpl());
    TableColumn tc = table.getColumnModel().getColumn(3);
    tc.setCellEditor(table.getDefaultEditor(Boolean.class));
    tc.setCellRenderer(table.getDefaultRenderer(Boolean.class));
    ((JComponent) table.getDefaultRenderer(Boolean.class)).setOpaque(true);
    tc.getCellEditor().addCellEditorListener(new CellEditorListenerImpl());

    add.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent event) {
            int index2 = 0;
            try {
                index2 = Integer.valueOf(field2.getText());
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            table.addRowSelectionInterval(index2,index2);
            field2.setText(String.valueOf(index2));
        }
    });

    JPanel command = new JPanel(new FlowLayout());
    command.add(label2);
    command.add(field2);
    command.add(add);

    add(pane,BorderLayout.CENTER);
    add(command,BorderLayout.SOUTH);
}

public static void showFrame() {
    JPanel panel = new JTableRowSelectProgramatically();
    panel.setOpaque(true);

    JFrame frame = new JFrame("JTable Row Selection");
    frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(panel);
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        public void run() {
            JTableRowSelectProgramatically.showFrame();
        }
    });
}

public class MyTableModel extends AbstractTableModel {

    private String[] columns = {"ID","NAME","AGE","A STUDENT?"};
    private Object[][] data = {
        {1,"Alice",20,new Boolean(false)},{2,"Bob",10,{3,"Carol",15,{4,"Mallory",25,new Boolean(false)}
    };

    public int getRowCount() {
        return data.length;
    }

    public int getColumnCount() {
        return columns.length;
    }

    public Object getValueAt(int rowIndex,int columnIndex) {
        return data[rowIndex][columnIndex];
    }

    @Override
    public String getColumnName(int column) {
        return columns[column];
    }

    @Override
    public boolean isCellEditable(int rowIndex,int columnIndex) {
        return columnIndex == 3;
    }

    //
    // This method is used by the JTable to define the default
    // renderer or editor for each cell. For example if you have
    // a boolean data it will be rendered as a check box. A
    // number value is right aligned.
    //
    @Override
    public Class
最佳答案
实现这些TableModel方法后,可以在按钮侦听器中使用setValueAt()来根据需要调整模型,以使复选框状态和选择模型保持同步.有一个相关的例子here.

@Override
public boolean isCellEditable(int rowIndex,int columnIndex) {
    return columnIndex == 3;
}

@Override
public void setValueAt(Object aValue,int columnIndex) {
    if (columnIndex == 3) {
        data[rowIndex][columnIndex] = aValue;
        fireTableCellUpdated(rowIndex,columnIndex);
    }
}

附录:作为一个具体示例,您的清除侦听器可能会调用TableModel中的方法,例如clearChecks():

MyTableModel model = (MyTableModel) table.getModel();
model.clearChecks();
...
private void clearChecks() {
    for (int i = 0; i < data.length; i++) {
        data[i][3] = false;
    }
    fireTableRowsUpdated(0,data.length);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读