domingo, 29 de julio de 2007

Y ahora los Layouts

He solucionado hoy mismo el problema que tenía con respecto al tamaño de un botón que creé. Bueno, no fue solo, pedí ayuda en un foro (en el de elhacker.net) y tuve una buena respuesta por parte de un usuario: los Layouts. Yo no sabía muy bien lo que eran, simplemente había leído unas notas rápidas cuando daba repasos a un tutorial de Java, no recuerdo exactamente cual, pero mis conocimientos sobre ello eran insignificantes y los tuve que reforzar hasta ahora para deshacerme del problema del botón.

Más o menos le agarré la onda: son formas de organizar una ventana y se crean usando la interfase LayoutManager, por suerte Java tiene creadas varias clases por defecto que implementan esa interfaz para hacer la vida más fácil. Los programadores de Java ya las conocerán: BorderLayout, GridLayout, CardLayout, etc.

Simplemente cambié éste trozo de mi clase (ubicado en el constructor):

setBackground(Color.CYAN);
setSize(256, 256);
setVisible(true);


Por este:

setBackground(Color.CYAN);
setSize(256, 256);
setLayout(new BorderLayout());
setVisible(true);


Y el botón se muestra del tamaño que le he mandado.

Aunque todo esto no ha quedado muy en claro: el problema se ha resuelto, pero no se ha comprendido, no me señalo with the index finger porque ya no es falta de razonamiento, sino la libertad de equivocarme que me doy. Si pongo el BorderLayout() después del setVisible(boolean) el botón aparece igual, aunque le añada un repaint(), pero no voy a batallar con eso, pues tengo la impresión de que la clave estará en controlar mejor a los Layout y saber de qué van los principales.

No me voy a presionar, he aprendido mucho tan sólo en este día: reafirmación de mis conocimientos con la creación de objetos, herencia y polimorfismo. Aprendí lo que son las interfaces y los Layouts... y los listeners y cómo implementarlos. Creo que para un solo día está muy bien.

Voy a seguir probando con esta clase Prueva a ver hasta dónde llego haciendo cositas varias como quizá otro botón, algún cuadro de texto y manipular sus eventos.

Por el momento ya tengo solucionados los problemas y lo que haré después de darle "Publicar entrada" es algo que ignoro: quizá siga programando, quizá me ponga a leer al saco, ver tele, jugar... no sé.

"Bueno chau" <--- ¿quién dice así? :-P

sábado, 28 de julio de 2007

Interfaces y Listeners en Java ;-)

¡Por fin! Esto no fue un quebradero de cabeza como los que me llevaba con el NekroEditor, lo que ocurre es que como ando saliendo de la novata del ámbito de Java aún me encuentro con conocimientos nuevos. Esta vez tuve que comprender bien cómo era eso de las clases abstractas, tuve que aprender sobre las interfaces que no es nada difícil pero tuve que arrancar de la nada y comprenderlo todo.

Lo que intenté solucionar fue el por qué mi programita de una ventana con un botón no cerraba cuando le hacía click en la tachita, lo que me costó googlear y leer durante varias horas en foros y manuales que tengo en del.icio.us. No voy a relatar toda la historia porque son tantos los lugares que vi, tantas las conclusiones que saqué que ya hasta se me olvidaron; jajaja bueno, será que se me olvidaron los sitios y el orden pero los conocimientos ya los tengo.

Una de las cosas que hice fue examinar un código que había hecho y que venía en un tutorial de Java que descargué hace años, el primero que tuve y que imprimí para leerlo en papel que fue el que me dio la introducción clave. Resulta que fue el primero al que se me ocurrió recurrir cuando me inicié verdaderamente en esto. El caso es que ahí venía un sencillo ejercicio de crear un Applet con unos cuantos elementos. Lo ejecuté y vi que la ventanita se cerraba, el código era este:


public void processEvent(AWTEvent mensaje){

        if (mensaje.getID() == Event.WINDOW_DESTROY){
              if (inAnApplet){
                     dispose();
              }
              else{
                     System.exit(0);
              }
       }

/* return super.processEvent(mensaje); */

}


