views:

495

answers:

6

i have a hashMap which i would like its data to be viewed in a JTable how ever i am having trouble getting the hashMap amount of columns and rows and the data to be displayed.i have a hashmap which takes a accountID as the key and a object of students in which each students have their data like name,id, age, etc.however referring to the JTable docs, it says i would need ints for the row and column and a multidimension array of type Object. how can i do it? can i change my hashMap into a multidimenion array?

--Edit i have edited my question so it could be more clear , i am fairly new to Java i do not really get what some of you have posted, especially since the work i am doing is quite related to OO and grasping OO concepts is my biggest challenge,

/I have a dataStorage class, the registered user is added to the HashMap with a Key input of his Username, which is getUser ./

import java.util.*;

public class DataStorage 
{
    HashMap<String, Student> students = new HashMap<String, Student>();  
    HashMap<String, Staff> staffMembers = new HashMap<String, Staff>();  
    //Default constructor
    public DataStorage(){
    }

    public void addStaffMember(Staff aAcc) 
    {
     staffMembers.put(aAcc.getUser(),aAcc);
    }

    public void addStudentMember(Student aAcc)
    {
     students.put(aAcc.getUser(),aAcc);
    }

   public Staff getStaffMember(String user)
   {
   return   staffMembers.get(user);
   }

   public Student getStudent(String user)
   {
    return students.get(user);
   }

   public int getStudentRows()
   {
        return students.size();
   }


}

/** This is a student class which extends Account*/

public class Student extends Account {

    private String studentNRIC;
    private String diploma;
    private String gender;
    private double level;
    private int credits;
    private int age;
    private boolean partTime;
    private boolean havePc;
    private boolean haveChild;

    public Student(String n, String nr, String id, String dep, String user, String pass)
    {
        super(n, dep, user, pass, id);
        studentNRIC = nr;
    }

    public void setPartTime(boolean state)
    {
        if(state == true)
        {
            partTime = true;
        }
        else
        {
            partTime = false;
        }
    }

    public boolean getPartTime()
    {
        return partTime;
    }

    public void setHavePc(boolean state)
    {
        if(state == true)
        {
            havePc = true;
        }
        else
        {
            havePc = false;
        }
    }

    public boolean getHavePc()
    {
        return havePc;
    }

    public void setHaveChild(boolean state)
    {
        if(state == true)
        {
            haveChild = true;
        }
        else
        {
            haveChild = false;
        }
    }

    public boolean getHaveChild()
    {
        return haveChild;
    }
    public void setDiploma(String dip)
    {
        diploma = dip;
    }

    public String getDiploma()
    {
        return diploma;
    }

    public void setCredits(String cre)
    {
        credits = Integer.parseInt(cre);
    }

    public int getCredits()
    {
        return credits;
    }

    public void setGender(String g)
    {
        gender = g;
    }

    public String getGender()
    {
        return gender;
    }

    public void setAge(String a)
    {
        age = Integer.parseInt(a);
    }

    public int getAge()
    {
        return age;
    }
    public void setLevel(String lvl)
    {
        level = Double.parseDouble(lvl);
    }

    public double getLevel()
    {
        return level;
    }
    public void setStudentNRIC(String nr)
    {
        studentNRIC = nr;
    }

    public String getStudentNRIC()
    {
        return studentNRIC;
    }

}

/** This is a the Account superclass*/

public class Account {

    private String name;
    private String department;
    private String username;
    private String password;
    private String accountID;
    public Account()
    {
    }   
    public Account(String nm,String dep,String user,String pass, String accID) 
    {
        name = nm;
        department = dep;
        username = user;
        password = pass;
        accountID = accID;

    }

    public void setName(String nm)
    {
        name = nm;
    }

    public String getName()
    {
        return name;
    }

    public void setDep(String d)
    {
        department = d;
    }

    public String getDep()
    {
        return department;
    }

    public void setUser(String u)
    {
        username = u;
    }
    public String getUser()
    {
        return username;
    }

    public void setPass(String p)
    {
        password = p;
    }

    public String getPass()
    {
        return password;
    }

    public void setAccID(String a)
    {
        accountID = a;
    }

    public String getAccID()
    {
        return accountID;
    }
}
A: 

Why not create an object that implements an interface in the fashion that JTable desires (an Object array), and provides a bridge to your existing map of Students ? So you can keep your existing data structure that is obviously working for you, and you're simply providing an adaptor for the benefit of the view (the JTable).

