Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 填充文件的JTable在模型修改后重复值(AbstractTableModel)_Java_Swing_Jtable_Jbutton_Abstracttablemodel - Fatal编程技术网

Java 填充文件的JTable在模型修改后重复值(AbstractTableModel)

Java 填充文件的JTable在模型修改后重复值(AbstractTableModel),java,swing,jtable,jbutton,abstracttablemodel,Java,Swing,Jtable,Jbutton,Abstracttablemodel,我又在为JTable苦苦挣扎,我被卡住了 问题是: 我有一个按钮来选择文件路径以填充JTable的第一列:这很好 单击一个复选框,我将更改jtable的结构以添加或删除列:这很好 当我再次尝试用文件路径填充新表时,在列的每一行中只复制最后一个选定的路径 我发现很多帖子都有类似的问题,但无法解决(试试cellRenderer、cellEditor、修改模型等等)。下面,我试图将代码减少到最低限度,使其变得简单。我尝试了很多不同的事情,但我真的不明白发生了什么事情的逻辑(我完全阅读了文档,但显然

我又在为JTable苦苦挣扎,我被卡住了

问题是:

  • 我有一个按钮来选择文件路径以填充JTable的第一列:这很好
  • 单击一个复选框,我将更改jtable的结构以添加或删除列:这很好
  • 当我再次尝试用文件路径填充新表时,在列的每一行中只复制最后一个选定的路径
我发现很多帖子都有类似的问题,但无法解决(试试cellRenderer、cellEditor、修改模型等等)。下面,我试图将代码减少到最低限度,使其变得简单。我尝试了很多不同的事情,但我真的不明白发生了什么事情的逻辑(我完全阅读了文档,但显然我遗漏了一些东西)

我也尝试过使用DefaultTableModel制作一个版本,但问题似乎是独立的。此外,我希望保留AbstractTableModel,因为其他类使用它。我认为模型中出现了一些问题,但我不知道是什么(在模型中尝试了不同的火***)

如果您看到了错误并能解释其背后的逻辑,我们将不胜感激

非常感谢。以下是我认为可以自我解释的代码:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;


public class FillTableExample extends JFrame {

private JLabel label = new JLabel("File:");
private JButton selectButton = new JButton("Select");
private JPanel labelButtonPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
private Object rowDataTable[][] = {{"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""}};
private String[] columnNames = {"File", "Name"};
private CustomTableModel fileTableModel = new CustomTableModel(rowDataTable, columnNames);
private JTable fileTable = new JTable(fileTableModel);
private JScrollPane scrollPane = new JScrollPane(fileTable);
private FillTable fillTableActionListener = new FillTable(fileTableModel);
private JPanel container = new JPanel();
private JCheckBox changeCol = new JCheckBox("ChangeCol");



public FillTableExample(){


    selectButton.addActionListener(fillTableActionListener);
    labelButtonPane.add(label);
    labelButtonPane.add(selectButton);

    changeCol.addActionListener(new DisplayPane());

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setExtendedState(MAXIMIZED_BOTH);
    this.setMinimumSize(new Dimension(400,400));
    this.setResizable(true);
    container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
    container.add(labelButtonPane);
    container.add(changeCol);
    container.add(scrollPane);
    this.setContentPane(container);
    this.setVisible(true);
}


public class CustomTableModel extends AbstractTableModel {

    private Object rowData[][];
    private String[] columnNames;

    public CustomTableModel(Object data[][], String[] titles){
        rowData = data;
        columnNames = titles;
    }

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

    public String getColumnName(int column) {
        return columnNames[column];
    }

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

    public Object getValueAt(int row, int column) {
        return rowData[row][column];
    }

    public Class getColumnClass(int column) {
        return this.rowData[0][column].getClass();
    }


    public int getColumnIndex(String columnName){
        return Arrays.asList(columnNames).indexOf(columnName);
    }

    public void setValueAt(Object value, int row, int column) {
        rowData[row][column] = value;
       // fireTableDataChanged();
    }

    public boolean isCellEditable(int row, int column) {

        if(column == 0 && columnNames[0].equals("Sample Name"))
            return true;
        else
            return (column != 0);
    }
}

class DisplayPane implements ActionListener {


    public void actionPerformed(ActionEvent e){

        final String[] tmpContent1 = {"", "", ""};
        final String[] newColumnNames = {"File", "Name", "Extension"};

        for (int i = 0; i < rowDataTable.length; i++)
                rowDataTable[i] = tmpContent1;
        fileTableModel = new CustomTableModel(rowDataTable, newColumnNames);

        fileTable.setModel(fileTableModel);
        fillTableActionListener.setModel(fileTableModel);
        fileTableModel.fireTableStructureChanged();
        fileTableModel.fireTableDataChanged();
    }
}


class FillTable implements ActionListener {

    private CustomTableModel model;

    public FillTable(CustomTableModel model){

        this.model = model;
    }

    public void actionPerformed(ActionEvent e){

        final JFileChooser fc = new JFileChooser();
        int returnVal;

        fc.setMultiSelectionEnabled(true);
        returnVal = fc.showOpenDialog(FillTableExample.this);

        model.setValueAt("toto", 0, 0);
        //I tried this, but you can see that toto is duplicated when clicking on cell
        //((AbstractTableModel) fileTable.getModel()).fireTableCellUpdated(0, 0);
        model.fireTableDataChanged();
    }

    public void setModel(CustomTableModel model){
        this.model = model;
    }
}


class FileEditor extends DefaultCellEditor {

    public FileEditor(){
        super(new JTextField());
    }
    public Component getTableCellEditorComponent(JTable table, Object value,
              boolean isSelected, int row, int column) {

        JTextField editor = (JTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column);

        if(column == 0){
            if(value != "toto")
                editor.setText("");
            else
                editor.setText(value.toString());
        }

        return editor;
    }
}


public static void main(String[] args) {

    FillTableExample example = new FillTableExample();
    example.setVisible(true);
}
}

请查找固定类别:

class DisplayPane implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            final String[] newColumnNames = { "File", "Name", "Extension" };

            for (int i = 0; i < rowDataTable.length; i++){
                rowDataTable[i] =new String[] { "", "", "" }; // See below
            }
            fileTableModel = new CustomTableModel(rowDataTable, newColumnNames);

            fileTable.setModel(fileTableModel);
            fillTableActionListener.setModel(fileTableModel);
            fileTableModel.fireTableStructureChanged();
            fileTableModel.fireTableDataChanged();
        }
    }
class DisplayPane实现ActionListener{
已执行的公共无效操作(操作事件e){
最终字符串[]newColumnNames={“文件”、“名称”、“扩展名”};
对于(int i=0;i
该错误是由于对每行使用相同的字符串数组造成的。
一个好的做法是从模型中触发事件。

非常感谢!问题是我在每行复制相同的字符串[]。因此,修改一个字符串在整个列中传播。声明新字符串[]可确保每行中都有不同的内容

将fireTableDataChanged()放在模型中,然后从类中删除fileTableModel.fireTableStructureChanged()和fileTableModel.fireTableDataChanged()即可实现此目的

以下是完整的操作代码:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;


public class FillTableExample extends JFrame {

private JLabel label = new JLabel("File:");
private JButton selectButton = new JButton("Select");
private JPanel labelButtonPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
private Object rowDataTable[][] = {{"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""}};
private String[] columnNames = {"File", "Name"};
private CustomTableModel fileTableModel = new CustomTableModel(rowDataTable, columnNames);
private JTable fileTable = new JTable(fileTableModel);
private JScrollPane scrollPane = new JScrollPane(fileTable);
private FillTable fillTableActionListener = new FillTable(fileTableModel);
private JPanel container = new JPanel();
private JCheckBox changeCol = new JCheckBox("ChangeCol");



public FillTableExample(){


    selectButton.addActionListener(fillTableActionListener);
    labelButtonPane.add(label);
    labelButtonPane.add(selectButton);

    changeCol.addActionListener(new DisplayPane());

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setExtendedState(MAXIMIZED_BOTH);
    this.setMinimumSize(new Dimension(400,400));
    this.setResizable(true);
    container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
    container.add(labelButtonPane);
    container.add(changeCol);
    container.add(scrollPane);
    this.setContentPane(container);
    this.setVisible(true);
}


public class CustomTableModel extends AbstractTableModel {

    private Object rowData[][];
    private String[] columnNames;

    public CustomTableModel(Object data[][], String[] titles){
        rowData = data;
        columnNames = titles;
    }

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

    public String getColumnName(int column) {
        return columnNames[column];
    }

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

    public Object getValueAt(int row, int column) {
        return rowData[row][column];
    }

    public Class getColumnClass(int column) {
        return this.rowData[0][column].getClass();
    }


    public int getColumnIndex(String columnName){
        return Arrays.asList(columnNames).indexOf(columnName);
    }

    public void setValueAt(Object value, int row, int column) {
        rowData[row][column] = value;
       fireTableDataChanged();
    }

    public boolean isCellEditable(int row, int column) {

        if(column == 0 && columnNames[0].equals("Sample Name"))
            return true;
        else
            return (column != 0);
    }
}

class DisplayPane implements ActionListener {


    public void actionPerformed(ActionEvent e){

        final String[] newColumnNames = {"File", "Name", "Extension"};

        for (int i = 0; i < rowDataTable.length; i++)
                rowDataTable[i] = new String[]{"", "", ""};
        fileTableModel = new CustomTableModel(rowDataTable, newColumnNames);

        fileTable.setModel(fileTableModel);
        fillTableActionListener.setModel(fileTableModel);
    }
}


class FillTable implements ActionListener {

    private CustomTableModel model;

    public FillTable(CustomTableModel model){

        this.model = model;
    }

    public void actionPerformed(ActionEvent e){

        final JFileChooser fc = new JFileChooser();
        int returnVal;

        fc.setMultiSelectionEnabled(true);
        returnVal = fc.showOpenDialog(FillTableExample.this);

        model.setValueAt("toto", 0, 0);
    }

    public void setModel(CustomTableModel model){
        this.model = model;
    }
}


public static void main(String[] args) {

    FillTableExample example = new FillTableExample();
    example.setVisible(true);
}
}

我认为您没有理由扩展AbstractTableModel。您可以使用DefaultTableModel,只需在适当的地方重写方法,比如isCellEditable(…)方法
还尝试了在模型中使用不同的fire***)。
-实际上,您没有在模型中使用它,这是使用DefaultTableModel的另一个原因,因为它已经为您提供了这一功能。您不应该在TableModel之外调用这些方法。对于自定义编辑器,您不应该检查列。编辑器只应添加到第一列,因此不需要进行检查。所有其他列都将使用默认编辑器。谢谢。我已经用DefaultTableModel做了一个代码(见编辑)并删除了fire***。同样的问题。
我已经用DefaultTableModel编写了一个代码(请参见编辑)
-不知道如何测试它,因为main()方法仍然调用第一个示例
当我再次尝试用文件路径填充新表时,在列的每一行中只复制最后一个选定的路径。
-不知道这意味着什么,“选择”按钮除了显示文件选择器外,什么都不做。我不知道如何测试代码。文件路径上的注释对我的初始程序有效。我对它进行了简化,使示例变得简单。问题在于您没有按照所述创建新字符串。正如我已经建议的,您不需要扩展AbstractTableModel。您不应该在setValueAt()方法中调用fireTableDataChanged(…)。有一种更合适的fireXXX方法可供使用。这一切都在DefaultTableModel中正确完成。只需使用DefaultTableModel来实现这样的基本功能。谢谢,你说得对。我已经用DefaultTableModel更新了答案(请参见编辑)。感谢camickr5和blueEOS。+不需要FileEditor类。如果您错了,必须从事件调度线程调用fireXXX。。。该错误是由于对每行使用相同的字符串数组造成的。谢谢你的否决票!我打赌你没有运行程序来解决问题。
fireXXX必须从事件调度线程调用
-正确。但是,TableModel(不是应用程序代码)负责调用fireXXX(…)方法。对TableModel的更新必须在EDT中完成
该错误是由于对每行使用相同的字符串数组造成的
-正确,但这不是否决票的目的。fireXXX()代码是错误的!另外,当你回答一个问题时,你应该陈述问题和解决方案,而不是仅仅发布几行随机的代码让每个人猜测问题是什么。
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;


public class FillTableExample extends JFrame {

private JLabel label = new JLabel("File:");
private JButton selectButton = new JButton("Select");
private JPanel labelButtonPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
private Object rowDataTable[][] = {{"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""}};
private String[] columnNames = {"File", "Name"};
private CustomTableModel fileTableModel = new CustomTableModel(rowDataTable, columnNames);
private JTable fileTable = new JTable(fileTableModel);
private JScrollPane scrollPane = new JScrollPane(fileTable);
private FillTable fillTableActionListener = new FillTable(fileTableModel);
private JPanel container = new JPanel();
private JCheckBox changeCol = new JCheckBox("ChangeCol");



public FillTableExample(){


    selectButton.addActionListener(fillTableActionListener);
    labelButtonPane.add(label);
    labelButtonPane.add(selectButton);

    changeCol.addActionListener(new DisplayPane());

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setExtendedState(MAXIMIZED_BOTH);
    this.setMinimumSize(new Dimension(400,400));
    this.setResizable(true);
    container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
    container.add(labelButtonPane);
    container.add(changeCol);
    container.add(scrollPane);
    this.setContentPane(container);
    this.setVisible(true);
}


public class CustomTableModel extends AbstractTableModel {

    private Object rowData[][];
    private String[] columnNames;

    public CustomTableModel(Object data[][], String[] titles){
        rowData = data;
        columnNames = titles;
    }

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

    public String getColumnName(int column) {
        return columnNames[column];
    }

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

    public Object getValueAt(int row, int column) {
        return rowData[row][column];
    }

    public Class getColumnClass(int column) {
        return this.rowData[0][column].getClass();
    }


    public int getColumnIndex(String columnName){
        return Arrays.asList(columnNames).indexOf(columnName);
    }

    public void setValueAt(Object value, int row, int column) {
        rowData[row][column] = value;
       fireTableDataChanged();
    }

    public boolean isCellEditable(int row, int column) {

        if(column == 0 && columnNames[0].equals("Sample Name"))
            return true;
        else
            return (column != 0);
    }
}

class DisplayPane implements ActionListener {


    public void actionPerformed(ActionEvent e){

        final String[] newColumnNames = {"File", "Name", "Extension"};

        for (int i = 0; i < rowDataTable.length; i++)
                rowDataTable[i] = new String[]{"", "", ""};
        fileTableModel = new CustomTableModel(rowDataTable, newColumnNames);

        fileTable.setModel(fileTableModel);
        fillTableActionListener.setModel(fileTableModel);
    }
}


class FillTable implements ActionListener {

    private CustomTableModel model;

    public FillTable(CustomTableModel model){

        this.model = model;
    }

    public void actionPerformed(ActionEvent e){

        final JFileChooser fc = new JFileChooser();
        int returnVal;

        fc.setMultiSelectionEnabled(true);
        returnVal = fc.showOpenDialog(FillTableExample.this);

        model.setValueAt("toto", 0, 0);
    }

    public void setModel(CustomTableModel model){
        this.model = model;
    }
}


public static void main(String[] args) {

    FillTableExample example = new FillTableExample();
    example.setVisible(true);
}
}
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;


public class FillTableExample2 extends JFrame {

private JLabel label = new JLabel("File:");
private JButton selectButton = new JButton("Select");
private JPanel labelButtonPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
private Object rowDataTable[][] = {{"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""},
        {"", ""}, {"", ""}, {"", ""}, {"", ""}};
private String[] columnNames = {"File", "Name"};
private DefaultTableModel fileTableModel = new DefaultTableModel(rowDataTable, columnNames);
private JTable fileTable = new JTable(fileTableModel);
private JScrollPane scrollPane = new JScrollPane(fileTable);
private FillTable fillTableActionListener = new FillTable(fileTableModel);
private JPanel container = new JPanel();
private JCheckBox changeCol = new JCheckBox("ChangeCol");



public FillTableExample2(){


    selectButton.addActionListener(fillTableActionListener);
    labelButtonPane.add(label);
    labelButtonPane.add(selectButton);

    changeCol.addActionListener(new DisplayPane());

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setExtendedState(MAXIMIZED_BOTH);
    this.setMinimumSize(new Dimension(400,400));
    this.setResizable(true);
    container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
    container.add(labelButtonPane);
    container.add(changeCol);
    container.add(scrollPane);
    this.setContentPane(container);
    this.setVisible(true);
}


class DisplayPane implements ActionListener {


    public void actionPerformed(ActionEvent e){
        fileTableModel.addColumn("Extension");
    }
}


class FillTable implements ActionListener {

    private DefaultTableModel model;

    public FillTable(DefaultTableModel model){

        this.model = model;
    }

    public void actionPerformed(ActionEvent e){

        final JFileChooser fc = new JFileChooser();
        int returnVal;

        fc.setMultiSelectionEnabled(true);
        returnVal = fc.showOpenDialog(FillTableExample2.this);

        model.setValueAt("toto", 0, 0);
    }
}

public static void main(String[] args) {

    FillTableExample2 example = new FillTableExample2();
    example.setVisible(true);
}
}