【问题标题】:Java JTable binding via JPA通过 JPA 绑定 Java JTable
【发布时间】:2011-07-07 21:25:37
【问题描述】:

我试图寻找正确的答案,但到目前为止没有任何帮助。我对 java GUI 编程很陌生,实际上,对 java 本身.. 然而,我有管理人员了解 JPA,如何使用 JPA 检索、插入和删除。

现在我希望将数据库中的数据显示在 JTable 中。

我目前有以下 mySQL 表(我想在 JTable 中显示它

游戏 Id PK 整数 标题 出版商 类型 发布日期

就编码问题而言,我已使用以下方法成功检索到表中包含的数据:

public List<Game> getGames(){
    List<Game> games;

    try{
        TypedQuery<Game> selectGamesQuery = entityManager.createQuery("SELECT g FROM Game g", Game.class);
        games = selectGamesQuery.getResultList();
    } catch(Exception e) {
        System.out.println(e);
    } 
    return games;
}

这成功返回了我可以迭代的游戏列表。

那么,在我看来,我有以下几点

        JScrollPane scrollPane = new JScrollPane();
    contentPane.add(scrollPane, BorderLayout.CENTER);

    tblGames = new JTable(new tblGamesModel());
    tblGames.setShowVerticalLines(true);
    tblGames.setShowHorizontalLines(true);
    tblGames.setFillsViewportHeight(true);
    scrollPane.setViewportView(tblGames);

这当然会引导我们进入表格模型,这是我卡住的地方。

public class tblGamesModel extends AbstractTableModel {

private GameRepository gameRepository;
private List<Game> games;
/**
 * 
 */
public tblGamesModel(){
    gameRepository = new GameRepository();
    games = gameRepository.getGames();
}

private static final long serialVersionUID = 1L;

@Override
public int getColumnCount() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public int getRowCount() {
    // TODO Auto-generated method stub
    return games.size();
}

@Override
public Object getValueAt(int arg0, int arg1) {
    // TODO Auto-generated method stub


    return null;
}

}

我知道这是一个简单帖子的大量代码,但我真的不知道如何显示当前问题。任何好的链接都会有所帮助,或自行提供建议。

感谢您花时间阅读代码并可能帮助我。

请记住,我只是一名学生编程,所以我还有很多关于约定等的知识。所以也欢迎指点,因为我渴望向更有经验的开发人员学习。

【问题讨论】:

    标签: java swing jpa jtable populate


    【解决方案1】:

    最简单的选择是这样的:

    @Override
    public int getColumnCount() {
        return 5;
    }
    
    ...
    
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Game game = games.get(rowIndex);
        switch (columnIndex) {
            case 0:
                return game.getId();
            case 1:
                return game.getTitle();
            case 2:
                return game.getPublisher();
            case 3:
                return game.getGenre();
            case 4:
                return game.getReleaseDate();
        }
        return null;
    }
    

    由于所有的幻数,这很容易出现维护问题 - 一种解决方案是对列使用枚举:

    enum GameTableColumn {
        ID, TITLE, PUBLISHER, GENRE, RELEASE_DATE;
    }
    

    然后使用 GameTableColumn.values()[columnIndex] 获取列的枚举实例。

    一些风格注释 - tblGamesModel 是 Java 类的非标准名称,类名总是以大写字母开头。更多的 Java 名称将是 GamesTableModel。通常不鼓励使用匈牙利符号前缀(例如“tbl”)。

    在构造函数中获取数据库通常是个坏主意。在 Swing 应用程序中,您希望所有获取都是显式的,这样您就可以确保它们不会阻塞 UI。我建议使用retrieveGames() 而不是getGames()。最好在表模型之外构建 GamesRepository 并将其传递给构造函数。然后,您可以先在不同的线程中执行 JPA 查询。这将防止 UI 线程在数据库访问过程中冻结。

    【讨论】:

    • 非常感谢 Russ Hayward,您的回答确实非常出色。我已经更改了您建议的所有内容以及更多内容,您是对的,我用于表模型的命名约定似乎有点不对劲。至于多线程查询,谢谢。我什至没有想过冻结我的用户界面。这个问题现在也解决了。我唯一不明白的是枚举部分。对于 List 中的所有对象,开关不都计数吗?还有一个问题,如何从列表中排除 Id?我不能在查询中使用它,因为我想稍后检索 ID。再次感谢。 :)
    • aah.. 抱歉.. 我忽略了开关中的 getId。对不起这个愚蠢的问题。想通了,它的工作原理。今晚我可以安然入睡了!谢谢。
    【解决方案2】:

    通过构造函数参数或setter方法将加载的列表传递给模型。然后您可以使用以下模型结构:

    public class TblGamesModel extends AbstractTableModel {
    
        private static final String[] COLUMNS = {"id", "title",
        ...........
        private static final int COL_ID = 0;
        private static final int COL_TITLE = 1;
    
        private List<Game> list;  //list that is injected via constructor or setter method
    
        public int getRowCount() {
            return list.size();
        }
    
        public int getColumnCount() {
            return COLUMNS.length;
        }
    
        public Object getValueAt(int rowIndex, int columnIndex) {
            Game game = list.get(rowIndex);
            switch (columnIndex) {
                case COL_ID:
                    return game.getId();
                ........
            }
        }
    
        public String getColumnName(int column) {
            return COLUMNS[column];
        }
    

    【讨论】:

    • 感谢您抽出宝贵时间回答。有了这条评论和上面的评论,我已经开始工作了。再次感谢:)
    • 所以,我的数据加载正确,现在一切正常,除了在switch中,返回game.genre的情况是一对多的关系,即许多游戏可能有一个并且只有一种流派,每个流派可以有一个或多个游戏。如何选择流派表中流派的名称,其中包含 2 列,ID 和名称
    • 如果每个游戏只能有一个流派,那么它在游戏流派之间是多对一的(游戏 M---1 流派)。默认情况下,JPA 会急切地获取此类关系,因此您应该能够执行game.getGenre().getName() 之类的操作。你不是吗?
    猜你喜欢
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多