Java / Swing app随机冻结

时间:2014-09-09 12:33:27

标签: java multithreading swing jtable swingworker

我有一个简单的Swing按钮刷新jtable,但是在随机点击后,应用程序冻结,有时无限期,有时它会在一分钟左右后响应。我从来没有做任何特定于线程的方法所以我认为可能s the issue but I don知道从哪里开始或如何修改方法,如果这是造成冻结的原因。

这是代码:

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;

}

编辑:我尝试在SwingWorker中插入持久化类(Persistir)的方法,但现在UI不会显示。

这是代码

public Vector listarPedidos() throws InterruptedException, ExecutionException{
SwingWorker listar = new SwingWorker<Vector, Vector>(){

    @Override
    protected Vector doInBackground() throws Exception {
        Vector<Articulos> lista = null;
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("PedidosPU" );
  EntityManager em = emf.createEntityManager();
  em.getTransaction().begin();

  try {
    Query query = em.createNativeQuery("SELECT * FROM pedidosview WHERE ENTREGADO='P' ORDER BY fecha_pedido");

lista = (Vector) query.getResultList();
  } catch (Exception e) {
    System.out.println( e.getMessage() );
    em.getTransaction().rollback();
  } finally {
    em.close();
    emf.close();
  }
    return lista;
        }

 };
    return (Vector) listar.get();

}

编辑2:我做了建议,我得到一个空指针异常,这是我的代码:

public Vector listarPedidos(){
//Vector<Articulos> lista = null;
final EntityManagerFactory emf = Persistence.createEntityManagerFactory("PedidosPU" );
final EntityManager em = emf.createEntityManager();

final SwingWorker worker = new SwingWorker(){  
  private Vector lista;


  @Override
  protected Object doInBackground() throws Exception {
      em.getTransaction().begin();

    try {
      Query query = em.createNativeQuery("SELECT * FROM pedidosview WHERE ENTREGADO='P' ORDER BY fecha_pedido");

      lista = (Vector) query.getResultList();
    } catch (Exception e) {
      System.out.println( e.getMessage() );
      em.getTransaction().rollback();
    } finally {
      em.close();
      emf.close();
    }
      return lista;
    }


 };
   worker.execute();
   return lista;


}

编辑3:我将此代码添加到按钮的ActionPerformed()。但它似乎完全跳过了代码

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

1 个答案:

答案 0 :(得分:6)

您的SwingWorker实施非常类似于您根本没有任何内容,因为在listarPedidos()结束时您调用get()方法:

public Vector listarPedidos() throws InterruptedException, ExecutionException {
    ...
    return (Vector) listar.get();
}

因此导致Event Dispatch Thread被阻止,直到doInBackground()完成:

enter image description here

您应该使用publish()process()代替。由于您使用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();

题外话

考虑到Vector classm的使用,我怀疑你的表模型是DefaultTableModel(如果不是这样的情况,pelase忽视了这个偏离主题的评论),这不是与复杂工作的最好的盟友模特课。

如果是这种情况(考虑到您似乎会说西班牙语),请参阅this post (in Spanish) (或in English,礼貌谷歌翻译)关于创建使用域类的可重用表模型。如果您不会说西班牙语,您仍然可以查看this entry (或in English末尾发布的GenericDomainTableModel班级代码,因为,它非常明显。