Me pareció algo tonto y decidí estudiar la clase directamente de la página de la API de Sun, bueno, entré e intenté buscarla pero no apareció por el índice, no sé ni cómo di con ella pero me di cuenta que era otra de las funciones que había dejado el Java Team obsoletas. No sé si lo que hicieron con SDK 6 fue un gran salto o volver a reprogramar el lenguaje de programación porque hay más "deprecated functions/methods/fields" que cosas nuevas :-S Es por ello que me resultó muy complicado seguir con los tutoriales que encuentro en internet como el que imprimí que es de hace casi 10 años creo y me tuve que arrancar a la intuición y las googleadas partiendo de la página de la API de sun, que tuve que hacer mi mejor amiga (Google ya lo era, de hecho es mi tío).

Estaba deprecada la función, lo demás fue tirada de rollo mías. Me dijo algo que ya había leído antes: "usa processWindowEvent(WindowEvent e) si quieres ser alguien en el futuro" puesto que, aunque aún servía la clase Event, eso de usar cosas por compatibilidad con lo viejo no es lo mío. Ni modo, a aprender a usar los eventos.

Y ese compromiso fue muy difícil ya que usar processWindowEvent va también de saber usar las interfaces debido a que, para que este método sirva de algo hay que añadir donde sea que se pueda ejecutar un addWindowListener que es como un "agregarEscuchadordeEventos".

Java ya tiene uno por defecto, al igual que cada Sistema Operativo en su API, el Gestor de Eventos que se encarga de procesar los mensajes de los controles en general. Pero hay un problema con esto: las aplicaciones de Java pueden ejecutarse de dos formas: como Applets y como aplicaciones Standalone, los Applets se pueden visualizar acuñándolos en el código HTML de una págia y verlos en el navegador o con el appletviewer que incluye Java, y las Standalone desde la consola, son como los programas básicos en C que usan stdio.h. Si estamos en modo Standalone matamos una aplicación con System.exit(0); y si estamos en un applet usamos dispose(); pero Java no tiene forma de saber si la aplicación es arrancada desde una consola o desde el navegador puesto que lo único que hay es un bytecode .class, la forma en que lo queramos ejecutar es otra cosa, entonces no tiene forma de saber cómo acabar una aplicación. Y en la misma página de Sun terminé de disipar toda duda que pudiera tener (Clase Frame):

Frames are capable of generating the following types of WindowEvents:


  • WINDOW_OPENED

  • WINDOW_CLOSING:
    If the program doesn't explicitly hide or dispose the window while processing this event, the window close operation is canceled.

  • WINDOW_CLOSED

  • WINDOW_ICONIFIED

  • WINDOW_DEICONIFIED

  • WINDOW_ACTIVATED

  • WINDOW_DEACTIVATED

  • WINDOW_GAINED_FOCUS

  • WINDOW_LOST_FOCUS

  • WINDOW_STATE_CHANGED




Justamente el mensaje que necesitaba se ve bloqueado y no me queda más de otra que agregar un WindowListener. WindowListener es una interfase, y yo apenas sabía los conceptos básicos de las interfaces, en fin que estuve leyendo un par de horas ya algo hastiado pero como mi curiosidad era más grande no me quedó de otra que aguantarme, y es que cuando le llega a uno el "¿y si la solución está en el siguiente?" remuerde quedarse con la duda de si el próximo resultado, el próximo párrafo o el próximo intento serán los correctos.

Implementar una interfase fue lo más fácil, puesto que sólo tenía que declarar los métodos y ponerlos en blanco: {} salvo el que necesitaba, donde había que poner un System.exit(0);.

Pero no tenía idea de cómo usar el addWindowListener(WindowListener l), pues el tipo de datos que requería el parámetro era una interfaz y no sabía dónde tenía que implementarla: buscando códigos de ejemplo vi dos que me resultaron muy raros y que hasta ahora no entiendo del todo bien:

public static void main(String s[]) {
   JFrame frame = new JFrame("A Basic Frame");

   WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
         System.exit(0);
      }
   };
   frame.addWindowListener(l);
   //BLA BLA BLA
}


Que es de esta página: Cómo Crear Frames (Ventanas Principales). Luego otro de elhacker.net:

...bueno es este: HAKIIIII!!!11eleven Es que está muy largo.


