java same ArrayList for multiple table model

我只是一个虾纸丫 提交于 2019-12-10 11:25:08

问题


I am struggling to avoid data duplication with multiple JTable. Basically I have a TableModel which has an arraylist of data and a string[] header.

So far nothing new. Now I have another TableModel which has the same arraylist of data BUT a different string[] header.

I can't make my code to work. I would appreciate some idea on how to share the arrayList of data across multiple table model.

So when I change the data all models are updated and there isn't data duplication. I would like to avoid copy of arraylist any idea or am I wrong with this setup? I did try listener but I think going that way we still have data duplication across table model.

public class GymTableModel extends AbstractTableModel {
    private final ResourceBundle name = ResourceBundle.getBundle("labels/TableLabel", Locale.getDefault());
    private final String[] entete = {
        name.getString("LNAME"),
        name.getString("FNAME"),
        name.getString("CONTACT"),
        name.getString("TELFIX"),
        name.getString("TELGSM"),
        name.getString("EMAIL"),
        name.getString("BDATE"),
        name.getString("EDATE"),
        name.getString("LICENSE"),
        name.getString("AGE"),
        name.getString("ANCIEN")
    };

    @Override
    public Class<?> getColumnClass(int columnIndex){
        switch(columnIndex){
            case 6:
                return Date.class;
            case 7:
                return Date.class;
            case 9:
                return Integer.class;
            default:
                return Object.class;
        }
    }

    @Override
    public int getRowCount() {
        return gymList.size();
    }

    @Override
    public int getColumnCount() {
        return entete.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch(columnIndex){
            case 0:
                return gymList.get(rowIndex).getLastName();
            case 1:
                return gymList.get(rowIndex).getFirstName();
            case 2:
                return gymList.get(rowIndex).getContact();
            case 3:
                return gymList.get(rowIndex).getTelFix();
            case 4:
                return gymList.get(rowIndex).getTelGsm();
            case 5:
                return gymList.get(rowIndex).getEmail();
            case 6:
                return gymList.get(rowIndex).getDateBirth();
            case 7:
                return gymList.get(rowIndex).getDateClub();
            case 8:
                return gymList.get(rowIndex).getLicence();
            case 9:
                return gymList.get(rowIndex).getAge();
            case 10:
                return gymList.get(rowIndex).getAnciennete();
            default:
                return null; // should never happen;
        }
    }

    public String getColumnName(int columnIndex){
        return entete[columnIndex];
    }

}

Now I have another table which has same data but only 3 columns (LNAME, FNAME and AGE) so getColumnClass isn't same. Question is, can I share my gymList data (which is an arrayList) with another table model? Thankyou


回答1:


Using Che's answer as a basis for a main table containing four columns then your code should be something like:

AllTableModel model = new AllTableModel();
JTable mainTable = new JTable( model );

If you want another View of the model then you create a new view not a new model. So the code would be:

JTable studentTable = new JTable( model );
studentTable.removeColumn( studentTable.getColumn("Subject") );
studentTable.removeColumn( studentTable.getColumn("Staff") );

Now the Student table will only contain the "Name" and "Grade" columns.

This is the basis behind MVC programming. That is you can easily change the View of the Model. So you are sharing 1 model not sharing the data of 3 separate models.




回答2:


