/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JTablePaginationExample.java
 *
 * Created on Aug 15, 2009, 10:42:31 AM
 */
package com.rubenlaguna;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

/**
 *
 * @author Ruben Laguna <ruben.laguna at gmail.com>
 */
public class JTablePaginationExample extends javax.swing.JPanel {

    /** Creates new form JTablePaginationExample */
    public JTablePaginationExample() {
        initComponents();
    }

    private TableModel getTableModel() {
        EntityManager manager = Persistence.createEntityManagerFactory("JTablePaginationJPAPU").createEntityManager();

        return new JPAPaginationTableModel(manager);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                JFrame frame = new JFrame("JTable with custom TableModel and JPA");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JComponent panel = new JTablePaginationExample();
                frame.add(panel);
                frame.pack();
                frame.setVisible(true);
            }
        });

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();

        jTable1.setModel(getTableModel());
        jScrollPane1.setViewportView(jTable1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(19, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(19, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    // End of variables declaration//GEN-END:variables
}

class JPAPaginationTableModel extends AbstractTableModel {

    private final EntityManager manager;
    private int startPosition;
    private List<Customers> theList;
    private int counter = 0;

    JPAPaginationTableModel(EntityManager manager) {
        this.manager = manager;
        this.startPosition = 0;
        this.theList = getItems(startPosition, startPosition + 100);
    }

    public int getRowCount() {
        return ((Long) manager.createQuery("SELECT COUNT(c) FROM Customers c").getSingleResult()).intValue();
    }

    public int getColumnCount() {
        return 3;
    }

    @Override
    public String getColumnName(int column) {
        switch(column) {
            case 0:
                return "ID";
            case 1:
                return "FIRST NAME";
            default:
                return "LAST NAME";
        }
    }


    public Object getValueAt(int rowIndex, int columnIndex) {

        if ((rowIndex >= startPosition) && (rowIndex < (startPosition + 100))) {
        } else {
            this.theList = getItems(rowIndex, rowIndex + 100);
            this.startPosition = rowIndex;
        }
        Customers c = theList.get(rowIndex - startPosition);

        Object toReturn = null;
        switch (columnIndex) {
            case 0:
                toReturn = c.getId();
                break;
            case 1:
                toReturn = c.getFirstName();
                break;
            case 2:
                toReturn = c.getLastName();
                break;
            default:
                toReturn = c.getId();

        }
        return toReturn;
    }

    private List<Customers> getItems(int from, int to) {
        System.out.println("numer of requests to the database " + counter++);
        Query query = manager.createQuery("SELECT c FROM Customers c").setMaxResults(to - from).setFirstResult(from);

        //add the cache
        List<Customers> resultList = query.getResultList();
        return resultList;
    }
}
