La elegancia y performance del código en Swing
¡Muy buenas días/tardes/noches a todos!
Éste será mi primer thread oficial (aunque ya llevo un tiempecito por acá, primero como Guest y luego como Usuario), llevo bastante leyendo los foros y contenido de la página de JavaMéxico (hasta asistí a la conferencia de Benek en CP2010).
Bueno, no agarraré un thread público en el foro de Java SE para publicar sobre mí, eso está reservado para un blog, pero haré una introducción breve, siento que la ocasión lo amerita, ¿O no?
Soy estudiante de Ingeniería en Sistemas Computacionales y a pesar de que ya voy bastante avanzado, aún no quiero tomar una decisión sobre qué área me gustaría más (i.e: programación, redes, DBA, etc.); lo que sí sé es que me encanta la carrera y a todo le encuentro gusto: mi hobbie es mi trabajo y mi trabajo es mi hobbie, se podría decir.
Por ahora, me encanta programar, empecé con C. Avancé bastante en ese lenguaje y comencé a picar Java. He de admitir que al principio me constaba trabajo pasar de un paradigma estructurado a uno orientado a objetos, pero la dedicación me ha permitido comprenderlo bien y seguir aprendiendo por mi cuenta.
¡Suficiente! Si llegaron a esta parte, gracias, podemos pasar a lo que nos concierne y tema del thread.
En todo lenguaje de programación se debe apuntar a mejorar el código, lograr los resultados más óptimos en la menor cantidad de tiempo. Por supuesto, Java no es la excepción y gracias a mi obsesión por querer hacer las cosas bien, les traigo este pedazo de código.
Supongamos que tenemos un JTextArea de Swing llamado mainTextArea. Adicionalmente tendremos un JLabel (cuyo nombre es irrelevante para el caso) en el cual se obtendrá la línea donde se posiciona el Caret (el "cursor" que indica dónde comenzaremos a escribir) cada vez que se produzca un evento de tipo caretUpdate, es decir, cada vez que el Caret se mueva a alguna posición, el Label se refrescará con la nueva posición.
Ahora bien, la API para Swing en Java no proporciona (hasta donde sé) un método per se para obtener la línea exacta donde se encuentra el Caret (recordemos que el método getCaretPosition() no regresa la información que buscamos), así que tendremos que ingeniárnoslas por nosotros mismos.
Esencialmente, lo que hace este código es obtener todo el texto a partir de la posición del Caret en el textArea y guardarlo en un String temporal, para posteriormente contar cuántos saltos de líneas tenemos y finalmente, aplicar esa información mediante una resta para sacar la cantidad de saltos de línea por encima del Caret.
Sencillo y hace el trabajo correctamente, sin embargo, podría apostar que no es la mejor opción. Probablemente se me escapa un método en la API, pero, hasta donde sé, no hay un método explícitamente para esto o que, en todo caso, facilite la tarea.
¿Alguien tiene una mejor idea de implementar esto? Si nos ponemos a pensar o incluso, implementar este método, notaremos un pequeño lag que prueba que se exige de más a la aplicación para una simple tarea.
Adicionalmente y para generar debate, me gustaría saber las técnicas que usan para mejorar sus algoritmos o implementaciones.
¡Saludos a todos!
- Inicie sesión o regístrese para enviar comentarios
Lag?
SI notas un lag ejecutando ese código tal vez deberías de hacer un upgrade a un 386... ya en serio, cómo puede haber un lag en algo tan simple?
La única optimización que le haría a eso es que si vas a recorrer tooooodos los caracteres del string, tal vez te convenga más hacer algo como esto:
Pero fuera de eso creo que está bien. Hay maneras de hacer lo mismo con menos código, pero creo que en cuanto a performance, lo que haces es una buena opción.
Jajaja
Sí, un lag a la hora de escribir en el textArea; me explico: Cuando escribes se nota que las letras van apareciendo muy poco después, casi puedes dejar de escribir mientras se pone la letra, aunque sí, intentaré en otra máquina.
Fíjate que me había pasado por la cabeza lo de convertir el String en un arreglo de caracteres usando ese método, pero tenía entendido que un String ya es una especie de arrelgo, pero convertido en un objeto y se me hizo algo redundante pasarlo al tipo primitivo char para hacer lo mismo.
Aunque talvez este razonamiento no es del todo correcto, ¿Qué diferencia habría entre recorrer un String y recorrer un array char?
lag
Ese código entonces lo invocas cada vez que se teclea algo? Con razón... Si estás detectando teclazos y empiezas con el texto vacío entonces no está tan complicado, solamente debes incrementar tu contador con cada \n o flecha hacia abajo y decrementarlo con cada flecha hacia arriba (se puede complicar un poco dependiendo del comportamiento de las teclas Home y End). Pero eso no toma en cuenta cuando pegas o cortas texto...
jaja chido titulo "La
jaja chido titulo "La elegancia y performance del código en Swing" elegancia en Swing?? no creo, performace?? tampoco, creo que es uno de los puntos debiles de Java, pero hay muchas alternativas muy buenas para arreglar esto, como Adobe Air por ejemplo..
nombre pa que, mejor amonos
nombre pa que, mejor amonos con winforms no?
Jugaré un rato con la idea
Jajaja, sí, lo invoco cada que el caret se mueve. Pero tienes razón, por ahí le intentaré. También me habían comentado un approach con multithread, un hilo que espera cada cierto tiempo para actualizar el JLabel, jugaré un rato y posteo más tarde cómo me fue por si alguien tiene un problema igual o parecido.