You need to register TableModelListener to the Tablemodel of both JTables.. So that whenever one of the table's cell value is changed the same could be reflected in other via repaint() method of JTable. For example consider the code given below:

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.JScrollPane;
import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import java.awt.Container;
import java.awt.GridLayout;
import java.util.ArrayList;
public class TablesHavingSameData extends JFrame implements TableModelListener
{
    MyTableModel model1;
    MyTableModel model2;
    JTable table1;
    JTable table2;
    ArrayList<ArrayList<String>> data;
    public void createAndShowGUI()
    {
        setTitle("JTables");
        Container c  = getContentPane();
        c.setLayout(new GridLayout(2,1));
        prepareData();
        model1 = new MyTableModel("table1");
        model2 = new MyTableModel("table2");
        table1 = new JTable(model1);
        table2 = new JTable(model2);
        model1.addTableModelListener(this);
        model2.addTableModelListener(this);
        JScrollPane jsTable1 = new JScrollPane(table1);
        JScrollPane jsTable2 = new JScrollPane(table2);
        c.add(jsTable1);
        c.add(jsTable2);
        setSize(500,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    @Override
    public void tableChanged(TableModelEvent evt)
    {
        AbstractTableModel model = (MyTableModel)evt.getSource();
        if (model == model1)
        {
            table2.repaint();
        }
        else
            table1.repaint();
    }
    private void prepareData()
    {
        data = new ArrayList<ArrayList<String>>();
        data.add(new ArrayList<String>(){{add("1");add("Michael");}});
        data.add(new ArrayList<String>(){{add("2");add("Derake");}});
        data.add(new ArrayList<String>(){{add("3");add("Archie");}});
    }
    private class MyTableModel extends AbstractTableModel
    {
        String columns[] ;
        String sTableName;
        public MyTableModel(String tableName)
        {
            sTableName = tableName;
            if ("table1".equals(sTableName))
            {
                columns = new String[] {"Roll No.","Name"};
            }
            else
            {
                columns = new String[] {"Emp ID.","Employee Name"};
            }
        }
        @Override
        public String getColumnName(int columnIndex)
        {
            return columns[columnIndex];
        }
        @Override
        public int getRowCount()
        {
            return data.size();
        }
        @Override 
        public int getColumnCount()
        {
            return columns.length;
        }
        @Override
        public Object getValueAt(int row, int col)
        {
            return data.get(row).get(col);
        }
        @Override
        public void setValueAt(Object aValue, int rowIndex, int colIndex)
        {
            data.get(rowIndex).set(colIndex,(String)aValue);
            fireTableCellUpdated(rowIndex,colIndex);
        }
        @Override
        public boolean isCellEditable(int row, int col)
        {
            return true;
        }
    }
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                TablesHavingSameData ths = new TablesHavingSameData();
                ths.createAndShowGUI();
            }
        });
    }
}



回答3:


I have used a table model which stores all the rows, another table model which store only student details and the third table model which stores staff details. All of them get the data from the same source but showing of columns is different foe each table.

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;


public class AllTableExample {

    private JTabbedPane tabbedPane;
    private JTable allTable;
    private JTable studentTable;
    private JTable staffTable;

    public AllTableExample() {
        setData();

        allTable = new JTable();
        studentTable = new JTable();
        staffTable = new JTable();
    }

    public void createUI() {
        JFrame frame = new JFrame();

        tabbedPane = new JTabbedPane();

        tabbedPane.add("All", getAllTablePanel());
        tabbedPane.add("Student", getStudentTablePanel());
        tabbedPane.add("Staff", getStaffTablePanel());

        frame.add(tabbedPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Table Model Example.");
        frame.pack();
        frame.setVisible(true);
    }

    private void setData() {
        List<TableData> data = new ArrayList<TableData>();
        data.add(new TableData("John1", "A", "Maths", "Hellen1"));
        data.add(new TableData("John2", "A", "Maths", "Hellen2"));
        data.add(new TableData("John3", "A", "Maths", "Hellen3"));
        data.add(new TableData("John4", "A", "Maths", "Hellen4"));
        data.add(new TableData("John5", "A", "Maths", "Hellen5"));

        MainDataClass.getInstance().setData(data);
    }

    private JPanel getAllTablePanel() {
        JPanel panel = new JPanel();
        JTable table = new JTable(new AllTableModel());
        JScrollPane scroll = new JScrollPane(table);
        panel.add(scroll);

        return panel;
    }

    private JPanel getStudentTablePanel() {
        JPanel panel = new JPanel();
        JTable table = new JTable(new StudentTableModel());
        JScrollPane scroll = new JScrollPane(table);
        panel.add(scroll);

        return panel;
    }

    private JPanel getStaffTablePanel() {
        JPanel panel = new JPanel();
        JTable table = new JTable(new StaffTableModel());
        JScrollPane scroll = new JScrollPane(table);
        panel.add(scroll);

        return panel;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new AllTableExample().createUI();
            }
        };

