Java 如何将hashMap与JTable一起使用

Java 如何将hashMap与JTable一起使用,java,swing,Java,Swing,我有一个hashMap,我希望它的数据可以在JTable中查看,无论我在获取列和行的hashMap数量以及要显示的数据方面有什么困难。我有一个hashMap,它以accountID为键,还有一个学生对象,其中每个学生都有自己的数据,如姓名、id、年龄、,然而在提到JTable文档时,它说我需要行和列的int以及Object类型的多维数组。我怎么做?我可以将hashMap更改为多维数组吗 --编辑我对我的问题进行了编辑,以便让问题更清楚,我对Java相当陌生,我并不真正了解你们中的一些人发布的内容

我有一个hashMap,我希望它的数据可以在JTable中查看,无论我在获取列和行的hashMap数量以及要显示的数据方面有什么困难。我有一个hashMap,它以accountID为键,还有一个学生对象,其中每个学生都有自己的数据,如姓名、id、年龄、,然而在提到JTable文档时,它说我需要行和列的int以及Object类型的多维数组。我怎么做?我可以将hashMap更改为多维数组吗

--编辑我对我的问题进行了编辑,以便让问题更清楚,我对Java相当陌生,我并不真正了解你们中的一些人发布的内容,特别是因为我正在做的工作与OO非常相关,掌握OO概念是我最大的挑战

/我有一个dataStorage类,注册用户被添加到HashMap中,并使用其用户名的键输入,即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();
   }


}
/****这是Account超类的一个示例***/

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

为什么不创建一个对象,以JTable希望的方式实现接口(一个
对象
数组),并为现有的学生地图提供一个桥梁?因此,您可以保留显然适合您的现有数据结构,并且您只需提供一个视图(JTable)

从链接:

适配器允许类工作 通常情况下,这两者不能结合在一起 由于接口不兼容 向客户提供其接口 在使用原始界面时。 适配器将调用转换为其 接口转换为对原始 接口,以及代码量 这样做通常是必要的 小的适配器也负责 用于将数据转换为适当的 表格


我会尽量不改变工作数据结构以适应特定的GUI组件(如果在以后的阶段您希望通过HTML或类似方式显示,会发生什么情况),而是根据需要调整每个视图。

您可以在这里使用多个选项。我可能会构建自己的
TableModel
并将
HashMap
转换为一个列表,但这需要
accountID
是Student的一部分,我无法判断它是否来自您的帖子。因此,创建多维数组可能更容易。为此,您需要检查
HashMap
中的每个对象,为此,我们将使用一个“循环”

首先创建阵列以保存数据:

Object[][] tableData = new Object[students.keySet().size()][numberOfColumns];
将numberOfColumns替换为表中的列数

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++;
}
因此,我们在这里要做的是创建一个循环,它将检查students HashMap中的每个键,并使用该键检索Student对象并用正确的数据填充数组


这是为了回答您的问题,但我建议您看看TableModel接口,并围绕学生的HashMap构建一个。更男性化:)

实现这一点的方法是为学生注册(也称为SortedMap)实现
TableModel
接口。
TableModel
是Swing JTable如何期望其数据的表模型表示。
TableModel
界面提供了提供该数据的充分灵活性

一旦创建了该实现,就可以直接创建
JTable

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

PS:这个示例部分来自其他一些实现,我刚刚将其更新为您的场景,如上所述。因此,它很可能包含一些代码亮点。提供它只是为了让您了解解决方案的外观。

您的
数据存储类似于示例代码中使用的
StudentRegistration

 // 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();  
对我来说,有点不清楚为什么
学生
扩展自
账户
。 帐户标识,是一个唯一的id,通过孔系统吗?员工(用户)和学生(用户)是否都将其作为唯一标识?在哪里/谁创建了它们?如果不是系统本身,则无法保证它们也正确地进入您的系统。即使在检查系统内的唯一性时,也会有所帮助。但谁说不是其他人(通过同意人)使用了其他人的唯一id?(学生和员工(账户)是如何创建的? 如果这些id确实是唯一的,为什么不使用这些id将学生放入分类地图? 如果排序不重要,为什么不使用学生列表呢

name参数是否唯一(用于将学生放置在地图中)

编程不仅仅是学习编程语言。一旦理解了OO语言Java,最好阅读一些更一般的编程书籍。在您的具体案例中,我会说从开始。然后继续阅读这些书籍,以及。

公共类HashMapToJtable{
公共静态void main(字符串[]args){
最终映射st=新树映射();
圣普特(“1”、“1”);
圣普特(“2”、“2”);
圣普特(“3”、“3”);
JTable t=新的JTable(toTableModel(st));
JPanel p=新的JPanel();
p、 加(t);
JFrame f=新的JFrame();
f、 加(p);
f、 设置大小(200200);
f、 setVisible(真);
}
公共静态表模型到表模型(地图){
DefaultTableModel=新的DefaultTableModel(
新对象[]{“键”,“值”},0
);
对于(Map.Entry:Map.entrySet()){
addRow(新对象[]{entry.getKey(),entry.getValue()});
}
收益模型;
}
}

这是一个用于从映射填充Jtable的示例代码。出于您的目的,您必须在学生和教职员工类中使用方法。

与Emil的答案不同,但要支持旧版本(使用Java 1.3测试)


回答得好,布莱恩,但既然这是家庭作业,可能太复杂了。给他一些代码让他开始,我会给你的帖子投上一票:)@willcodejavaforfood-是的。我想我并不是在回答问题本身,而是在提供一个更高的视角来看待正在发生的事情。我已经猜到你的答案了
/**
 * 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);
    }

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

}