Pero no son el objeto de mi explicación estos códigos que no entiendo bien cómo usan la interfase.

Perp ya pude solucionarlo: creo una clase que implemente la interfase WindowListener, luego creo una instancia de esa clase y se lo paso a addWindowListener. Sencillo pero para mi mente poco adentrada en Java le costó algo de trabajo asimilarlo, y me siento muy orgulloso de haber logrado esto, aprendí varias cosas el día de hoy y pude solucionar un problema y prever más.

El código resultante el siguiente, el cuál es el que llevo hasta ahora, pero le seguiré modificando muchas cosas porque, como ya dije antes, sigo con el problema de que mi botón de comando se redimensiona apenas encuentra un pretexto:

import java.awt.*;
import java.awt.event.*;

public class Prueva extends Frame{

       public static void main(String args[]){

              Prueva app = new Prueva("Hols!");

       }

       public Prueva(String title){

              super(title);

              wndListener Eventos = new wndListener();
              addWindowListener(Eventos);


              /*Button button = new Button("Heisann");
              add(button);
              button.setBackground(Color.MAGENTA);
              button.setLocation(64, 64);
              button.setSize(64, 64);*/

              setBackground(Color.CYAN);
              setSize(256, 256);
              setVisible(true);

       }

       protected void processWindowEvent(WindowEvent e){

              super.processWindowEvent(e);

       }

}


class wndListener implements WindowListener{

       public void windowOpened (WindowEvent e){}

       public void windowClosing (WindowEvent e){

              System.exit(0);

       }


       public void windowClosed (WindowEvent e){}

       public void windowIconified (WindowEvent e){}
       public void windowDeiconified (WindowEvent e){}

       public void windowActivated (WindowEvent e){}
       public void windowDeactivated (WindowEvent e){}

}


Hilsener.

kolorwhore

Voy de pasada porque sigo programando en Java. Resulta que he estado modificando el template del blog para que se ajuste a mis gustos y necesidades, aunque por veces no me siento muy orgulloso de decir "gusto" por cosas que explico en el título de esta entrada.

Para agilizar los cambios de formato de los textos y códigos que publico, y ahorrar también letras HTML en vano le he añadido mi propia sección de modificaciones a la plantilla CSS que usa esto y hasta el día de hoy va así:


/* NekroTemplate
----------------------------------------------- */
/* blockquote{
color: rgb(192, 192, 192);
} */

comment{
color: rgb(255, 255, 255);
}

code{
color: rgb(192, 192, 192);
font: $bodyfont;
}

red{ color: rgb(255, 0, 0); }
green{ color: rgb(0, 255, 0); }
blue{ color: rgb(0, 0, 255); }

cyan{ color: rgb(0, 255, 255); }
yellow{ color: rgb(255, 255, 0); }
magenta{ color: rgb(255, 0, 255); }


Los cambios que le he puesto por si los llego a necesitar para no estarlos programando en ese entonces som los últimos: las definiciones de RGB y CYM.

De modo que si aquí en la vista HTML tipeo:


<red>Rojo</red> <green>Verde</green> <blue>Azul</blue>
<cyan>Cyan</cyan> <yellow>Amarillo</yellow> <magenta>Magenta</magenta>


Me sale


Rojo Verde Azul
Cyan Amarillo Magenta


¿Les gusta? No me refiero a la combinación de colores :#( sino a los efectos. Pueden hacer cosas como estas y facilitar el engorroso "hespan eztile igual comillas" porque bueno, yo uso la vista HTML para escribir mis entradas y cuando toca poner colores tengo dos opciones: o acordarme y adaptarme o pasar a la vista normal pero no me gusta porque luego ahí se modifican códigos y de vez encuando se producen pequeños desastres que, aunque corregibles, son molestos, perturbadores, piedras-en-el-camino.

Sigo codeando entonces.

Un extraño pack() en Frame ??

Esto va con relación al post anterior.

Al parecer Java hace alguna especie de pack() interno, o al menos he descubierto que es el software de programación y no yo quien es responsable de que mi botón se muestre del tamaño de la ventana y no como yo lo asigno.

No voy a citar imágenes ni códigos pasados porque el presente revela lo que quiero mostrar a la luz. Para esto basta analizar este pequeño código en el constructor de una clase extends Frame:

