2010-02-13 153 views
5

tengo un hashMap que me gustaría que sus datos se vean en una JTable, siempre tengo problemas para obtener la cantidad de columnas y filas de hashMap y los datos que se mostrarán. Tengo un hashmap que toma un accountID como la clave y un objeto de estudiantes en el que cada estudiante tiene sus datos como nombre, id, edad, etc., sin embargo, en referencia a los documentos de JTable, dice que necesitaría entradas para la fila y columna y una matriz multidimensional de tipo Object. ¿Cómo puedo hacerlo? ¿Puedo cambiar mi hashMap en una matriz multidimensional?cómo usar hashMap con JTable

- Edito mi pregunta por lo que podría ser más claro, soy bastante nuevo en Java realmente no entiendo lo que algunos de ustedes han publicado, sobre todo porque el trabajo que estoy haciendo está bastante relacionado con OO y captar los conceptos OO es mi mayor desafío,

/Tengo una clase dataStorage, el usuario registrado se agrega al HashMap con una entrada clave de su nombre de usuario, que es 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(); 
    } 


} 

/**** Esta es una clase de estudiante que se extiende Cuenta ***/

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; 
    } 

} 

/**** Esta es una superclase de la Cuenta ***/

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; 
    } 
} 
+0

Se muestra un ejemplo completo que extiende 'AbstractTableModel' [aquí] (http://stackoverflow.com/a/9134371/230513). – trashgod

Respuesta

3

por qué no crear un objeto que implementa una interfaz de la manera que desea JTable (una matriz Object), y proporciona un puente a su mapa existente de estudiantes? Para que pueda mantener su estructura de datos existente que obviamente está trabajando para usted, y simplemente está proporcionando un adaptor para el beneficio de la vista (la JTable).

Desde el enlace:

Un adaptador permite que las clases para trabajar juntos que normalmente no podrían porque interfaces incompatibles, por proporcionar su interfaz para clientes durante el uso de la interfaz original. El adaptador traduce las llamadas a su interfaz en llamadas a la interfaz original , y la cantidad de código necesaria para hacer esto suele ser pequeña. El adaptador también es responsable para transformar los datos en formularios apropiados .

me gustaría probar no para cambiar una estructura de datos de trabajo para encajar con un componente de interfaz gráfica de usuario en particular (lo que ocurre si en una etapa posterior desea mostrar a través de HTML o similar), pero adaptarse a cada vista como un requisito surge.

+0

Buena respuesta Brian, pero dado que esto es tarea, quizás sea demasiado complicado. Dale un poco de código para empezar y voy a proxenetismo con un voto positivo :) – willcodejavaforfood

+0

@willcodejavaforfood - sí. Pensé que no estaba respondiendo la pregunta * per se *, sino que ofrecía una visión más amplia de lo que estaba sucediendo. He +1ed tu respuesta desde que escribiste el código y no veo sentido duplicarlo :-) –

+0

Saludos amigo. Encontraré otra de tus respuestas y, por el contrario, la envié :): – willcodejavaforfood

7

Tiene a su disposición varias opciones aquí. Probablemente construiría mi propio TableModel y convertiría el HashMap en una lista, pero eso requeriría que accountID fuera parte de Student y no puedo decir si es de tu publicación. Probablemente sea más fácil crear una matriz multidimensional. Para hacer esto, necesita examinar cada objeto en su HashMap y para hacer esto, usaríamos un 'bucle'.

En primer lugar crear la matriz para que contenga sus datos:

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

Reemplazar NumberOfColumns con el número de columnas de la tabla tiene.

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++; 
} 

Así que lo que hacemos aquí es crear un bucle que va a examinar cada clave en los estudiantes HashMap y con esa clave recuperamos el objeto Student y rellenar la matriz con los datos correctos.

Esto es para responder a su pregunta, pero le recomendaría que eche un vistazo a la interfaz TableModel y compile una en su HashMap of Students. Más varonil :)

+0

hola, sí, los estudiantes tienen acceso a accountID – sutoL

+0

