Autocomplete JCombobox from database

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Autocomplete JCombobox from database

bolsover
This post has NOT been accepted by the mailing list yet.
I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database.

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'.

Is this a problem that can be solved? If so How?

 package com.nomogen.pegging.components;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.swing.AutoCompleteSupport;
import com.nomogen.jobshop.dao.HibernateUtil;
import com.nomogen.jobshop.hibernate.Part;

import java.beans.Beans;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.SwingWorker;

import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author DBolsover
 */
@SuppressWarnings("serial")
public class PartNumberComboBox extends JComboBox<String>{
    public static String            PROP_PART = "part";
    @SuppressWarnings("unchecked")
    private final EventList<String> data      = new BasicEventList<>();
    private long                    when      = 0l;
    private Part                    part;
 

    /**
     * Constructs ...
     *
     */
    public PartNumberComboBox() {
        init();
    }

    /**
     * Method description
     *
     *
     * @param partial_no
     *
     * @return
     */
    private List<String> dataList(String partial_no) {
        Session  session = HibernateUtil.openSession();
        SQLQuery q       =
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;");

        q.setString("partial_no", partial_no + "%");

        @SuppressWarnings("unchecked") List<String> dataList = q.list();

        HibernateUtil.closeSession();

        return dataList;
    }

    /**
     * @return the part
     */
    public Part getPart() {
        return part;
    }

    /**
     * Method description
     *
     *
     * @param part_no
     *
     * @return
     */
    private Part getPartbyId(String part_no) {
        Session session = HibernateUtil.openSession();
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no",
                              part_no)).uniqueResult();

        HibernateUtil.closeSession();

        return p;
    }

    /**
     * Method description
     *
     */
    @SuppressWarnings("unchecked")
    private void init() {
        if (!Beans.isDesignTime()) {
            data.addAll(initialList());
            AutoCompleteSupport.install(this, data);

           this.addPopupMenuListener(null);

            addItemListener(new java.awt.event.ItemListener() {
                @Override
                public void itemStateChanged(java.awt.event.ItemEvent evt) {
                    partNumberCooserItemStateChanged(evt);
                }
            });
            addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    partNumberCooserActionPerformed(evt);
                }
            });
           
        }
    }

    /**
     * Method description
     *
     *
     * @return
     */
    private List<String> initialList() {
        Session                                     session     = HibernateUtil.openSession();
        SQLQuery                                    q           =
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;");
        @SuppressWarnings("unchecked") List<String> initialList = q.list();

        HibernateUtil.closeSession();

        return initialList;
    }

    /**
     * Method description
     *
     *
     * @param evt
     */
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) {
        if (evt.getWhen() - when > 50) {
            String part_no = (String) this.getSelectedItem();
            Part   p       = getPartbyId(part_no);

            setPart(getPartbyId(part_no));
        }

        when = evt.getWhen();
    }

    /**
     * Method description
     *
     *
     * @param evt
     */
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) {
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            @SuppressWarnings("unchecked")
            protected Void doInBackground() throws Exception {
                String partial_no = (String) evt.getItem();
                int    length     = ((String) evt.getItem()).length();

                data.getReadWriteLock().writeLock().lock();

                try {
                    if (length < 1) {
                        for (String s : initialList()) {
                            if (!data.contains(s.trim())) {
                                data.add(s.trim());
                            }
                        }
                    } else {
                        List<String> moreData = dataList(partial_no);

                        for (String s : moreData) {
                            if (!data.contains(s.trim())) {
                                data.add(s.trim());
                            }
                        }
                    }
                } finally {
                    data.getReadWriteLock().writeLock().unlock();
                }

                return null;
            }
        };

        worker.execute();
    }

 

    /**
     * @param part the part to set
     */
    public void setPart(Part part) {
        Object oldValue = getPart();

        this.part = part;
        firePropertyChange(PROP_PART, oldValue, part);
    }

   
   
}
Reply | Threaded
Open this post in threaded view
|

Autocomplete JCombobox from database

bolsover

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

Reply | Threaded
Open this post in threaded view
|

Re: Autocomplete JCombobox from database

Dmitriy Moroz

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

Reply | Threaded
Open this post in threaded view
|

RE: Autocomplete JCombobox from database

bolsover

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

Reply | Threaded
Open this post in threaded view
|

Re: Autocomplete JCombobox from database

Dmitriy Moroz
In reply to this post by Dmitriy Moroz

... And autocompletion with intellihints... All part of free common layer.

Regards
DM

On Aug 13, 2013 4:06 PM, "Dmitriy Moroz" <[hidden email]> wrote:

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