Button button = new Button("Heisann");
button.setBackground(Color.MAGENTA);

add(button);
setBackground(Color.CYAN);
setTitle("Hols!");
setSize(256, 256);
button.setSize(64, 64);
System.out.println(button.getSize());
setVisible(true);
System.out.println(button.getSize());



y lo que me tira la consola:


[nekrobyte@localhost Prueva]$ javac Prueva.java
[nekrobyte@localhost Prueva]$ java Prueva
java.awt.Dimension[width=64,height=64]
java.awt.Dimension[width=246,height=226]
[]


Ahh, el último [] que puse es para representar al cursor cuadrado que indica dónde se va a insertar el próximo caracter, en realidad no había nada pero es que si tampoco pongo nada siento que no dejo las cosas muy en claro ;-)

Tengo que ver qué hago con eso porque no confío mucho en asignar las propiedades a todos mis controles en el futuro después de abrir el telón.

viernes, 27 de julio de 2007

EODLFEFAEP

¡Puaj! ¡Qué lastre! Ni bien acabo de escribir el post pasado y ya confirmé mis sospechas: el orden de los factores, en efecto, altera el producto.

Si usamos este código dentro de main:

Prueva app = new Prueva();

Button button = new Button("Heisann");
button.setBackground(Color.MAGENTA);
button.setSize(64, 64);

app.add(button);
app.setBackground(Color.CYAN);
app.setTitle("Hols!");
app.setSize(256, 256);
app.setVisible(true);


Obtendremos esto:



Pero si ponemos:

Prueva app = new Prueva();

Button button = new Button("Heisann");
button.setBackground(Color.MAGENTA);

app.add(button);
app.setBackground(Color.CYAN);
app.setTitle("Hols!");
app.setSize(256, 256);
app.setVisible(true);
button.setSize(64, 64);


Obtenemos:



De esto concluimos que:

El orden de los factores, en efecto, altera el producto


O lo que es más corto: EODLFEFAEP. Por cierto, "EF" significa "En Efecto", y es que me gusta más dibujar "EF" que "EE", nada personal, sólo preferencias ;-)

Progman i Java

No sé si ya lo había comentado antes, pero me inicié con la programación en Java desde hace, digamos, un par de meses... o tal vez tres, no lo sé, pero no es mucho que digamos. En este tiempo me he estado instruyendo con varios manuales que conseguí en internet y la página de la API de Java por Sun ha sido un sitio de constante visita. Por fortuna había estudiado Java cuando tenía como 13 o 14 años pero como no tenía en qué practicar y apenas sabía algo de programación fracasé, pero ya no me resultó tan difícil recobrarme ahora que volví puesto que, aunado a aquella experiencia, llegué con más noción de la programación orientada a objetos gracias a Visual Basic y las ojeadas que le daba a C++.

El punto es que ahora resulto ser programador novicio en Java, comenzando pero viendo hacia'l frente.

Los problemas ahora vienen con Java, cosa que para mí es una noticia amigable :-)

Estos liado con un código en Java. Practico la programación gráfica de Java y me empiezo por crear figuras basadas en las clases de AWT. Por ahora lo que quiero es algo muy sencillo: crear un una ventana con un botón, sólo eso. Para la ventana uso la clase Frame y para el botón la clase Button. El código es pequeño cabe en un único archivo llamado Prueva.java:

import java.awt.*;
import java.awt.event.*;

public class Prueva extends Frame{

       public static void main(String args[]){

              Prueva app = new Prueva();

              Button button = new Button("Heisann");
              button.setBackground(Color.MAGENTA);
              button.setSize(64, 64);

              app.add(button);
              app.setBackground(Color.CYAN);
              app.setTitle("Hols!");
              app.setSize(512, 512);
              app.setVisible(true);

       }

       public Prueva(){

              //

       }

       /*protected void processWindowEvent(WindowEvent e){

              if (e.getID() == e.WINDOW_CLOSING) {
                     System.exit(0);
              }

       }*/


}


Lo que consigo con esto es que se cree una ventana de unos 512 x 512 con el título "Hols!" y en ella... ahí el problema. Se supone que

Button button = new Button("Heisann");
button.setBackground(Color.MAGENTA);
button.setSize(1, 1);


