Afroid1000
Afroid1000

Reputation: 169

JAVA SWING: Vector used in Default Table Model fails to addElement() added through a for loop

Two Jtables in this example show a challenge am facing. Simply put,one table is a Master table while the second depends on the Master table data. Master table contains data which on column 3 is Boolean, the purpose of the second table is simply to display all data that on column 3 which is true(Names of all Males). In other words, all data that is false as far as column 3 on Master table is concerned is not to be displayed. The problem is that when I ran the code, only one element is displayed in the second table while other data which is 'Boolean=true' is ignored as shown below. enter image description here

What might be wrong with my code which fails to display all Boolean true data on the second table.NOTE: I also tried to used the DefaultTableModel addRow() method within the loop but also failed to display all data that is true from MasterTable Column 3.

public class ZoomTable extends JFrame{

    JPanel panel;
    Object [] masterColumns = new Object []{"Name","Age","Male"};
    Object [][] masterData = new Object [][]{
       {"Simon",10,new Boolean(true)},
       {"Jane",10,new Boolean(false)},
       {"Hellen",10,new Boolean(false)},
       {"Amos",10,new Boolean(true)},
       {"Brenda",10,new Boolean(false)},
       {"Dennis",10,new Boolean(true)},
       {"Mary",10,new Boolean(false)},
       };
    MasterTableModel mtm = new MasterTableModel(masterData,masterColumns);
    Vector<Vector> maleListData = new Vector<Vector>();
    Vector maleList = new Vector();
    public static void main(String[] args) {
       ZoomTable zoom = new ZoomTable();
       zoom.init();
       zoom.setVisible(true);
       zoom.setSize(new Dimension(600,800));
       zoom.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    void init(){
        panel = new JPanel();
        panel.setLayout(new BorderLayout());
        JTable masterTable = new JTable(masterData,masterColumns);
        JScrollPane spMaster = new JScrollPane();
        spMaster.setViewportView(masterTable);
        panel.add(spMaster,"North");

        Vector <String> tinyColumns = new Vector <String>();       
        tinyColumns.addElement("NAMES OF MALES");

        DefaultTableModel dtm = new           DefaultTableModel(maleListVector(),tinyColumns);
        JTable tinyTable = new JTable(dtm); 
        JScrollPane spTiny = new JScrollPane();
        spTiny.setViewportView(tinyTable);
        panel.add(spTiny,"Center");
        add(panel);
        pack();
    }

    public Vector maleListVector(){
        for(int k = 0;k < mtm.getRowCount();k++){

            if(mtm.getValueAt(k,2).equals(true)){
                String maleName = mtm.getValueAt(k,0).toString();
                maleList.addElement(maleName);
            System.out.println(maleName+" is Male");
            }
            else if(mtm.getValueAt(k,2).equals(false)){
                String femaleName = mtm.getValueAt(k,0).toString();
              System.out.println(femaleName+" is Female");
            }


         }
        maleListData.add(maleList);
     return maleListData;}
}

class MasterTableModel extends AbstractTableModel{
    Object [][] data;
    Object [] cols;

    MasterTableModel(Object[][] masterData, Object[] masterColumns) {
       data = masterData;
       cols = masterColumns;
    }

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

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

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

 }

Upvotes: 1

Views: 1236

Answers (2)

Dan
Dan

Reputation: 7744

As mentioned in other answers, the specific problem here is you were only ever adding the first element of the vector to your maleListData. To fix this you could either create a vector with one element in, like camickr did, and add this to your maleListData in each iteration of your for loop. Or you could use the addAll method with a little modification of your code.


Some suggestions. Make your code a little more OOP. The use of generics and keywords to do with scope, like private, can make your code more readable and easier to understand. It also prevents it being used in the wrong way.

In this case by use of generics I mean specifying to types of your vectors so that IDEs like Eclipse don't throw a load of warnings at you.

For example, with your fixed class.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Vector;

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

@SuppressWarnings("serial")
public class ZoomTable extends JFrame{
    private JPanel panel;
    private Object[] masterColumns = new Object[]{"Name","Age","Male"};
    private Object[][] masterData = new Object[][]{
        {"Simon", 10, true},
        {"Jane", 10, false},
        {"Hellen", 10, false},
        {"Amos",10, true},
        {"Brenda",10, false},
        {"Dennis",10, true},
        {"Mary",10, false},
    };
    private MasterTableModel mtm = new MasterTableModel(masterData,masterColumns);
    private Vector<Vector<Object>> maleListData = new Vector<Vector<Object>>();

    public static void main(String[] args) {
        ZoomTable zoom = new ZoomTable();
        zoom.init();
        zoom.setVisible(true);
        zoom.setSize(new Dimension(600,800));
        zoom.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void init(){
        panel = new JPanel();
        panel.setLayout(new BorderLayout());
        JTable masterTable = new JTable(masterData,masterColumns);
        JScrollPane spMaster = new JScrollPane();
        spMaster.setViewportView(masterTable);
        panel.add(spMaster,"North");

        Vector <String> tinyColumns = new Vector <String>();       
        tinyColumns.addElement("NAMES OF MALES");

        DefaultTableModel dtm = new DefaultTableModel(maleListVector(), tinyColumns);
        JTable tinyTable = new JTable(dtm); 
        JScrollPane spTiny = new JScrollPane();
        spTiny.setViewportView(tinyTable);
        panel.add(spTiny,"Center");
        add(panel);
        pack();
    }

    private Vector<Vector<Object>> maleListVector(){
        for(int k = 0;k < mtm.getRowCount();k++){
            if(mtm.getValueAt(k, 2).equals(true)){
                String maleName = mtm.getValueAt(k, 0).toString();
                Vector<Object> name = new Vector<Object>();
                name.add(maleName);
                maleListData.addElement(name);
                System.out.println(maleName + " is Male");
            } else if(mtm.getValueAt(k, 2).equals(false)){
                String femaleName = mtm.getValueAt(k, 0).toString();
                System.out.println(femaleName + " is Female");
            }
        }
        return maleListData;
    }

    private class MasterTableModel extends AbstractTableModel{
        Object[][] data;
        Object[] cols;

        MasterTableModel(Object[][] masterData, Object[] masterColumns) {
            data = masterData;
            cols = masterColumns;
        }

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

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

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

Upvotes: 1

camickr
camickr

Reputation: 324197

The data for the DefaultTableModel is a Vector of Vectors.

You only ever add one Vector to the "maleListData" so this means you have a single row with multiple columns of data.

This is easy to verify. Just change your code to:

tinyColumns.addElement("NAMES OF MALES");
tinyColumns.addElement("2");

and you will see another column of data.

So the solution to your problem is to add a new row of data to the Vector for every male item you find:

//maleList.addElement(maleName);
Vector row = new Vector(1);
row.add(maleName);
maleListData.addElement( row );

...

//maleListData.add(maleList);

Upvotes: 1

Related Questions