Reply | Threaded
Open this post in threaded view
|

RE: Autocomplete JCombobox from database

Dmitriy Moroz
In reply to this post by bolsover

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

Reply | Threaded
Open this post in threaded view
|

RE: Autocomplete JCombobox from database

bolsover

Dmitriy

 

I’ve got the documentation out now…

I’ll try putting it all together – see if I can make it work.

 

Not given up on glazedlists yet though – It took me a couple of hours to get my current solution working reasonably well. The only problem is getting the thing to work fully with mouse gestures alone.

 

David

 

 

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:30
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

Reply | Threaded
Open this post in threaded view
|

Re: Autocomplete JCombobox from database

James Lemieux
Hi David,

   It's not clear to me what about the mouse is failing. Doesn't it fire an ItemEvent just like the keyboard does? What about your currently listener fails in the case of mouse clicks but succeeds in the case of keyboard events?

James


On Tue, Aug 13, 2013 at 1:35 PM, David Bolsover <[hidden email]> wrote:

Dmitriy

 

I’ve got the documentation out now…

I’ll try putting it all together – see if I can make it work.

 

Not given up on glazedlists yet though – It took me a couple of hours to get my current solution working reasonably well. The only problem is getting the thing to work fully with mouse gestures alone.

 

David

 

 

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:30
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}


Reply | Threaded
Open this post in threaded view
|

RE: Autocomplete JCombobox from database

bolsover

Hi James

 

When using mouse only to select an item from the initialdata list (just the initial letters of part numbers retrieved from the database), I need this to trigger retrieval of all part numbers starting with that letter and update the popup list accordingly – which should remain visible.  At present, if I use mouse to select an initial letter, the popup list closes and no data is retrieved.

 

If I use keyboard only and type an initial letter, this is found in the initial list and further data is retrieved from the database. The popup remains visible and keyboard (or mouse) can then be used to filter/select an actual part number.

 

Thanks..

 

David

 

From: James Lemieux [mailto:[hidden email]]
Sent: 13 August 2013 21:59
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Hi David,

 

   It's not clear to me what about the mouse is failing. Doesn't it fire an ItemEvent just like the keyboard does? What about your currently listener fails in the case of mouse clicks but succeeds in the case of keyboard events?

 

James

 

On Tue, Aug 13, 2013 at 1:35 PM, David Bolsover <[hidden email]> wrote:

Dmitriy

 

I’ve got the documentation out now…

I’ll try putting it all together – see if I can make it work.

 

Not given up on glazedlists yet though – It took me a couple of hours to get my current solution working reasonably well. The only problem is getting the thing to work fully with mouse gestures alone.

 

David

 

 

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:30
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

 

Reply | Threaded
Open this post in threaded view
|

RE: Autocomplete JCombobox from database

bolsover

James..

Sorry I should have added – Yes, the mouse action does fire an Item event – but it also forces the popup to close.

 

David

 

From: David Bolsover [mailto:[hidden email]]
Sent: 13 August 2013 22:08
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hi James

 

When using mouse only to select an item from the initialdata list (just the initial letters of part numbers retrieved from the database), I need this to trigger retrieval of all part numbers starting with that letter and update the popup list accordingly – which should remain visible.  At present, if I use mouse to select an initial letter, the popup list closes and no data is retrieved.

 

If I use keyboard only and type an initial letter, this is found in the initial list and further data is retrieved from the database. The popup remains visible and keyboard (or mouse) can then be used to filter/select an actual part number.

 

Thanks..

 

David

 

From: James Lemieux [[hidden email]]
Sent: 13 August 2013 21:59
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Hi David,

 

   It's not clear to me what about the mouse is failing. Doesn't it fire an ItemEvent just like the keyboard does? What about your currently listener fails in the case of mouse clicks but succeeds in the case of keyboard events?

 

James

 

On Tue, Aug 13, 2013 at 1:35 PM, David Bolsover <[hidden email]> wrote:

Dmitriy

 

I’ve got the documentation out now…

I’ll try putting it all together – see if I can make it work.

 

Not given up on glazedlists yet though – It took me a couple of hours to get my current solution working reasonably well. The only problem is getting the thing to work fully with mouse gestures alone.

 

David

 

 

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:30
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

 

Reply | Threaded
Open this post in threaded view
|

Re: Autocomplete JCombobox from database

Niklas Kyster Rasmussen
Without knowing anything about the problem, I will suggest you just re-show the popup:


On Tue, Aug 13, 2013 at 11:10 PM, David Bolsover <[hidden email]> wrote:

James..

Sorry I should have added – Yes, the mouse action does fire an Item event – but it also forces the popup to close.

 

