6 Stimmen

Wie man hashMap mit JTable verwendet

Ich habe eine HashMap, deren Daten ich gerne in einer JTable anzeigen würde. Allerdings habe ich Probleme damit, die Anzahl der Spalten und Zeilen der HashMap sowie die Daten angezeigt zu bekommen. Ich habe eine HashMap, die eine Konto-ID als Schlüssel nimmt und ein Objekt von Studenten enthält, bei dem jeder Schüler Daten wie Name, ID, Alter usw. hat. Wenn ich jedoch die JTable-Dokumente konsultiere, heißt es, dass ich ints für die Zeile und Spalte sowie ein multidimensionales Array vom Typ Object benötigen würde. Wie kann ich das machen? Kann ich meine HashMap in ein multidimensionales Array ändern?

--Edit Ich habe meine Frage bearbeitet, damit sie klarer wird, ich bin ziemlich neu in Java und habe nicht wirklich verstanden, was einige von euch gepostet haben, besonders da die Arbeit, die ich mache, ziemlich mit OO zusammenhängt und das Erfassen von OO-Konzepten meine größte Herausforderung ist.

/Ich habe eine DatenSpeicher-Klasse, der registrierte Benutzer wird der HashMap mit einem Schlüssel hinzugefügt, der seinem Benutzernamen entspricht, der getUser ist./

import java.util.*;

public class DataStorage 
{
    HashMap students = new HashMap();  
    HashMap staffMembers = new HashMap();  
    //Standardkonstruktor
    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();
   }

}

/**** Dies ist eine Studentenklasse, die von Konto erbt***/

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

}

/**** Dies ist eine die Account-Superklasse***/

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 Stimmen

Ein vollständiges Beispiel, das AbstractTableModel erweitert, ist hier zu sehen.

9voto

Emil Punkte 13139
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 (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.

8voto

willcodejavaforfood Punkte 41426

Sie haben hier mehrere Optionen zur Verfügung. Ich würde wahrscheinlich mein eigenes TableModel erstellen und die HashMap in eine Liste umwandeln, aber dafür müsste accountID Teil von Student sein und ich kann nicht erkennen, ob dies aus Ihrem Beitrag hervorgeht. Wahrscheinlich einfacher wäre es also, ein mehrdimensionales Array zu erstellen. Dazu müssen Sie jedes Objekt in Ihrer HashMap überprüfen und dies würde einen 'loop' erfordern.

Erstellen Sie zunächst das Array, um Ihre Daten zu speichern:

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

Ersetzen Sie numberOfColumns durch die Anzahl der Spalten in Ihrer Tabelle.

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
    // und so weiter
    index++;
}

Also, was wir hier tun, ist eine Schleife zu erstellen, die jeden Schlüssel in der students HashMap überprüft und mit diesem Schlüssel das Studentenobjekt abruft und das Array mit den korrekten Daten füllt.

Dies soll Ihre Frage beantworten, aber ich würde empfehlen, dass Sie einen Blick auf das TableModel-Interface werfen und eines um Ihre HashMap von Studenten erstellen. Mehr männlich :)

0 Stimmen

Hallo, ja, die Schüler haben Zugriff auf die Kontonummer

0 Stimmen

Ein vollständiges Beispiel, das AbstractTableModel erweitert, ist hier zu sehen.

3voto

Brian Agnew Punkte 260470

Warum erstellen Sie nicht ein Objekt, das eine Schnittstelle auf die von JTable gewünschte Weise implementiert (ein Object-Array) und eine Brücke zu Ihrer vorhandenen Map von Studenten bereitstellt? So können Sie Ihre bestehende Datenstruktur beibehalten, die offensichtlich gut für Sie funktioniert, und einfach einen Adapter zum Nutzen der Ansicht (des JTables) bereitstellen.

Von dem Link:

Ein Adapter ermöglicht es Klassen zusammenzuarbeiten, die normalerweise nicht zusammenarbeiten könnten, aufgrund inkompatibler Schnittstellen, indem sie ihre Schnittstelle den Clienten zur Verfügung stellen, während sie die ursprüngliche Schnittstelle verwenden. Der Adapter übersetzt Aufrufe seiner Schnittstelle in Aufrufe der ursprünglichen Schnittstelle, und der Code, der dafür benötigt wird, ist normalerweise gering. Der Adapter ist auch dafür verantwortlich, Daten in angemessene Formen umzuwandeln.