From the link:

An adapter allows classes to work together that normally could not because of incompatible interfaces, by providing its interface to clients while using the original interface. The adapter translates calls to its interface into calls to the original interface, and the amount of code necessary to do this is typically small. The adapter is also responsible for transforming data into appropriate forms.

I would try not to change a working data structure to fit with a particular GUI component (what happens if at a later stage you want to display via HTML or similar) but adapt to each view as a requirement comes up.

Brian Agnew
Good answer Brian, but since this is homework maybe it is too complicated. Give him some code to get started and I'll pimp your post with an upvote :)
willcodejavaforfood
@willcodejavaforfood - yes. I figured I wasn't answering the question *per se*, so much as providing a higher view of what's going on. I've +1ed your answer since you've written the code and I see no point in duplicating it :-)
Brian Agnew
@Brian - Cheers buddy. I'll find another of your answers and upvote that one instead :)
willcodejavaforfood
The TableModel is actually the adapter class, for a JTable and the data to display! The nice thing is also that when you change values through the GUI, they can be stored back into your data model! (see my sample code, in which public void setValueAt(Object value, int rowIndex, int columnIndex) would need an implementation. And modifing can be done per cell by providong an implementation for public boolean isCellEditable(int rowIndex, int columnIndex)!
Verhagen
+2  A: 

You have several options available to you here. I would probably build my own TableModel and convert the HashMap into a List, but that would require that accountID was part of Student and I cannot tell if it is from your post. So probably easier to create a multi dimensional array. To do this you need to examine every object in your HashMap and to do this we would use a 'loop'.

First create the array to hold your data:

Object[][] tableData = new Object[students.keySet().size()][numberOfColumns];

Replace numberOfColumns with the number of columns your table has.

int index = 0;
for (String key : students.keySet())
{
    Student student = students.get(key);
    tableData[index][0] = student.getXXX
    tableData[index][1] = student.getYYY
    tableData[index][2] = student.getZZZ
    // and so forth
    index++;
}

So what we do here is create a loop that will examine every key in the students HashMap and with that key we retrieve the Student object and populate the array with the correct data.

This is to answer your question, but I would recommend that you take a look at the TableModel interface and build one around your HashMap of Students. More manly :)

willcodejavaforfood
hello , yes students have access to accountID
kyrogue
A: 

The way to do this is by implementing the TableModel interface for the student register (aka SortedMap). The TableModel is the table model representation of how the Swing JTable expects its data. The TableModel interface, gives full flexibilty of providing that data.

Once that implementation is created, creating a JTable is straight on:

 // As StudentRegistration class
    new JTable(new StudentTableModel(studentRegistration));
    // Or as SortedMap<String, Student>
    new JTable(new StudentTableModel(students));

In this scenario I expect that the plain SortedMap<String, Student> is not directly given, but a instance of StudentRegistration, which contains a SortedMap<String, Student> like that.

/**
 * Models the {@link Student} entries as a Swing TableModel. 
 */
final public class StudentTableModel implements TableModel {
    /** The TableModel column names. */
    public final String columnNames[] = 
            new String[] {
                "Name", "Identification", "Age"
            };
    /** The list of TableModelListeners. */
    private final ArrayList tableModelListenerList = new ArrayList();
    /** The manager containing all the Student instances. */
    private final StudentRegistration register;


    public StudentTableModel(StudentRegistration register) {
        super();
        this.register = register;
    }


    public Class getColumnClass(int columnIndex) {
        return null;
    }


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

    public String getColumnName(int columnIndex) {
        return (columnIndex  studentMap = register.getStudents();
        String[] studentIdArray = studentMap.keySet().toArray(new String[studentMap.keySet().size()]);
        Student student = studentMap.get(studentIdArray[rowIndex]);
        final Object result;
        switch (columnIndex) {
            case 0:
                result = student.getName();
                break;
            case 1:
                result = student.getIdentification();
                break;
            case 2:
                result = student.getAge();
                break;
            default:
                result = null;
        }
        return result;
    }


    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        // Just ignore, model is read only.
    }


    public void addTableModelListener(TableModelListener tml) {
        if (! tableModelListenerList.contains(tml)) {
            tableModelListenerList.add(tml);
        }
    }

    public void removeTableModelListener(TableModelListener tml) {
        tableModelListenerList.remove(tml);
    }

}