David

 

From: David Bolsover [mailto:[hidden email]]
Sent: 13 August 2013 22:08


To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hi James

 

When using mouse only to select an item from the initialdata list (just the initial letters of part numbers retrieved from the database), I need this to trigger retrieval of all part numbers starting with that letter and update the popup list accordingly – which should remain visible.  At present, if I use mouse to select an initial letter, the popup list closes and no data is retrieved.

 

If I use keyboard only and type an initial letter, this is found in the initial list and further data is retrieved from the database. The popup remains visible and keyboard (or mouse) can then be used to filter/select an actual part number.

 

Thanks..

 

David

 

From: James Lemieux [[hidden email]]
Sent: 13 August 2013 21:59
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Hi David,

 

   It's not clear to me what about the mouse is failing. Doesn't it fire an ItemEvent just like the keyboard does? What about your currently listener fails in the case of mouse clicks but succeeds in the case of keyboard events?

 

James

 

On Tue, Aug 13, 2013 at 1:35 PM, David Bolsover <[hidden email]> wrote:

Dmitriy

 

I’ve got the documentation out now…

I’ll try putting it all together – see if I can make it work.

 

Not given up on glazedlists yet though – It took me a couple of hours to get my current solution working reasonably well. The only problem is getting the thing to work fully with mouse gestures alone.

 

David

 

 

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:30
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}

 


Reply | Threaded
Open this post in threaded view
|

RE: Autocomplete JCombobox from database

bolsover

Hi Niklas

 

I’ve tried doing that – but so far without success.

 

I have got the code working better though – now it does retrieve the extra data needed on a mouse click and the only real problem remaining is how to keep the popup visible..

 

Code now is:

 

package com.nomogen.pegging.components;

 

import ca.odell.glazedlists.BasicEventList;

import ca.odell.glazedlists.EventList;

import ca.odell.glazedlists.swing.AutoCompleteSupport;

import com.nomogen.jobshop.dao.HibernateUtil;

import com.nomogen.jobshop.hibernate.Part;

 

import java.beans.Beans;

import java.util.List;

import javax.swing.JComboBox;

import javax.swing.SwingWorker;

 

import org.hibernate.SQLQuery;

import org.hibernate.Session;

import org.hibernate.criterion.Restrictions;

 

/**

*

* @author DBolsover

*/

@SuppressWarnings("serial")

public class PartNumberComboBox extends JComboBox<String> {

    public static String            PROP_PART = "part";

    @SuppressWarnings("unchecked")

    private final EventList<String> data      = new BasicEventList<>();

    private long                    when      = 0l;

    private Part                    part;

 

    /**

     * Constructs ...

     *

     */

    public PartNumberComboBox() {

        init();

    }

 

    /**

     * Method description

     *

     *

     * @param partial_no

     *

     * @return

     */

    private List<String> dataList(String partial_no) {

        Session  session = HibernateUtil.openSession();

        SQLQuery q       =

            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;");

 

        q.setString("partial_no", partial_no + "%");

 

        @SuppressWarnings("unchecked") List<String> dataList = q.list();

 

        HibernateUtil.closeSession();

 

        return dataList;

    }

 

    /**

     * @return the part

     */

    public Part getPart() {

        return part;

    }

 

    /**

     * Method description

     *

     *

     * @param part_no

     *

     * @return

     */