        EventQueue.invokeLater(r);
    }

}


class AllTableModel extends AbstractTableModel {

    List<TableData> tableData = new ArrayList<TableData>();

    Object[] columnNames = {"Name", "Grade", "Subject", "Staff"};

    public AllTableModel() {
        tableData = MainDataClass.getInstance().getData();
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column].toString();
    }

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

    @Override
    public int getRowCount() {
        return tableData.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        TableData data = tableData.get(rowIndex);
        switch (columnIndex) {
        case 0:
            return data.getName();
        case 1:
            return data.getGrade();
        case 2:
            return data.getSubject();
        case 3:
            return data.getStaff();
        default:
            return null;
        }
    }

}

class StudentTableModel extends AbstractTableModel {

    List<TableData> tableData = new ArrayList<TableData>();

    Object[] columnNames = {"Name", "Grade"};

    public StudentTableModel() {
        tableData = MainDataClass.getInstance().getData();
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column].toString();
    }

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

    @Override
    public int getRowCount() {
        return tableData.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        TableData data = tableData.get(rowIndex);
        switch (columnIndex) {
        case 0:
            return data.getName();
        case 1:
            return data.getGrade();
        default:
            return null;
        }
    }
}

class StaffTableModel extends AbstractTableModel {

    List<TableData> tableData = new ArrayList<TableData>();

    Object[] columnNames = {"Subject", "Staff"};

    public StaffTableModel() {
        tableData = MainDataClass.getInstance().getData();
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column].toString();
    }

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

    @Override
    public int getRowCount() {
        return tableData.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        TableData data = tableData.get(rowIndex);
        switch (columnIndex) {
        case 0:
            return data.getSubject();
        case 1:
            return data.getStaff();
        default:
            return null;
        }
    }
}

class TableData {

    private String name;
    private String grade;
    private String subject;
    private String staff;

    public TableData(String name, String grade, String subject, String staff) {
        super();
        this.name = name;
        this.grade = grade;
        this.subject = subject;
        this.staff = staff;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGrade() {
        return grade;
    }
    public void setGrade(String grade) {
        this.grade = grade;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getStaff() {
        return staff;
    }
    public void setStaff(String staff) {
        this.staff = staff;
    }
}

class MainDataClass {

    private static MainDataClass mainDataClass;
    private List<TableData> data;

    private MainDataClass() {

    }

    public static MainDataClass getInstance() {
        if(null == mainDataClass) {
            mainDataClass = new MainDataClass();
        }
        return mainDataClass;
    }

    public List<TableData> getData() {
        return data;
    }

    public void setData(List<TableData> data) {
        this.data = data;
    }
}

EDIT-2:

Referring @camickr explanation of using only one model I tried this one and it worked. Use removeColumn method it worked like a charm.

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;


public class AllTableExample {


    private JTabbedPane tabbedPane;
    private JTable allTable;
    private JTable studentTable;
    private JTable staffTable;
    private AllTableModel allTableModel;

    public AllTableExample() {
        allTable = new JTable();
        studentTable = new JTable();
        staffTable = new JTable();

        allTableModel = new AllTableModel();
    }

    public void createUI() {
        JFrame frame = new JFrame();

        tabbedPane = new JTabbedPane();

        tabbedPane.add("All", getAllTablePanel());
        tabbedPane.add("Student", getStudentTablePanel());
        tabbedPane.add("Staff", getStaffTablePanel());

        frame.add(tabbedPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Table Model Example.");
        frame.pack();
        frame.setVisible(true);
    }

    private JPanel getAllTablePanel() {
        JPanel panel = new JPanel();
        JTable table = new JTable(allTableModel);
        JScrollPane scroll = new JScrollPane(table);
        panel.add(scroll);

        return panel;
    }

    private JPanel getStudentTablePanel() {
        JPanel panel = new JPanel();
        JTable table = new JTable(allTableModel);
        table.removeColumn(table.getColumn("Subject"));
        table.removeColumn(table.getColumn("Staff"));
        JScrollPane scroll = new JScrollPane(table);
        panel.add(scroll);

        return panel;
    }

    private JPanel getStaffTablePanel() {
        JPanel panel = new JPanel();
        JTable table = new JTable(allTableModel);
        table.removeColumn(table.getColumn("Name"));
        table.removeColumn(table.getColumn("Grade"));
        JScrollPane scroll = new JScrollPane(table);
        panel.add(scroll);

        return panel;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new AllTableExample().createUI();
            }
        };

        EventQueue.invokeLater(r);
    }

}


class AllTableModel extends AbstractTableModel {

