style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Ayuda con filtracion de datos mediante keyreleased

Buenas, estoy haciendo un sistema y aplique un buscador con el keyreleased y me funciono a la perfeccion pero quisiera saber si me ayudan para que se muestre solo con las letras que inicia cada dato por ejemplo:

Buscar: M

*Maria
*Marta
*Carlos Martinez

en lugar de:

Buscar: M

*Maria
*Carmen

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

fuente

De dónde vienen tus datos? De una base de datos, o están en memoria?

No es recomendable que hagas un SELECT en cada teclazo del usuario. Pero si son datos que ya tienes en memoria y sólo quieres filtrar sobre eso, pues con una expresión regular. Aunque no es muy claro qué quieres buscar; con tu ejemplo, podríamos decir que sólo quieres buscar M mayúscula, o sea que la búsqueda sea sensible a mayúsculas, que es lo más fácil; o también quieres encontrar por ejemplo "mario" pero no "carMen"?

En fin, si es insensible a mayúsculas pero que sea la primera letra de una palabra, me parece que es una expresión regular [Mm].*|.*\s[Mm].*

En Groovy esta expresión:

['Maria','carMen','mario','Carlos Marquez'].findAll { it ==~ /[Mm].*|.*\s[Mm].*/ }

Me devuelve Maria, mario, Carlos Marquez

los datos los recojo de una

los datos los recojo de una base de datos... entonces que es recomendable para filtrar datos?
porque cuando yo busco por ejemplo:

Buscar: c (ya sea en mayuscula o minuscula)
me salen datos como por ejemplo:
Carlos Arias
Francisco Luna
Martha Sanchez

y lo que yo quiero es q solo muestre datos q empiecen con lo que yo pongo en el jtextfield que no importe si yo pongo en mayusculas o minusculas

Imagen de ezamudio

ilike

Tu PreparedStatement con este SQL SELECT * FROM tabla WHERE campo ILIKE ?

Y le pasas como parámetro C* (supongo que actualmente le pasas *C*)

La cosa es que si ejecutas esa consulta en respuesta a un teclazo del usuario, puedes terminar enviando muchísimas consultas seguidas y finalmente ni vas a usar los resultados de las consultas intermedias. Eso va a generarle mucha carga a la base de datos, además innecesaria porque ni siquiera estás utilizando los resultados. Por ejemplo si empiezas a teclear CAR, y lo haces rápido, vas a disparar tres consultas a la base de datos, pero solamente vas a usar los resultados de la última; los de las otras dos ya ni te sirven.

Lo mejor para esos casos es una combinación de búsqueda en base de datos y posteriormente un filtro sobre los resultados en memoria, combinado con un timer para hacer la búsqueda periódicamente cuando el valor cambia, o un buffer para agrupar todos los teclazos y solamente realizar la búsqueda cuando hay una pausa mayor a cierto tiempo entre teclazos.

Gracias, pero como haria para

Gracias, pero como haria para que tecleando una letra me salgan todos los datos que "EMPIECEN" con dicha letra

Desde luego gracias por responder

Para explicarlo mejor:Yo

Este es otro problema que tengo es con defimalformat

Para explicarlo mejor:

Yo ingreso estos datos:
http://www.subirimagenes.net/i/140813091750106198.png

Y quisiera que no pase esto:
http://www.subirimagenes.net/i/140813091757917523.png

Gracias de antemano

Imagen de ezamudio

DecimalFormat

Ese es sencillo. new DecimalFormat("0.00"). Si lo quieres con comas separando magnitudes, el formato sería "#,##0.00"

DecimalFormat

Y eso como le aplicaria en el jtable lo estaba intentando pero no sabia como!

Imagen de ezamudio

ni idea

Tiene años que no toco Swing.

Probablemente no es necesario DecimalFormat

Sería bueno que mostraras un poco del código que estás usando para asignar los datos a tu JTable... ¿estás usando el diseñador de formularios de netbeans o estás desarrollando todo el código tú?

@ezamudio Estoy intrigado con