    private Part getPartbyId(String part_no) {

        Session session = HibernateUtil.openSession();

        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no",

                              part_no)).uniqueResult();

 

        HibernateUtil.closeSession();

 

        return p;

    }

 

    /**

     * Method description

     *

     */

    @SuppressWarnings("unchecked")

    private void init() {

        if (!Beans.isDesignTime()) {

            data.addAll(initialList());

        

            

            AutoCompleteSupport.install(this, data);

            this.addPopupMenuListener(null);

            addItemListener(new java.awt.event.ItemListener() {

                @Override

                public void itemStateChanged(java.awt.event.ItemEvent evt) {

                    partNumberCooserItemStateChanged(evt);

                }

            });

            addActionListener(new java.awt.event.ActionListener() {

                @Override

                public void actionPerformed(java.awt.event.ActionEvent evt) {

                    partNumberCooserActionPerformed(evt);

                }

            });

        }

    }

   

    

    

 

    /**

     * Method description

     *

     *

     * @return

     */

    private List<String> initialList() {

        Session                                     session     = HibernateUtil.openSession();

        SQLQuery                                    q           =

            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;");

        @SuppressWarnings("unchecked") List<String> initialList = q.list();

 

        HibernateUtil.closeSession();

 

        return initialList;

    }

 

    /**

     * Method description

     *

     *

     * @param evt

     */

    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) {

        updateData();

 

        if (System.currentTimeMillis() - when > 75) {

            String part_no = (String) this.getSelectedItem();

            Part   p       = getPartbyId(part_no);

 

            setPart(p);

            when = System.currentTimeMillis();

        }

    }

 

    /**

     * Method description

     *

     *

     * @param evt

     */

    private void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) {

        updateData();

    }

 

    /**

     * @param part the part to set

     */

    public void setPart(Part part) {

        Object oldValue = getPart();

 

        this.part = part;

        firePropertyChange(PROP_PART, oldValue, part);

    }

 

    /**

     * Method description

     *

     */

    private synchronized  void updateData() {

        if ((selectedItemReminder != null) && ((String) selectedItemReminder).length() == 1) {

            SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

                @Override

                @SuppressWarnings("unchecked")

                protected Void doInBackground() throws Exception {

                    String partial_no = (String) selectedItemReminder;

 

                    data.getReadWriteLock().writeLock().lock();

 

                    try {

                        List<String> moreData = dataList(partial_no);

 

                        for (String s : moreData) {

                            if (!data.contains(s.trim())) {

                                data.add(s.trim());

                            } else {

                                break;

                            }

                        }

                    } finally {

                        data.getReadWriteLock().writeLock().unlock();

                    }

 

                    return null;

                }

            };

 

            worker.execute();

        }

    }

}

 

From: Niklas Kyster Rasmussen [mailto:[hidden email]]
Sent: 14 August 2013 10:44
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Without knowing anything about the problem, I will suggest you just re-show the popup:

 

On Tue, Aug 13, 2013 at 11:10 PM, David Bolsover <[hidden email]> wrote:

James..

Sorry I should have added – Yes, the mouse action does fire an Item event – but it also forces the popup to close.

 

David

 

From: David Bolsover [mailto:[hidden email]]
Sent: 13 August 2013 22:08


To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hi James

 

When using mouse only to select an item from the initialdata list (just the initial letters of part numbers retrieved from the database), I need this to trigger retrieval of all part numbers starting with that letter and update the popup list accordingly – which should remain visible.  At present, if I use mouse to select an initial letter, the popup list closes and no data is retrieved.

 

If I use keyboard only and type an initial letter, this is found in the initial list and further data is retrieved from the database. The popup remains visible and keyboard (or mouse) can then be used to filter/select an actual part number.

 

Thanks..

 

David

 

From: James Lemieux [[hidden email]]
Sent: 13 August 2013 21:59
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Hi David,

 

   It's not clear to me what about the mouse is failing. Doesn't it fire an ItemEvent just like the keyboard does? What about your currently listener fails in the case of mouse clicks but succeeds in the case of keyboard events?

 

James

 

On Tue, Aug 13, 2013 at 1:35 PM, David Bolsover <[hidden email]> wrote:

Dmitriy

 

I’ve got the documentation out now…

I’ll try putting it all together – see if I can make it work.

 

Not given up on glazedlists yet though – It took me a couple of hours to get my current solution working reasonably well. The only problem is getting the thing to work fully with mouse gestures alone.

 

David

 

 

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:30
To: [hidden email]
Subject: RE: Autocomplete JCombobox from database

 

Hey David,

It has been a while since I looked at this but they have a class called AutoCompetionComboBox. You can provide your own AutoCompletion class. Can't say beyond that but it sounds like what you need, with probably customized model...

Best
-DM

On Aug 13, 2013 4:23 PM, "David Bolsover" <[hidden email]> wrote:

Interesting… I’m actually using Jide common layer already in the same project but had not considered for this use.

I can see that it can readily support the search function – but do you know if it can be configured to retrieve data from a database on-the –fly? This latter feature is most important; the data I use currently has some 25000 entries (and growing rapidly) – for performance reasons I don’t want to read all 25K primary keys and load these into a list.

 

db

 

From: Dmitriy Moroz [mailto:[hidden email]]
Sent: 13 August 2013 21:06
To: [hidden email]
Subject: Re: Autocomplete JCombobox from database

 

Why not use Jide Software's common layer? It has Searchable combo box and tools where you can control the model...

My 5c...

On Aug 13, 2013 3:54 PM, "David Bolsover" <[hidden email]> wrote:

I'm currently working on a custom JCombobox with autocomplete where the data elements are retrieved from a database. 

The code I have works splendidly when I use keyboard selections from the combobox dropdown list - but not when the user uses a mouse to select an item from the 'initialList'. I’m having a hard time making this work…

