Java/Swing应用程序随机冻结
我有一个简单的Swing按钮,可以刷新jtable,但在随机点击次数后,应用程序会冻结,有时是无限期冻结,有时会在一分钟左右后响应。我从来没有使用过任何特定于线程的方法,所以我认为这可能是问题所在,但我不知道从哪里开始,或者如果这是冻结的原因,我不知道如何修改这些方法 代码如下:Java/Swing应用程序随机冻结,java,multithreading,swing,jtable,swingworker,Java,Multithreading,Swing,Jtable,Swingworker,我有一个简单的Swing按钮,可以刷新jtable,但在随机点击次数后,应用程序会冻结,有时是无限期冻结,有时会在一分钟左右后响应。我从来没有使用过任何特定于线程的方法,所以我认为这可能是问题所在,但我不知道从哪里开始,或者如果这是冻结的原因,我不知道如何修改这些方法 代码如下: private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
recorrerLista();
}
public EventList recorrerLista(){
Persistir p = Persistir.getInstancia();
Vector<Pedidos> lista2 = p.listarPedidos();
Iterator it = lista2.iterator();
if(!pedList.isEmpty()){
pedList.clear();
}
while(it.hasNext()){
Vector v = new Vector();
v = (Vector) it.next();
int index = (Integer)v.get(0);
Pedidos ped = new Pedidos();
ped = p.buscarPedidoPorId(index);
pedList.add(ped);
}
return pedList;
}
您的实现非常类似于一无所有,因为在listarPedidos()
的末尾,您调用了以下方法:
因此,在完成之前,会导致系统被阻塞:
您应该使用和。由于您使用JPA,我假设您可以获得一个名为Articulos
的实体,因此您可以执行以下操作:
SwingWorker<Void, Articulos> worker = new SwingWorker<Void, Articulos>() {
@Override
protected Void doInBackground() throws Exception {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PedidosPU" );
EntityManager em = emf.createEntityManager();
String jqpl = "SELECT a FROM Articulos a WHERE a.entregado = :param";
TypedQuery<Articulos> query = em.createQuery(jpql, Articulos.class);
query.setParameter("param", "P");
List<Articulos> resultList = query.getResultList();
publish((Articulos[])resultList.toArray());
em.close();
emf.close();
}
@Override
protected void process(List<Articulos> chunks) {
// add your items to the table model here
// this code runs in the EDT
}
@Override
protected void done() {
refreshButton.setEnabled(true);
}
};
worker.execute();
SwingWorker-worker=新的SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
EntityManagerFactory emf=Persistence.createEntityManagerFactory(“PedidosPU”);
EntityManager em=emf.createEntityManager();
String jqpl=“从Articulos a中选择a,其中a.entregado=:param”;
TypedQueryClassM我怀疑您的表模型是(如果不是这样的话,请忽略这个离题的注释),它不是处理复杂模型类的最佳盟友
如果是这种情况(并且考虑到您似乎会说西班牙语),请参阅(或者,由google translate提供)关于使用域类创建可重用表模型的内容。如果您不会说西班牙语,您仍然可以查看(或者)末尾发布的GenericDomainTableModel
类代码因为,这是不言自明的。您的实现非常类似于您一无所有,因为在listarPedidos()
的末尾,您调用了以下方法:
因此,在完成之前,会导致系统被阻塞:
您应该使用和。由于您使用JPA,我假设您可以设法获得一个名为Articulos
的实体,因此您可以执行以下操作:
SwingWorker<Void, Articulos> worker = new SwingWorker<Void, Articulos>() {
@Override
protected Void doInBackground() throws Exception {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PedidosPU" );
EntityManager em = emf.createEntityManager();
String jqpl = "SELECT a FROM Articulos a WHERE a.entregado = :param";
TypedQuery<Articulos> query = em.createQuery(jpql, Articulos.class);
query.setParameter("param", "P");
List<Articulos> resultList = query.getResultList();
publish((Articulos[])resultList.toArray());
em.close();
emf.close();
}
@Override
protected void process(List<Articulos> chunks) {
// add your items to the table model here
// this code runs in the EDT
}
@Override
protected void done() {
refreshButton.setEnabled(true);
}
};
worker.execute();
SwingWorker-worker=新的SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
EntityManagerFactory emf=Persistence.createEntityManagerFactory(“PedidosPU”);
EntityManager em=emf.createEntityManager();
String jqpl=“从Articulos a中选择a,其中a.entregado=:param”;
TypedQueryClassM我怀疑您的表模型是(如果不是这样的话,请忽略这个离题的注释),它不是处理复杂模型类的最佳盟友
如果是这种情况(并且考虑到您似乎会说西班牙语),请参阅(或者,由google translate提供)关于使用域类创建可重用表模型的内容。如果您不会说西班牙语,您仍然可以查看(或者)末尾发布的GenericDomainTableModel
类代码因为,好吧,这是不言自明的。“我需要修改它以便它在GUI的同一线程上运行吗?”-可能是另一种方式,您需要在不同的线程上运行它。您似乎已经在ui线程(EDT)上运行了。长时间运行的任务应该在后台线程上运行。您的Persistir
类正在命中数据库,这可能会导致ui无响应。因此,是的,您可能希望在Swing Worker
上运行该任务。请参阅查看一些标记的问题,获取一些想法。除了明智的@peeskillet注释,在繁重的更新过程中,通常会禁用按钮直到更新完成,以避免用户重复触发相同的操作。我尝试在SwingWorker中插入该方法,但UI现在没有显示。显然,我做错了“是否需要修改它,使其在GUI的同一线程上运行?”-可能是另一种方式,您需要在其他线程上运行它。您似乎已经在ui线程(EDT)上运行了。长时间运行的任务应该在后台线程上运行。您的Persistir
类正在命中数据库,这可能会导致ui无响应。因此,是的,您可能希望在Swing Worker
上运行该任务。请参阅查看一些标记的问题,获取一些想法。除了明智的@peeskillet注释,在繁重的更新过程中,通常会禁用按钮直到更新完成,以避免用户重复触发相同的操作。我尝试在SwingWorker中插入该方法,但UI现在没有显示。显然我做错了。我有一个问题。我按照你的建议做了,得到了一个空指针异常。Le让我澄清一点,方法listarPedidos返回所述对象的向量,当我设置断点进行调试时,我看到Swingworker中的代码被完全跳过。由于我需要向量的返回,我需要该方法给我所述向量,但它是空的。我不知道为什么代码被跳过或者为什么我无法获取向量。您好。Y你需要你的向量来填充你的表模型,对吗?这就是这个SwingWorker异步做的:在doInBackground()
方法中获取Articulos
列表,并使用publish()
方法处理该列表并在process()中更新你的表模型
方法将在EDT中完成保修。您不必因为在同一步骤中获得列表并一起处理而返回任何内容。@IsmaelMarquezI不知道为什么在操作执行()中使用断点运行时,按钮的
会完全跳过SwingWorker
中的内容,它会直接转到worker.execute()
它什么也不做。为什么会这样?为什么我做错了?我忘了提到我正在使用GlazedList填充表,并在列表更新时显示更改。我有一个问题。我按照你的建议做了,我得到了一个空指针
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
final Persistir p = Persistir.getInstancia();
SwingWorker<Void, Pedidos> worker = new SwingWorker<Void, Pedidos>() {
//private Vector lista2;
@Override
protected Void doInBackground() throws Exception {
EntityManagerFactory emf = Persistir.createEntityManagerFactory("PedidosPU" );
EntityManager em = emf.createEntityManager();
String jqpl = "SELECT * FROM pedidosview WHERE ENTREGADO='P' ORDER BY fecha_pedido";
//TypedQuery<Articulos> query = em.createQuery(jpql, Articulos.class);
Query query = em.createNativeQuery("SELECT * FROM pedidosview WHERE ENTREGADO='P' ORDER BY fecha_pedido");
//query.setParameter("param", "P");
//lista = (Vector) query.getResultList();
List<Pedidos> lista2 = query.getResultList();
publish((Pedidos[])lista2.toArray());
em.close();
emf.close();
return null;
}
@Override
protected void process(List<Pedidos> chunks) {
Iterator it = lista2.iterator();
if(!pedList.isEmpty()){
pedList.clear();
}
while(it.hasNext()){
Vector v = new Vector();
v = (Vector) it.next();
int index = (Integer)v.get(0);
Pedidos ped = new Pedidos();
ped = p.buscarPedidoPorId(index);
pedList.add(ped);
}
}
@Override
protected void done() {
jButton1.setEnabled(true);
}
};
worker.execute();
}
public Vector listarPedidos() throws InterruptedException, ExecutionException {
...
return (Vector) listar.get();
}
SwingWorker<Void, Articulos> worker = new SwingWorker<Void, Articulos>() {
@Override
protected Void doInBackground() throws Exception {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PedidosPU" );
EntityManager em = emf.createEntityManager();
String jqpl = "SELECT a FROM Articulos a WHERE a.entregado = :param";
TypedQuery<Articulos> query = em.createQuery(jpql, Articulos.class);
query.setParameter("param", "P");
List<Articulos> resultList = query.getResultList();
publish((Articulos[])resultList.toArray());
em.close();
emf.close();
}
@Override
protected void process(List<Articulos> chunks) {
// add your items to the table model here
// this code runs in the EDT
}
@Override
protected void done() {
refreshButton.setEnabled(true);
}
};
worker.execute();