问题描述
我的 MVC 应用程序在 JTable 中显示数据时遇到问题.一切正常,但我决定添加一个 SwingWorker 来从数据库中检索数据.
I have a problem with my MVC application that displays data in a JTable. Everything worked fine, but I decided to add a SwingWorker to retrieve data from the database.
我的控制器使用数据库中的数据调用模型.它看起来像这样.
My controller calls the model with data from the database. It looks like this.
模型.java
public class Model {
private List<Category> people = new Vector<Category>();
public List<Category> getPeople() {
return new ArrayList<Category>(people);
}
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
CategoryDAO personDAO = factory.getCategoryDAO();
people.addAll(personDAO.getCategory());
}
}
我将 SwingWorker 添加到 getCategory 类
I add SwingWorker to getCategory class
MySQLCategodyDAO.java
MySQLCategodyDAO.java
public class MySQLCategoryDAO extends SwingWorker<Void, Vector<Object>> implements CategoryDAO{
private Job job;
private List<Category> cat;
public MySQLCategoryDAO(Job job){
this.job = job;
}
@Override
protected Void doInBackground() throws Exception {
// TODO Auto-generated method stub
if(job == Job.SELECT){
getCategory();
System.out.println("Table selected");
}
return null;
}
@Override()
public void done(){
}
public List<Category> getCategory() throws SQLException
{
cat = new ArrayList<Category>();
Connection conn = Database.getInstance().getConnection();
System.out.println(conn);
String sql = "select id, name from kategorie";
Statement selectStatement = conn.createStatement();
ResultSet results = selectStatement.executeQuery(sql);
while(results.next())
{
int id = results.getInt("id");
String name = results.getString("name");
Category category = new Category(id, name);
cat.add(category);
}
results.close();
selectStatement.close();
return cat;
}
}
View 只是从模型中检索数据:
View just retrieves the data from the model:
people = model.getPeople();
for (Category person : people) {
tablemodel
.addRow(new Object[] { person.getId(), person.getName() });
}
在 Model.java 类中调用 SwingWorker 时出现问题
The problem comes when you call SwingWorker in class Model.java
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
CategoryDAO personDAO = factory.getCategoryDAO();
people.addAll(new MySQLCategoryDAO(Job.SELECT).execute()); - ERROR
}
错误:-
The method addAll(Collection<? extends Category>) in the type List<Category> is not applicable for the
arguments (void)
我知道 SwingWorker 什么都不返回,因为有一个错误.我应该在方法 done()
中编写代码,但我不知道如何解决它.
I know SwingWorker returns nothing, because there is an error. I should write the code in the method done()
, but I have no idea how to solve it.
推荐答案
execute
没有返回值,因此无法按照您尝试使用的方式使用它.SwingWorker 的想法是任务应该异步执行,所以你需要重新设计你的设计.
execute
does not have a return value so it can't be used in the way you are trying to use it. The idea of SwingWorker is that the task should be executed asynchronously so you need to rework your design.
SwingWorker 产生一个结果(List
),你要么需要:
The SwingWorker bears a result (the List<Category>
) and you either need to:
- 将结果放在 SwingWorker 内部的某个位置(例如使用发布机制)
- 或者从外部调用
get
等待任务完成返回.
- put the result somewhere from inside the SwingWorker (such as with the publish mechanism)
- or call
get
from the outside to wait for the task to finish and return.
这里是复习教程:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
快速示例:
class MySQLCategoryDAO extends SwingWorker<Void, Category> {
// ...
private List<Category> list; // do not modify inside doInBackground
MySQLCategoryDAO(Job job, List<Category> list) {
this.list = list;
// ...
}
@Override
protected Void doInBackground() {
// ...
while(results.next()) {
int id = results.getInt("id");
String name = results.getString("name");
publish(new Category(id, name)); // publish results to the EDT
}
// ...
return null;
}
@Override
protected void process(List<Category> chunks) {
list.addAll(chunks); // add results to the list on the EDT
// add to the JTable (?)
}
}
public void load() throws Exception {
people.clear();
DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
CategoryDAO personDAO = factory.getCategoryDAO();
// just execute
new MySQLCategoryDAO(Job.SELECT, people).execute();
}
如果您想一次填充整个表格,那么您还可以在循环后发布一个列表,而不是一次发布一个类别.process
将接收一个带有单个元素的 List
.
If you want to populate the entire table at once then you can also publish a List after the loop instead of one Category at a time. process
would receive a List<List<Category>>
with a singular element.
这篇关于Java SwingWorker 从数据库加载数据到列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!