Ich würde versuchen, nicht eine funktionierende Datenstruktur zu ändern, um zu einem bestimmten GUI-Komponenten zu passen (was passiert, wenn Sie später über HTML oder ähnliches anzeigen möchten), sondern mich jeder Ansicht anzupassen, wenn eine Anforderung entsteht.

0 Stimmen

Gute Antwort Brian, aber da dies Hausaufgaben sind, ist es vielleicht zu kompliziert. Gib ihm etwas Code, um anzufangen, und ich werde deinen Beitrag mit einem Upvote aufpeppen :)

0 Stimmen

@willcodejavaforfood - ja. Ich habe mir gedacht, dass ich die Frage an sich nicht beantworte, sondern eher einen höheren Überblick darüber gebe, was passiert. Ich habe deine Antwort +1 gegeben, da du den Code geschrieben hast und ich keinen Sinn darin sehe, ihn zu duplizieren :-)

0 Stimmen

Prost Kumpel. Ich werde eine weitere deiner Antworten finden und stattdessen hochwerten :)

2voto

Verhagen Punkte 3787

Der Weg, dies zu tun, besteht darin, das TableModel-Interface für das Schülerregister (auch bekannt als SortedMap) zu implementieren. Das TableModel ist die tabellarische Modellrepräsentation, wie die Swing JTable ihre Daten erwartet. Das TableModel-Interface bietet die volle Flexibilität, um diese Daten bereitzustellen.

Sobald diese Implementierung erstellt ist, ist die Erstellung einer JTable ganz einfach:

// Als StudentRegistration-Klasse
new JTable(new StudentTableModel(studentRegistration));
// Oder als SortedMap
new JTable(new StudentTableModel(students));

In diesem Szenario erwarte ich, dass die einfache SortedMap nicht direkt übergeben wird, sondern eine Instanz von StudentRegistration, die eine SortedMap darstellt, enthält.

/**
 * Modelliert die {@link Student}-Einträge als Swing TableModel. 
 */
final public class StudentTableModel implements TableModel {
    /** Die Spaltennamen des TableModels. */
    public final String columnNames[] = 
            new String[] {
                "Name", "Identifikation", "Alter"
            };
    /** Die Liste der TableModelListener. */
    private final ArrayList tableModelListenerList = new ArrayList();
    /** Der Manager, der alle Studenteninstanzen enthält. */
    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) {
        // Eine Lösung
        String identification = register.getStudentIds().toArray()[rowIndex];
        Student student = register.getStudent(identification);
        // Andere Option
        SortedMap 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) {
        // Einfach ignorieren, das Modell ist schreibgeschützt.
    }   

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

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

}

PS: Dieses Beispiel stammt teilweise aus einer anderen Implementierung, die ich einfach an Ihr beschriebenes Szenario angepasst habe. Es ist daher möglich, dass es einige Codefehler enthält. Es dient lediglich dazu, Ihnen eine Vorstellung davon zu geben, wie eine Lösung aussehen könnte.

0 Stimmen

Vielen Dank für Ihr Feedback, aber ich verstehe die meisten Teile der Tabellenmodel-Schnittstelle nicht. Verzeihen Sie mir, ich habe gerade erst mit Java begonnen und die OO-Konzepte sind sehr schwer zu erfassen. Darf ich einen ausführlicheren Beitrag verfassen, damit Sie mir vielleicht den richtigen Weg zeigen können?

0 Stimmen

Hallo, ich habe einen Überblick über meine Frage angehängt. Grundsätzlich hat mein GUI ein Registrierungsformular. Wenn sich ein Benutzer registriert, würde ich die Informationen in den DataStorage-HashMap "student" eintragen. Danach könnte sich auch ein Mitarbeiter anmelden und die Informationen des Schülers sehen. Ich habe gelesen, dass eine JTable verwendet werden kann, um Daten anzuzeigen, jedoch benötigt sie ein Array von Objekten, aber ich verwende eine HashMap. Daher stecke ich total fest, wie ich die Informationen abrufen kann.

0 Stimmen

Das Erweitern von AbstractTableModel bietet Implementierungen der Mutatoren von TableModelListener über EventListenerList; ein vollständiges Beispiel ist hier gezeigt.

2voto

Pyrite Punkte 43

Basierend auf Emils Antwort, aber zur Unterstützung älterer Versionen (getestet mit 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;
 }

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X