Era para que creara un botón de 64 * 64 y que lo pusiera donde se le de la gana, pero no es así, por el contrario aparece uno de 512 * 512, y algo que he comprendido en este ejemplo que he programado es que, según parece, el orden de los factores altera el producto. Hay una instrucción: setVisible(boolean) de Frame que, dependiendo de dónde la coloque, hará que se pinte de Color.CYAN todo el fondo de la ventana pero que cuando redimensione (haciendo más grande la ventana) el fondo nuevo aparezca también pintado o de color gris.

Por el momento esto es lo que llevo, habrá que descubrir la solución.

El verdadero quebradero de cabeza lo explicaré más tarde pero es con los eventos de la aplicación, pero decidí corregir primero esto del tamaño del botón, es por ello que dejé como comentario lo demás.

Saludos.

jueves, 19 de julio de 2007

El Pingûino de Vitrubio

En estos momentos me encuentro escribiendo bajo una nueva distribución que al fin pude tener el gusto de probar, Knoppix 5.1.1 corriendo bajo una DELL Optiplex de 512 de RAM.



Antes había pensado en incendiar un disco pero por unos problemas que tuve con mi quemador lo fui a dejar en garantía para reposición a principios de enero y hace como dos semanas me lo devolvieron; ahora que cuento con uno más moderno y, digamos, una torre de 20 CDs que me regaló mi padre, me decidí a descargarlo para quemarlo de una buena vez y probarlo.

Ya he dado mi opinión de Mandriva: es el que estoy usando ahora y me parece de lo más excelente, aunque no cuento con cliente para instalar o descargar programas desde la consola tales como apt o aptitude, pero no importa, me las arreglo.

Ubuntu para mí fue un fiasco: aunque la instalación de Edgy Eft resultó satisfactoria, el precario Gnome con que venía me pareció con muchas limitaciones, casi nada configurable... en fin, creo que es por Gnome, ya que ese entorno de escritorio nunca me agradó, desde la primera vez que lo vi, ni el diseño ni el nautilus. Favor de no tomar como ofensa, es que simplemente no me gusta Gnome... aunque tampoco es que me caiga mal, para nada, es bien buena onda ese wue y mis paisanos han hecho un muy buen trabajo programándolo.

...Pero basta que este espacio no es para hablar de Ubuntu, sino del pingûino de Vitrubio de Linuxim, el nodo 3.

Hasta ahora me ha parecido muy agradable, no me dio problemas de ningún tipo, salvo la primera vez que lo arranqué y la pantalla se quedó en negro pero con el led amarillo, volví a intentar y esta vez salió todo bien.

Pantalla inicial
Pantalla inicial

Y aquí es donde manifiesto que no encontré la forma de ajustar la pantalla a XGA correctamente, y no sé si sea problema mío o de Linux (Knoppix, pues ;-) ) porque de poder puedo: click derecho y todo lo demás, se cambia pero no se ajusta, únicamente se muestra en el monitor lo que cabe, como si mi monitor no soportara para más. ¡Ah! Pero si paso el mouse por la parte de abajo se corre la vista y va apareciendo el panel de tareas con el menú K y todo, si ruedo la flechita hasta el extremo lateral izquierdo se corre la pantalla y se van mostrando los iconos del escritorio.

Raro pero así es, por lo que decidí no usar tiempo en indagar profundamente en cuestiones que en realidad no me interesan del todo... vaya, esto ni tiene la hora correcta pero no se lo compuse porque no tengo interés en que se vea la hora bien. De cualquier forma cuando extraiga el CD del lector todo lo que haya hecho se va a ir a la mierda.

Seguí probando para ver qué tal las cosas



Comencé abriendo el navegador, lo primero que se me ocurrió, lo encontré en el panel de tareas y no era el habitual Firefox, sino IceWeasel, y aquí fue donde rompí con mi desconocimiento de la bifurcación de la apuesta de Mozilla:


vs


¿El La Zorra de Fuego o La Comadreja de Hielo?

No hay mucha diferencia, ambos usan el motor de Firefox y, a menos que prestes atención al icono, te sentirás tal cual Firefox, así que para qué seguir, hablar de IceWeasel es hablar de Firefox.