Se muestra un ejemplo completo que extiende 'AbstractTableModel' [aquí] (http://stackoverflow.com/a/9134371/230513). – trashgod

2

La forma de hacerlo es implementando la interfaz TableModel para el registro de estudiantes (también conocido como SortedMap). El TableModel es la representación del modelo de tabla de cómo Swing JTable espera sus datos. La interfaz TableModel brinda total flexibilidad para proporcionar esa información.

Una vez que se crea que la aplicación, la creación de un JTable es recto:

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

En este escenario espero que la llanura SortedMap<String, Student> no se da directamente, sino una instancia de StudentRegistration, que contiene una SortedMap<String, Student> como esa .

/** 
* 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<TableModelListener> tableModelListenerList = new ArrayList<TableModelListener>(); 
    /** 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 < columnNames.length) ? columnNames[columnIndex] : null; 
    } 

    public int getRowCount() { 
     return register.getStudents().size(); 
    } 


    public Object getValueAt(int rowIndex, int columnIndex) { 
     // One solution 
     String identification = register.getStudentIds().toArray()[rowIndex]; 
     Student student = register.getStudent(identification); 
     // Other option 
     SortedMap<String, Student> 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); 
    } 

} 

PD: Esta muestra proviene en parte de alguna otra implementación, la acabo de actualizar a su escenario como se describió anteriormente. Por lo tanto, es bastante posible que contenga algunos glitzes de código. Solo se proporciona para que tenga una idea de cómo se vería una solución.

+0

gracias por su aporte, sin embargo, no entiendo más partes de la interfaz del modelo de la tabla, perdóneme, acabo de comenzar Java y los conceptos de OO son muy difíciles de entender. ¿Puedo publicar una publicación más elaborada para que tal vez me puede señalar en la dirección correcta – sutoL

+0

hola, he adjuntado un A pesar de mi pregunta, básicamente mi GUI tiene un formulario de registro así que cuando esté registrado pondría la información en el estudiante de hashmap de DataStorage, y después de eso un miembro del personal también debe iniciar sesión y ver la información del alumno. y he leído que se puede usar una JTable para mostrar datos, sin embargo, necesita una matriz de objetos pero estoy usando una HashMap, por lo que estoy totalmente sorprendido de cómo recuperar la información. – sutoL

+0

Extendiendo 'AbstractTableModel' proporciona implementaciones de los mutadores' TableModelListener' a través de 'EventListenerList'; un ejemplo completo se muestra [aquí] (http://stackoverflow.com/a/9134371/230513). – trashgod

0

Su DataStorage es como StudentRegistration que se utiliza en el código de ejemplo.

// 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() 

Para mí es un poco claro por qué Student se extiende desde Account. La identificación de la cuenta, ¿es una identificación única, a través del sistema de agujeros? ¿El personal (usuarios) y los estudiantes (usuarios) tienen eso como una identificación única? ¿Dónde/quién los crea? Si no es el sistema, nunca se puede garantizar que también ingresen correctamente en su sistema. Incluso cuando verifica la exclusividad dentro de su sistema, ayuda. ¿Pero quién dice que no otra persona (por accedent) usó a alguien más su identificación única? (¿Cómo se crean el estudiante y el personal (cuentas)? Si estos identificadores son realmente únicos, ¿por qué no usarlos para ubicar al estudiante en un mapa ordenado? Si la clasificación no es importante. ¿Por qué no usar una lista de estudiantes?

es el parámetro de nombre único (por el cual se coloca al estudiante en el Mapa)?

la programación es poco más que el aprendizaje de un lenguaje de programación. Como una vez que la comprensión de la OO-lenguaje Java es bueno leer algo más general libros de programación. En su caso específico, yo diría que comience con Domain Driven Design. Y luego continúe con libros como estos Test Driven Development, Refactoring to Patterns y Design Patterns.

+0

la cuenta Superclass contiene instancias comunes, como Nombre, Edad, Sexo, por las cuales las cuentas creadas por el Estudiante y el Personal heredarán, es por eso que creé esa cuenta y el personal y el alumno la extienden – sutoL

+0

StudentTableModel público (registro de Registro de Estudiante) { super() ; this.register = register; } no entiendo por qué necesitaré una llamada al constructor de mi clase DataStorage? mi constructor de clase DataStorage es nulo – sutoL

+0

Mmm, no hay ninguna llamada de nuevo registro de estudiante (...) (también conocido como DataStorage) allí. Solo se requiere una referencia a esa instancia. – Verhagen

6
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; 
} 
} 

Este es un código de ejemplo para rellenar un JTable de un map.For su propósito tendrá que override the toString método en su estudiante y clases de personal.

2

Saliendo de la respuesta de Emil, pero para admitir una versión anterior (probada con 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; 
} 

}