@ezamudio Estoy intrigado con lo que acabas de decir sobre filtrar los resultados en memoria, el timer y/o el buffer, yo suelo hacer lo mismo que menciona kristxpher, lo de las consultas cada vez que se da un teclazo, porque no se me ocurría ningún otro método. ¿Tendrás un ejemplo de como implementar el filtro de resultados en la memoria porfavor?

Imagen de ezamudio

no

No tengo código para eso, pero hay varias maneras de implementar ese patrón. Pero probablemente ya haya alguna biblioteca que lo haga. Y si no, pues una manera simple es más o menos así (me lo estoy improvisando, en Groovy):

class Buscador {
  JdbcTemplate jdbc //para buscar en base de datos
  String query = "SELECT *FROM tabla WHERE columna ILIKE ?" //configurable
  private List<Map<String,Object>> results //la lista obtenida
  String columna //La columna por la que quieren filtrar
  private String last //La ultima cadena buscada

  void reset() {
    results = null
    last = null
  }
  //Este lo llaman cada keyPressed
  List<Map<String,Object>> filtra(String s) {
    s = s.toLowerCase()
    if (last != null && !(last.startsWith(s) || s.startsWith(last))) {
      results = null
    }
    if (results == null) {
      //TODO esto no debería hacerse en el mismo hilo de la GUI, hay que usar SwingWorker y sincronizar esto para evitar que se hagan varias llamadas si la consulta se tarda
      results = jdbc.queryForList(query, s+"*")
      last = s
      return results
    } else {
      last = s
      return results.findAll { it[columna] == null || it[columna].empty || it[columna].toLowerCase().startsWith(s) }
    }
  }
}

De tu GUI debes tener un KeyListener o como se llame pegado a un JTextField, ese recibe los teclazos (y ahí harías el buffering en todo caso), y ahí es donde invocas al Buscador, pasándole el texto actual del textfield. El Buscador la primera vez que tecleas algo, como no tiene resultados, va a la base de datos por ellos, pero de ahí en adelante solamente filtra en memoria, a menos que la cadena cambie por completo, pero sirve para cuando estás tecleando y si acaso borras alguna cosa.

Suponte que está en blanco tu campo. Tecleas C, entonces el Buscador va a la base de datos por los registros que comienzan con C o c. Luego tecleas A, entonces sobre los registros que ya trajo el Buscador, que ya los tiene en memoria, filtra y te devuelve sólo los que empiezan con CA (combinaciones de mayúsculas/minúsculas). Luego tecleas R, entonces igual en memoria te trae los que empiezan con CAR. Das backspace, la nueva cadena es CA otra vez, el buscador te da esos filtrando en memoria. Tecleas M, filtra en memoria y te trae los que empiezan con CAM. Pero si seleccionas el texto y tecleas D, entonces se sustituye todo y como D no se parece en nada a lo que estabas filtrando, pues va de nuevo a la base de datos.

En cuanto al buffer de teclazos, es un poco más elaborado; es algo similar a lo que hace Hystrix con lo de colapsar varios eventos en uno solo.

Codigo

Este es el codigo que utilizo para mostrar los datos en el jtable

public TblProgramas() {
        initComponents();  
        conexion();
        cargarProgramas("");
        FormatoProgramas();
        centrar_datos(0);
        centrar_datos(2);
        centrar_datos(3);
        centrar_datos(4);
        centrar_datos(5);
        setLocationRelativeTo(null);
    }
   
    private void cargarProgramas(String valor) {
        try {
            String titulos[] = {"Cód.", "Programas", "Precio", "Idioma", "Clasificación", "Tamaño"};
           
            m = new DefaultTableModel(null, titulos);
            JTable p = new JTable(m);
            String fila[] = new String[6];
            TblProgramas.conectate obj = new TblProgramas.conectate();
            String consulta = "SELECT * FROM verprogramas where CONCAT(idProgramas,' ',Programas,' ',Precio,' ',Idioma,' ',Clasificacion, Tamano) LIKE '%"+valor+"%'";
            ResultSet r;
            r = obj.Listar(consulta);
            while (r.next()) {

                fila [0] = r.getString(1);
                fila [1] = r.getString(2);
                fila [2] = r.getString(3);
                fila [3] = r.getString(4);
                fila [4] = r.getString(5);
                fila [5] = r.getString(6);
                m.addRow(fila);
               
            }
            tblProgramas.setModel(m);
            decimalestabla(2);
            centrar_datos(0);
            centrar_datos(2);
            centrar_datos(3);
            centrar_datos(4);
            centrar_datos(5);
            FormatoProgramas();
            sorter = new TableRowSorter<TableModel>(m);
            tblProgramas.setRowSorter(sorter);
            this.tblProgramas.setModel(m);
            tblProgramas.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "Error al extraer los datos", "Advertencia", JOptionPane.WARNING_MESSAGE);
        }