Is this a problem that can be solved? If so How? 

 package com.nomogen.pegging.components; 

import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.swing.AutoCompleteSupport; 
import com.nomogen.jobshop.dao.HibernateUtil; 
import com.nomogen.jobshop.hibernate.Part; 

import java.beans.Beans; 
import java.util.List; 
import javax.swing.JComboBox; 
import javax.swing.SwingWorker; 

import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.criterion.Restrictions; 

/** 
 * 
 * @author DBolsover 
 */ 
@SuppressWarnings("serial") 
public class PartNumberComboBox extends JComboBox<String>{ 
    public static String            PROP_PART = "part"; 
    @SuppressWarnings("unchecked") 
    private final EventList<String> data      = new BasicEventList<>(); 
    private long                    when      = 0l; 
    private Part                    part; 
  

    /** 
     * Constructs ... 
     * 
     */ 
    public PartNumberComboBox() { 
        init(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param partial_no 
     * 
     * @return 
     */ 
    private List<String> dataList(String partial_no) { 
        Session  session = HibernateUtil.openSession(); 
        SQLQuery q       = 
            session.createSQLQuery("select p.part_no from Part p where p.part_no like :partial_no order by 1 asc;"); 

        q.setString("partial_no", partial_no + "%"); 

        @SuppressWarnings("unchecked") List<String> dataList = q.list(); 

        HibernateUtil.closeSession(); 

        return dataList; 
    } 

    /** 
     * @return the part 
     */ 
    public Part getPart() { 
        return part; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param part_no 
     * 
     * @return 
     */ 
    private Part getPartbyId(String part_no) { 
        Session session = HibernateUtil.openSession(); 
        Part    p       = (Part) session.createCriteria(Part.class).add(Restrictions.eq("part_no", 
                              part_no)).uniqueResult(); 

        HibernateUtil.closeSession(); 

        return p; 
    } 

    /** 
     * Method description 
     * 
     */ 
    @SuppressWarnings("unchecked") 
    private void init() { 
        if (!Beans.isDesignTime()) { 
            data.addAll(initialList()); 
            AutoCompleteSupport.install(this, data); 

           this.addPopupMenuListener(null); 

            addItemListener(new java.awt.event.ItemListener() { 
                @Override 
                public void itemStateChanged(java.awt.event.ItemEvent evt) { 
                    partNumberCooserItemStateChanged(evt); 
                } 
            }); 
            addActionListener(new java.awt.event.ActionListener() { 
                @Override 
                public void actionPerformed(java.awt.event.ActionEvent evt) { 
                    partNumberCooserActionPerformed(evt); 
                } 
            }); 
            
        } 
    } 

    /** 
     * Method description 
     * 
     * 
     * @return 
     */ 
    private List<String> initialList() { 
        Session                                     session     = HibernateUtil.openSession(); 
        SQLQuery                                    q           = 
            session.createSQLQuery("select distinct left(p.part_no, 1) from Part p order by 1 asc;"); 
        @SuppressWarnings("unchecked") List<String> initialList = q.list(); 

        HibernateUtil.closeSession(); 

        return initialList; 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private void partNumberCooserActionPerformed(java.awt.event.ActionEvent evt) { 
        if (evt.getWhen() - when > 50) { 
            String part_no = (String) this.getSelectedItem(); 
            Part   p       = getPartbyId(part_no); 

            setPart(getPartbyId(part_no)); 
        } 

        when = evt.getWhen(); 
    } 

    /** 
     * Method description 
     * 
     * 
     * @param evt 
     */ 
    private synchronized void partNumberCooserItemStateChanged(final java.awt.event.ItemEvent evt) { 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { 
            @Override 
            @SuppressWarnings("unchecked") 
            protected Void doInBackground() throws Exception { 
                String partial_no = (String) evt.getItem(); 
                int    length     = ((String) evt.getItem()).length(); 

                data.getReadWriteLock().writeLock().lock(); 

                try { 
                    if (length < 1) { 
                        for (String s : initialList()) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } else { 
                        List<String> moreData = dataList(partial_no); 

                        for (String s : moreData) { 
                            if (!data.contains(s.trim())) { 
                                data.add(s.trim()); 
                            } 
                        } 
                    } 
                } finally { 
                    data.getReadWriteLock().writeLock().unlock(); 
                } 

                return null; 
            } 
        }; 

        worker.execute(); 
    } 

  

    /** 
     * @param part the part to set 
     */ 
    public void setPart(Part part) { 
        Object oldValue = getPart(); 

        this.part = part; 
        firePropertyChange(PROP_PART, oldValue, part); 
    } 

    
    
}