Después se me ocurrió conectarme pero por alguna extraña razón supuse que no iba a estar mi usado Kopete, sino el Gaim.. y así fue: el Gaim, que en Knoppix 5.1.1 y en Mandriva 2007 aún no aparece como Pidgin, no necesita comentarse, sólo que... funciona igualito que en Mandriva y Ubuntu, jajajajajajajaja.

Otra cosa muy importante, la música. El reproductor que usé fue el primero que vi en el menú de Multimedia que más tenía la cara de poder abrir los OGG que tenía en la partición Ext3 donde guardo todo lo valioso que tengo. El reproductor es el XMMS que aparece en arriba a la derecha en la segunda captura, reproduciendo Holy Mountains de System of a Down. No le he checado bien las opciones, me limité a añadirle una lista para que la reprodujera lo cuál hizo muy bien pero en sí la poca funcionalidad que me dí tiempo de conocer no estuvo muy buena que digamos, cuesta entenderle sin etiquetas que den una señal de para qué es cata minibotón blanco.

De la interfaz gráfica no me quejo, así como tampoco voy a sostener de todo las críticas que aporto a este sistema operativo, ya que ellas no son los comentarios de un usuario avanzado de Knoppix, ni de Linux, sólo son "la primera impresión" que tuve al usar Knoppix, el vistazo, y no dudo de retractarme de muchas cosas si frecuento Knoppix.

Eso sí, es un SO muy bien trabajado, con una interfaz gráfica agradable y armónica, me encantó mucho la apariencia del panel de KDE, sus gráficos, su nitidez.

Definitivamente, después de perder la virginidad que tenía en Knoppix, lo recomiendo !!

sábado, 7 de julio de 2007

Recordatorios

Cada vez que uso MySQL después de dejarla en el abandono durante un buen tiempo suceden problemas, no sé por qué.

El punto es que ahora el problema fue que por alguna razón no podía realizar la operación describe [table]; y me marcaba el error:

ERROR 1 (HY000): Can't create/write to file '/root/tmp/#sql_10b7_0.MYI' (Errcode: 13)


ni como root.

Busqué unos segundos por Google y di con la respuesta:

aberselli
had the same problem... now solved... :)
two ways:
1)chmod 777 root (deprecated for security reason)
chmod 777 root/tmp
2)edit your /usr/local/etc/my.cnf
add or edit
[mysqld]
tmpdir = /tmp/

way 2 works belive me :) :mambo: :)


Sólo era cosa de ir a mi my.cnf y agregarle el trozo [mysqld] LF
tmpdir = /tmp/
que se explica y listo.

Me costó algo de trabajo porque como llevaba tiempo sin dialogar en SQL ni me acordaba dónde estaba ese archivo, hasta que después de como 2 minutos me acordé que era en /etc/my.cnf, lo abrí como root y lo edité, downié el servidor (oquei, mexicanizando el verbo 'to down') y lo volví a inicializar. ¡Listo! pude hacer el describe user; de la table mySQL.

Si a alguien le ayuda esto cuanto mejor, porque el blog está indexado en Google y para eso puse todas estas especificaciones: para que se llegue más fácilmente; aunque la realidad es que lo postié cono nota, como recordatorio para cuando se me vuelva a olvidar esto, y es que como ni lo practico casi (no tengo mucha necesidad de bases de datos) pues se me pierde.

Por lo mismo agregaré otras notas.

Iniciar MySQL :#(       (primero ir a /usr/local/mysql/bin)
[nekrobyte@localhost bin]$ ./mysqld_safe --user=[NekroByte||root] -p &

Insertar datos (que también para ingresar un nuevo usuario)
mysql> INSERT INTO [tabla] (campo1, campo2, ...) VALUES (valor1, valor2, ...);

Borrar datos
mysql> DELETE FROM [tabla] WHERE [expresión];

Cambiar contraseñas;
mysql> SET PASSWORD FOR '[usuario]'@'[host]' = Password('TU-FECHA-DE-CUMPLEAÑOS');

Actualizar Privilegios
mysql> FLUSH PRIVILEGES;


Y creo que con esto es suficiente... sino pues le agrego, ¿cuál es el problema?

SaludosJílsenerKambioIPhuera!