esta es la clase que cree para darles formato a los decimales:

public class Renderdeci extends DefaultTableCellRenderer {
 
    private DecimalFormatSymbols simbolos;
    private DecimalFormat formateador;
 
    public Renderdeci() {
        simbolos = new DecimalFormatSymbols();
        simbolos.setDecimalSeparator('.');
        formateador = new DecimalFormat("###0.00", simbolos);
    }
   
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

        return this;
    }
   
}

y asi es como la inserto:

private void decimalestabla(int colum) {
            tblProgramas.getColumnModel().getColumn(colum).setCellRenderer(new Renderdeci());
        }
Imagen de julgo

no era necesario que

no era necesario que mostraras todo el código para los decimales ni tampoco es necesaria tu clase para dar formato .
con una línea de código puedes agregar lo que preguntabas y es mas legible

int numero=10;
//este código inserta una fila con una sola columna , agregale mas columnas si deseas
m.addRow(new String[]{ new DecimalFormat("#,##0.00").format(numero)});

DecimalFormat

Hola de nuevo, bueno yo no soy un experto en el lenguaje ni en swing, pero puedo ver que hay algunos problemas de diseño en tu código (revuelves código de manejo de interfaz gráfica con consultas a la base de datos, por ejemplo) y esto a la larga te puede traer confusiones o problemas cuando quieras dar mantenimiento al programa.

Bueno, como tu código es funcional, me propuse hacer un par de sugerencias para ayudarte a que quede como deseas haciendo los menos cambios posibles.

1) He visto que estás declarando un arreglo de Strings para crear la fila: String fila[] = new String[6]; lo cual creo que es un error porque el formateador DecimalFormat no te cambiará el formato de un String, sino de un número (por ejemplo, Double), por lo que mi primera recomendación es que cambies ese arreglo de String por un arreglo de Object: Object fila[] = new Object[6];

2) Estás dándole formato a la columna de Precio después de haber insertado todas las filas que vienen de la base de datos, te recomiendo que muevas las instrucciones

tblProgramas.setModel(m);
decimalestabla(2);

antes del while(r.next())

3) Investigué en google un ejemplo de DefaultTableCellRenderer y me encontré con este link: http://stackoverflow.com/questions/9834508/defaulttablecellrenderer-gett...
Por lo que vi que es necesario agregar un par de instrucciones al método que estás sobreescribiendo en Renderdeci:

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
       
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                row, column);
       
        this.setText(formateador.format(value));
       
        return this;
    }

4) Estás guardando todos los datos de tus filas en un mismo arreglo, te recomiendo que dentro de while(r.next()) instancies de nuevo el arreglo fila = new Object[6];

5) Estás obteniendo puros Strings con el método r.getString();, te recomiendo que cambies de método por cada tipo de dato que te devuelve cada columna, por ejemplo, para precio supongo que querrás usar r.getDouble(3);

Uff, espero no se me esté olvidando nada jeje, con esto creo que ya debería formatearte el número como tú quieres

Gracias

Muchas Gracias... hare lo que me sugieres... esas respuestas son las que me ayudan a mejorar... ya que estoy aprendiendo

De nuevo gracias!!

Funciona