PS: This sample comes partly from some other implementation, I just updated it to your scenario as described above. So it is quite possible that it contains some code glitzes. It is just provided to give you an idea on how a solution could look.

Verhagen
thanks for your input,however i do not understand most parts of the table model interface, pardon me, i have only just started java and the OO concepts are very hard to grasps. may i post a more elaborate post so maybe you can point me in the right direction
kyrogue
hi, i have attached a redit of my question, basically my GUI has a registration form so when registered i would put the information into the DataStorage hashmap student. and after that a staff would also be also to login and see the information of the student. and i have read that a JTable can be used to display data, however it needs Array of objects but i am using a HashMap, so i am totally stucked as how to retrieve the informations.
kyrogue
A: 

Your DataStorage is like the StudentRegistration is used in the sample code.

 // TIP: It can be handy to place the student in some order in the Map 
    //      (therefore using the sorted map).
    private SortedMap students = new TreeMap();  
    // QUESTION: Why not use argument name 'student'?
    public void addStudentMember(Student aAcc)
    {
        students.put(aAcc.getUser(),aAcc);
    }
    // Updated implementation
    public void addStudent(Student student)
    {
        students.put(student.getAccID(), student);
    }
 // QUESTION: Would a method name 'getNumberOfStudents' not be better?  
    public int getStudentRows()

For me it is a little unclear why Student extends from Account. The account identification, is that an unique-id, through the hole system? Do staff (users) and student (users) all have that as unique identification? Where / who creates them? If not the system self, it can never be guranteed that they also enter correctly into your system. Even when checking on uniqueness within your system, helps. But who say not someone else (by accedent) used someone else his/her unique id? (How are the student and staff (accounts) created? If these id's are indeed unique, why not use those for placing the student into a SortedMap? If the sorting is not important. Why not just use a List of students?

Is the name parameter unique (by which you place the student in the Map)?

Programming is little more then learning a programming language. As once understanding the OO-language Java it is good to read some more general programming books. In your specific case I would say start with Domain Driven Design. And then continue with books like these Test Driven Development, Refactoring to Patterns and Design Patterns.

Verhagen
the account Superclass contains common instances,like Name, Age,Gender whereby both Student and Staff created accounts will inherit, that is why i created that account and have staff and student extend them
kyrogue
public StudentTableModel(StudentRegistration register) { super(); this.register = register; }i do not understand that why would i need a call to the constructor of my DataStorage class? my DataStorage class constructor is null
kyrogue
Mmm, There is no call of new StudentRegistration(...) (aka DataStorage) there. Only a reference to that instance is required.
Verhagen
Would User or Person not be an better name instead of Account?
Verhagen
A: 
public class HashMapToJtable {
public static void main(String[] args) {
    final Map<String,String> st=new TreeMap<String, String>();
    st.put("1","one");
    st.put("2","two");
    st.put("3","three");
    JTable t=new JTable(toTableModel(st));
    JPanel p=new JPanel();
    p.add(t);
    JFrame f=new JFrame();
    f.add(p);
    f.setSize(200,200);
    f.setVisible(true);
}
public static TableModel toTableModel(Map<?,?> map) {
    DefaultTableModel model = new DefaultTableModel(
        new Object[] { "Key", "Value" }, 0
    );
    for (Map.Entry<?,?> entry : map.entrySet()) {
        model.addRow(new Object[] { entry.getKey(), entry.getValue() });
    }
    return model;
}
}

This is a sample code for populating a Jtable from a map.For your purpose you will have to override the toString method in your Student and Staff classes.

Emil
A: 

Going off of Emil's answer, but to support older version (tested with Java 1.3).

import javax.swing.*;
import java.util.*;
import javax.swing.table.*;

public class HashMapToJtable {
 public static void main(String[] args) {
  final Map st = new TreeMap();
  st.put("1","one");
  st.put("2","two");
  st.put("3","three");
  JTable t=new JTable(toTableModel(st));
  JPanel p=new JPanel();
  p.add(t);
  JFrame f=new JFrame();
  f.add(p);
  f.setSize(200,200);
  f.setVisible(true);
 }

 public static TableModel toTableModel(Map map) {
     DefaultTableModel model = new DefaultTableModel (
   new Object[] { "Key", "Value" }, 0
  );
  for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
   Map.Entry entry = (Map.Entry)it.next();
   model.addRow(new Object[] { entry.getKey(), entry.getValue() });
  }
  return model;
 }

}
Pyrite