    List<TableData> tableData = new ArrayList<TableData>();

    Object[] columnNames = {"Name", "Grade", "Subject", "Staff"};

    public AllTableModel() {
        List<TableData> data = new ArrayList<TableData>();
        data.add(new TableData("John1", "A", "Maths", "Hellen1"));
        data.add(new TableData("John2", "A", "Maths", "Hellen2"));
        data.add(new TableData("John3", "A", "Maths", "Hellen3"));
        data.add(new TableData("John4", "A", "Maths", "Hellen4"));
        data.add(new TableData("John5", "A", "Maths", "Hellen5"));
        tableData = data;
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column].toString();
    }

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

    @Override
    public int getRowCount() {
        return tableData.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        TableData data = tableData.get(rowIndex);
        switch (columnIndex) {
        case 0:
            return data.getName();
        case 1:
            return data.getGrade();
        case 2:
            return data.getSubject();
        case 3:
            return data.getStaff();
        default:
            return null;
        }
    }

}

class TableData {

    private String name;
    private String grade;
    private String subject;
    private String staff;

    public TableData(String name, String grade, String subject, String staff) {
        super();
        this.name = name;
        this.grade = grade;
        this.subject = subject;
        this.staff = staff;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGrade() {
        return grade;
    }
    public void setGrade(String grade) {
        this.grade = grade;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getStaff() {
        return staff;
    }
    public void setStaff(String staff) {
        this.staff = staff;
    }
}

class MainDataClass {

    private static MainDataClass mainDataClass;
    private List<TableData> data;

    private MainDataClass() {

    }

    public static MainDataClass getInstance() {
        if(null == mainDataClass) {
            mainDataClass = new MainDataClass();
        }
        return mainDataClass;
    }

    public List<TableData> getData() {
        return data;
    }

    public void setData(List<TableData> data) {
        this.data = data;
    }
}



回答4:


Small example of the same data with different column names:

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

public class TestTable {

    public static class MyModel extends AbstractTableModel {

        private List<Object[]> data;
        private List<String> columnNames;

        public MyModel(List<String> columnNames, List<Object[]> data) {
            super();
            this.columnNames = columnNames;
            this.data = data;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public int getColumnCount() {
            return columnNames.size();
        }

        @Override
        public String getColumnName(int column) {
            return columnNames.get(column);
        }

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

    }

    protected void initUI() {
        JFrame frame = new JFrame(TestTable.class.getSimpleName());
        List<String> columns = Arrays.asList("Name", "Age");
        List<String> columns2 = Arrays.asList("Label", "Price");
        List<Object[]> data = new ArrayList<Object[]>();
        for (int i = 0; i < 50; i++) {
            Object[] value = new Object[2];
            value[0] = "Something-" + i;
            value[1] = 12 + i;
            data.add(value);
        }
        JTable table = new JTable(new MyModel(columns, data));
        JTable table2 = new JTable(new MyModel(columns2, data));
        frame.add(new JScrollPane(table), BorderLayout.WEST);
        frame.add(new JScrollPane(table2), BorderLayout.EAST);
        frame.pack();
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                new TestTable().initUI();
            }
        });
    }
}


来源:https://stackoverflow.com/questions/15313240/java-same-arraylist-for-multiple-table-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!