Java JTable binding via JPA
I have tried to search for proper answers, but nothing helped me so far. I am quite new to java GUI programming, actually, to java itself.. I have however managers to understand JPA, how to retrieve, insert and delete using JPA.
Now I want the data in my database to be shown in a JTable.
I currently have the following mySQL table(which i want to show in a JTable
games Id PK int Title Publisher Genre ReleaseDate
As far as coding concerns, I have succesfully retrieved the data contained in the table using the following:
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;开发者_JAVA百科
}
This succesfully returns a list of games whom I can iterate trough.
Then, in my view I have the following
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);
Which ofcourse leads us to the table model,which is where I'm stuck.
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;
}
}
I know this is alot of code for a simple post, but I really don't know how else to show the current problem. Any good links would help, or advise on its own.
Thanks for taking the time to read the code and possibly help me out.
Remember, I am just a student programming, so I have a lot to learn about conventions etc aswell. So pointers are also welcome, as I am eager to learn from more experienced developers.
The simplest option is something like this:
@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;
}
That can be prone to maintenance problems due to all the magic numbers - a solution would be to use an enumeration for the columns:
enum GameTableColumn {
ID, TITLE, PUBLISHER, GENRE, RELEASE_DATE;
}
And then get the enumeration instance for a column using GameTableColumn.values()[columnIndex].
A few style notes - tblGamesModel is a non-standard name for a Java class, class names always start with an upper case letter. A more Java name would be GamesTableModel. Hungarian notation prefixes (such as "tbl") are generally discouraged.
Also having a database fetch in a constructor is generally a bad idea. In a Swing application you want all fetches to be explicit so you can ensure they do not block the UI. Rather than getGames() I would suggest retrieveGames(). It may be best to construct the GamesRepository outside the table model and pass it in to the constructor. You could then perform the JPA query first in a different thread. This would prevent the UI thread from freezing while the database access is in progress.
Pass loaded list to the model via constructor parameter or setter method. Then you can use following model structure:
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];
}
精彩评论