He hecho lo que me has sugerido y si me sirvio pero me sale con un solo decimal es decir 2.0, 8.0, etc..
No lo entiendo xq yo declaro esto en el decimalformat (###0.00)

De antemano gracias, hasta ahora ha sido la mejor respuesta

Imagen de paranoid_android

Problema de palabras Parecidas

Para encontrar textos con palabras parecidas existe el algoritmo Levenshtein. tiene implementaciones en varios lenguajes e incluso en bases de datos.
Mientras que el problema de las consultas a la base de datos para esa particular funcionalidad podría servirte una base de datos NOSQL. Mongodb u otra.

Imagen de ezamudio

WHAT?

En serio estás recomendando usar NoSQL simplemente por un algoritmo que además está super sobrado para lo que piden?

Imagen de paranoid_android

Solo es una opción

Solo son opciones, si les puede servir y si realmente es lo que buscan.
Para el requerimiento del inicio, no para el segundo.

LLegue muy tarde al foro...

Pues

Hola, pues no será posible saber qué está pasando si no podemos ver el código... ¿ya probaste debuggeando y poniendo puntos de interrupción para ver qué entra y qué sale de la instrucción formateador.format();?

Si quieres, puedes postear aquí una parte RELEVANTE de tu código (no postees todo porque es confuso), alguna parte que no entiendas como funciona o donde creas que esté el error

Clase

No se en que este mal pero hice lo que me dijiste en la clase renderdeci y nada
este es el codigo de la clase:

public class Renderdeci extends DefaultTableCellRenderer {
 
        private final DecimalFormatSymbols simbolos;
        private final DecimalFormat formateador;
 
        public Renderdeci() {
        simbolos = new DecimalFormatSymbols();
        simbolos.setDecimalSeparator('.');
        formateador = new DecimalFormat("###0.00");
        }
   
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
       
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                row, column);
       
            this.setText(formateador.format(value));
     
        return this;
    }
   
}

setMinimumFractionDigits

¿Ya probaste poniendo esto en tu constructor: formateador.setMinimumFractionDigits(2);?

EDICION: También creo que te falta asignarle los símbolos al formateador: formateador = new DecimalFormat("#,##0.00", simbolos);

Solucionado

Muchas Gracias ya lo solucione.. no hubo necesidad de crear la clase... tan solo hice los cambios que me dijiste sobre object, etc...

y lo que hice fue:

DecimalFormatSymbols simbolo = new DecimalFormatSymbols();
simbolo.setDecimalSeparator('.');
DecimalFormat formateador = new DecimalFormat("###0.00", simbolo);
while(r.next())
.....
fila [2] = formateador.format(r.getFloat(3))

Y listo todo me funciono!

Y ahora volviendo al tema principal (que ya me desvie jeje) tu sabes como hacer lo del filtro de datos pero solo que me aparezca datos que inicien con lo que yo escribo!

ya te dijeron

Ya te dijo ezamudio en los primeros comentarios hechos, que puedes utilizar en tu consulta "SELECT * FROM tabla WHERE campo LIKE '" + valor + "%'",
y además filtrar los datos obtenidos mediante expresiones regulares.
Aunque en vez de usar la consulta "plana" te recomendaron usar PreparedStatement e insertar el string de filtro. También por rendimiento, ezamudio te recomendó hacer una sola consulta a la base de datos y para el resto de tecleos filtrar a partir de los datos que ya tienes en memoria, para lo cual también nos mostró un poco de código de cómo podría hacerse (aunque en groovy y usando clases especiales como JdbcTemplate), algo que te tocaría averiguar cómo hacer si te interesa

Imagen de ezamudio

No concatenes

No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA.

Usa un PreparedStatement y pásale la cadena. ps=conn.prepareStatement("SELECT* FROM tabla WHERE campo LIKE ?") y luego le pasas el parámetro con ps.setString(1, "C*") (en JDBC usas asterisco y ya el driver lo sustituirá por un % si eso es lo que usa la base de datos).

No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA. No concatenes SQL NUNCA.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">