Últimas entradas del blog

Java Swing 2: Crear ventanas con Eclipse

2012-12-08 - Categorías: Java / Java Swing

Para éste microtutorial he usado el Swing Designer de Eclipse y la versión 1.7 update 9 de Java, el JDK y el JRE.

En Eclipse tenemos tenemos varias opciones para generar código esqueleto para nuestro programa. En la ventana del explorador de proyectos, en el lugar elegido le damos con el botón derecho a New -> Other… y nos saldrá una ventana como la siguiente con las opciones disponibles con respecto a Swing:

En el árbol de Swing Designer tenemos las opciones para crear programas con ventanas Swing, valga la redundancia. Todos los códigos generados con el Swing Designer también se pueden crear a mano y se pueden llevar a otros entornos de desarrollo y te van a funcionar. Ésto lo digo porque no ocurre siempre, según en qué entorno de desarrollo estés, a veces pasa que si te sales de él ya no te sirven los códigos porque se les han puesto «extras» que te atan a ellos. Ésto no te va a pasar con los Swing en Eclipse, o por lo menos yo no me encontrado con éste problema.

Vamos al grano…

Application Window

Si elegimos una Application Window nos va a crear la clase siguiente:

package pruebasSwing;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class ApplicationWindowPrueba {

    private JFrame frame;

    // primero se ejecuta ésto…
    public static void main(String[] args) {
        // en un hilo de ejecución aparte hace todo
        // porque todo lo hace en un new Runnable
        // a continuación…
        EventQueue.invokeLater(new Runnable() {
            // run es el método que se ejecuta
            // al arrancar el hilo
            public void run() {
                try {
                    // crea una variable de la clase y se inicializa
                    // con el constructor de la misma                  
                    ApplicationWindowPrueba window = new ApplicationWindowPrueba();
                    // muestra la ventana
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    // éste es el constructor de la clase
    public ApplicationWindowPrueba() {
        initialize();
    }

    // la función que inicializa
    private void initialize() {
        // crea el frame
        frame = new JFrame();
        // coordenadas de la ventana
        frame.setBounds(100, 100, 450, 300);
        // establece la operación a ejecutar cuando
        // se cierra el JFrame
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

Se trata de una clase que no hereda de ninguna otra, y lo que simplemente hace es crear un JFrame en un hilo de ejecución separado.

JApplet

Un Applet es una programa de Java que se ejecuta en un navegador de Internet. Éste programa se le envía al cliente mientras que navega y se ejecuta en su máquina. Nos crea lo básico para hacer uno, pero a fecha de hoy están totalmente en desuso y los navegadores los desactivan por defecto.. Así que mejor ni probarlo…

package pruebasSwing;

import javax.swing.JApplet;

// clase que extiende de JApplet,
// que a su vez extiende de la clase
// Applet y ésta en sí es un Panel…
public class JAppletPrueba extends JApplet {

    // el constructor
    public JAppletPrueba() {

    }
}

JDialog

Con ésta opción generaremos el código para hacer un típico cuadro de diálogo con el usuario para que se le informe de algo o elija entre las opciones que queramos. Éste tipo de ventanas se usan asociadas a otra ventana padre, aunque al tener un main se puede generar un .jar ejecutable que sólo tenga un cuadro de diálogo de éstos.

El código que genera:

package pruebasSwing;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

// la clase que extiende de JDialog,
// que a su vez extiende de Dialog,
// y ésta de Window…
public class JDialogPrueba extends JDialog {

    private final JPanel contentPanel = new JPanel();

    public static void main(String[] args) {
        try {
            // crea un nuevo objeto de la clase
            JDialogPrueba dialog = new JDialogPrueba();
            // operacion al cerrar
            dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            // lo muestra
            dialog.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // constructor de la clase
    public JDialogPrueba() {
        // propiedades de la ventana
        setBounds(100, 100, 450, 300);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setLayout(new FlowLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
       
        // los botones para confirmar o cancelar
        {
            JPanel buttonPane = new JPanel();
            buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
            getContentPane().add(buttonPane, BorderLayout.SOUTH);
            {
                JButton okButton = new JButton(«OK»);
                okButton.setActionCommand(«OK»);
                buttonPane.add(okButton);
                getRootPane().setDefaultButton(okButton);
            }
            {
                JButton cancelButton = new JButton(«Cancel»);
                cancelButton.setActionCommand(«Cancel»);
                buttonPane.add(cancelButton);
            }
        }
    }

}

JFrame

Con el asistente del JFrame, hace casi lo mismo que con el de Application Window, pero hay dos ligeras diferencias. La primera es que con Application Window tenemos una variable interna a la clase que es el JFrame, y con el éste lo que tenemos es que la clase misma extiende a JFrame, con lo que realmente tenemos un JFrame en sí que se puede reutilizar en otros lugares del programa. La segunda diferencia es que añade un JPanel al JFrame, cosa que con el asistente de Application Window no lo hace.

El código es el siguiente:

package pruebasSwing;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

// la clase extiende de JFrame, realmente ES un JFrame
public class JFramePrueba extends JFrame {

    private JPanel contentPane;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    JFramePrueba frame = new JFramePrueba();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public JFramePrueba() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        // añade el panel…
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
    }

}

JInternalFrame

Ésta clase se usa para hacer ventanas que se ejecutan dentro de un JDesktopPane. Es decir, dentro de la misma ventana padre, tendremos una zona que será un panel de escritorio, el anterior JDesktopPane. Y en éste panel es donde veremos el JInternalFrame. Así que necesitaremos un JFrame padre para poder ejecutarlo dentro.

Ésta clase tiene un main pero no se puede ejecutar en un .jar aparte.

El código:

package pruebasSwing;

import java.awt.EventQueue;
import javax.swing.JInternalFrame;

public class JInternalFramePrueba extends JInternalFrame {

    // arranca en un hilo el formulario hijo
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    JInternalFrame frame = new JInternalFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    // aquí estará construida la ventana
    public JInternalFramePrueba() {
        setBounds(100, 100, 450, 300);

    }

}

JPanel

Ésto es una clase básica que podemos usar en otros formularios o ventanas. Es decir, podemos poner paneles dentro de JFrames. Así que puede ser útil tener un panel programado aparte. El código que genera es:

package pruebasSwing;

import javax.swing.JPanel;

public class JPanelPrueba extends JPanel {

    // constructor de la clase
    public JPanelPrueba() {

    }

}

Swing Automatic Databinding

Aquí tenemos un asistente que nos va a crear lo necesario para crear una ventana con Databindings. Necesitaremos un Bean, y configurar las diversas opciones. Ésto es bastante extenso así que ya tengo tema para otro post.. 🙂

Terminando

Las principales clases que primero se van a usar van a ser la ApplicationWindow o la JFrame. De éstas la JFrame es bueno usarla de un principio porque luego la puede incluir dentro de otros proyectos sin muchos cambios.

Dentro de Eclipse podemos visualizar todos los anteriores con F11, menos el JInternalFrame y el JPanel que se podrá visualizar dentro de otro. Una vez generado el código correspondiente, podremos entrar a editar el diseño visualmente, con lo que nos ahorraremos un considerable esfuerzo.

Con ésto me voy a la cama y mañana más…

Un saludo!


Java Swing 1: A vista de pájaro

2012-12-05 - Categorías: Java / Java Swing
En éste post, espero dar un vistazo general al paquete de clases de Java de Swing, en concreto a la versión estándar 1.7 update 9. En la fecha en que escribo ésto, los Swing ya no están en desarrollo, con lo que no se van a añadir nuevas funcionalidades, ni componentes. En la web de Oracle, podemos ver la jerarquía completa del paquete javax.swing en la documentación original, aquí teneis el árbol de la jerarquía de clases:

Casi todas las clases que hay para crear nuestra interfaz de usuario van a empezar por J, como JFrame, JDialog, JButton, JLabel, etcétera… Ya tengo instalada la versión del JDK y del JRE más nueva ahora mismo para asegurarme de que tengo al día el paquete de clases. Así pues, la ayuda contextual de Eclipse me muestra un listado de todos éstos componentes:
Tenemos 46 clases en éste listado, de las cuales la clase con la que se contruyen todas las demás clases visuales es JComponent. El resto de clases de Swing que no comienzan por J, ayudan o nos sirven de herramientas para éstas. Quitando la JComponent, nos quedan 45 clases que «dibujan» nuestra interfaz gráfica.

Estado actual

Swing se contruyó a partir de AWT, es decir se basa en AWT, que es más dependiente del Sistema Operativo. De ésta forma los programas hechos con Swing son más independientes del Sistema Operativo, así que mejor si usamos Swing porque está más elaborado. Otro tema es JavaFX, que es el siguiente «level» en la programación gráfica que la gente de Java están desarrollando. JavaFX promete ser más independiente del Sistema Operativo si aún cabe, prometiendo en un futuro que tu programa desarrollado en JavaFX llegue a ser compatible con cualquier dispositivo que tenga gráficos, como móviles, televisiones, coches, incluso en una página web dicen en los vídeos de Oracle siempre que tengamos la máquina virtual de Java instalada. Pero todo ésto se va del tema del post que tenemos entre manos…

Contenedores externos

Volviendo a los Swing, de todas éstas clases tenemos las clases que nos van a ayudar a estructurar nuestro programa en ventanas, diálogos, paneles.. en donde vamos a poner el resto de componentes. Éstas clases son las siguientes:
  1. JFrame -> es la madre del cordero, la clase que normalmente se usa para que contenga el resto de componentes, es la principal.
  2. JApplet -> para construir un applet.
  3. JDesktopPane -> crea una zona donde podemos poner ventanas internas (JInternalFrame).
  4. JDialog -> es una ventana de diálogo.
  5. JInternalFrame -> ventana hija que debe estar dentro de un escritorio (JDesktopPane).
  6. JLayer -> crea un borde alrededor de otro componente.
  7. JLayeredPane -> es un panel con borde.
  8. JPanel -> un panel simple sin adornos ni nada.
  9. JRootPane -> panel principal que puede contener otros objetos.
  10. JScrollPane -> es un panel que sirve para contener objetos que se salen del campo, entonces con barras de scroll podemos movernos por ellos.
  11. JSplitPane -> sirve para dividir una zona en dos, en cada subdivisión podemos poner otros elementos.
  12. JTabbedPane -> parecido al JSplitPane pero divide las zonas en pestañas.
  13. JViewPort -> es un objeto que sirve para visualizar los otros objetos que se mueven en una ventana, como por ejemplo con barras de scroll.
  14. JWindow -> es como un JFrame pero sin bordes ni botones para cerrar, maximizar y minimizar.
Pueden crearso objetos anteriores y meterse unos dentro de otros, algunos se pueden omitir y otros son necesarios. Por ejemplo si queremos ventanas internas debemos de ponerlas dentro de un panel de escritorio (JDesktopPane), sino no funcionará.

El resto de componentes

Vistos los anterioes 14 elementos, nos quedan 45 menos 14 que son 31 componentes. Éstos que quedan son más conocidos y en cuanto leemos sobre ellos seguro que sabemos de qué hablamos.
Los clásicos:
  1. JButton -> para hacer botones.
  2. JCheckBox -> cajas chequeables.
  3. JComboBox -> pues el combo de siempre, creo que se llama «caja de selección desplegable».
  4. JLabel -> para poner etiquetas.
  5. JList -> implementa una lista seleccionable.
  6. JOptionPane -> panel donde podemos poner opciones a elegir.
  7. JPasswordField -> campo de contraseña.
  8. JProgressBar -> barras de progreso.
  9. JRadioButton -> estos son los elementos que dan varias opciones a elegir, en la que sólo una es posible.
  10. JEditorPane -> para poner textos complejos, admite HTML y  texto en el formato Rich Text Format (RTF).
  11. JFormattedTextField -> para poner textos con formato.
  12. JTextArea -> areas de texto donde podemos poner textos grandes, multilínea.
  13. JTextField -> areas de textos pequeños, de una sola linea de texto.
  14. JTextPane -> admite textos formateados, iconos y componentes.
Unas utilidades:
  1. JColorChooser -> nos sirve para mostrar una ventana donde podemos elegir un color.
  2. JFileChooser -> éste objeto es una ventana para elegir un archivo.
Menús:
  1. JMenu -> ésto es un menú que podemos poner dentro de una barra de menú o dentro de otro menú.
  2. JMenuBar -> barra de menús, dentro de ésta se ponen el resto de los elementos de los menús.
  3. JMenuItem -> es un elemento de menú.
  4. JCheckBoxMenuItem -> cajas de texto seleccionable en un menú.
  5. JPopupMenu -> implementa un menú desplegable.
  6. JRadioButtonMenuItem -> para poner opciones a elegir en un menú.
  7. JSeparator -> es una raya entre elemento y elemento de menú.
Otros:
  1. JToolBar -> es una barra de herramientas para personalizar.
  2. JToolTip -> muestra un texto al pasar por encima de un componente.
  3. JScrollBar -> barras de scroll.
  4. JSlider -> es una barra que puedes mover arriba y abajo con la que elijes un valor.
  5. JSpinner -> es una caja de texto con dos botones arriba y abajo para cambiar el valor de la caja.
  6. JToggleButton -> botón con dos estados, presionado y no presionado.
  7. JTable -> se usa para mostrar tablas de datos, como su nombre indica.
  8. JTree -> es un árbol, que puede servir para mostrar por ejemplo un árbol de directorios.
Con ésto ya nos podemos hacer una idea de las posibilidades que tenemos para hacer una interfaz de usuario con Swing.
Espero que sirva de ayuda.
Un saludo.

Multiprocesamiento en Java: ¡Dale caña a tu procesador!

2012-11-17 - Categorías: General / Java

Multiprocesamiento, como reza la Wikipedia, se refiere a la ejecución de varios procesos de manera concurrente, es decir, a la vez. Con los nuevos procesadores que cada vez nos traen más núcleos, he visto que ésto viene a ser más importante. Con Java el multiprocesamiento para aprovechar los núcleos de uno o varios procesadores viene gestionado con la máquina virtual de Java. Es decir, sólo tendremos que preocuparnos de hacer el programa de manera que se puedan ejecutar ‘a trozos’, poner cada tarea en un hilo de ejecución y luego la máquina virtual se encargará de gestionarlo todo.

Ésto es lo mismo que viene ocurriendo con los Sistemas Operativos (SO). Tenemos muchos procesos que se ejecutan desde que arrancamos el ordenador, y el SO se encarga de gestionar qué se ejecuta en cada momento. De igual manera nosotros en Java podemos gestionar qué se ejecuta o que se queda esperando, también podemos decirle a todas las tareas que se ejecuten a la vez simplemente sin esperar unas a otras ni nada parecido. Ésto es lo que vamos a ver con el ejemplo sencillo de a continuación, donde se van a crear dos tareas, a y b, y se van a ejecutar concurrentemente.

Continuar leyendo..

El SlideShow más simple con jQuery

2012-11-14 - Categorías: General

Un slideshow viene a significar visor de imágenes o diapositivas que van pasando una tras otra.

Estuve buscando para descargar slideshows para web. Encontré de todo tipo, muy elaborados y con muchos extras, unos de pago y otros gratis, pero no era lo que yo quería. Buscaba algo lo más sencillo posible para adaptarlo luego donde lo necesite y al final acabé programándolo a partir de jQuery.

Aquí va el código para el que lo necesite:

<html>
<head>
<!– Con ésto incluyes el jquery en tu web usando en CDN de Google –>
<script src=»https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js»></script>
</head>
<body>

<img id=»imagenslide» src=»imagenes/imagenInicial.jpg» alt=»Imagen de una mascota..» />

<script>
  cambiaSlideShow();

function cambiaSlideShow() {
// variables para configurar
var dirImagenes = ‘imagenes/’; // directorio donde estan
 // las imágenes, se deben nombrar de la forma
 // 1.jpg
 // 2.jpg
 // etcétera…
var numImagenes = 3; // número de imágenes que hay

// elige un número aleatorio para mostrar las imágenes
// aleatoriamente
var randomNum = Math.ceil(Math.random() * numImagenes);

// con ésto la imagen desaparece y cuando ha desaparecido
// cambia de imagen
$(‘#imagenslide’).fadeOut(3000,
function () {$(‘#imagenslide’).attr(‘src’, dirImagenes + randomNum + ‘.jpg’);}
);

// con ésto otro la imagen aparece con un efecto fade de nuevo
$(‘#imagenslide’).fadeIn(3000);
setTimeout(function () {cambiaSlideShow(); }, 7000);
}

</script>
</body>
</html>

Y un archivo para descargar el ejemplo haciendo click aquí.
Ten en cuenta que debes poner las imágenes en el directorio dirImagenes que tengas en dicha variable.

Un saludo.


Ponle un Favicon a tu web

2012-11-13 - Categorías: General
Ya le he puesto al blog un Favicon, y les dejo un nuevo post.
Cuando navegas por Internet, las páginas muestran un icono en tu navegador. Cuando agregas dicha web a Favoritos, Marcadores, o como se llame en el navegador que uses.. También verás dicho icono asociado a dicha página web. Ésto es lo que se llama ‘el Favicon’.

Favicon, viene de Favourites Icon, icono de favoritos en castellano. Nació para darle mejor estética al listado de páginas de nuestra lista de páginas web favoritas. Y si quieres que tu web tenga una imagen de éstas lo único que debes hacer es usar un código tal que así:

<html>
<head>
<title>Aquí va el título</title>
<link href=»http://direcciondetuweb/favicon.ico» rel=»icon» type=»image/x-icon»>
</head>
<body>
<p>Contenido de la página.</p>
</body>
</html>

La imagen debe ser de 16×16 pixeles tradicionalmente, también puede ser de 32×32, incluso se pueden usar en algunos navegadores imágenes en JPG, PNG y GIF. Pero éstas otras opciones no son totalmente estándar y puede que no funcionen en todos los navegadores.
En éste blog, gracias a Blogger, tengo disponible el gadget llamado tal cual Favicon, que automáticamente me genera el código de aquí arriba. Yo te lo he detallado por si acaso lo usas en otro sitio.
Así que, después de éste post ¿no merece que agregues ésta web a favoritos? agregame a favoritos y así me visitas de vez en cuando 😉
Un saludo.

Hola Mundo con Swing y Eclipse

2012-11-10 - Categorías: Java / Java Swing
Aquí dejo cómo crear una primera aplicación gráfica en Java usando Swing y Eclipse. El ejercicio clásico ¡Hola Mundo! usando una tecnología que nos brinda Java crear aplicaciones con entorno gráfico, Java Swing. Y para verlo, el entorno de desarrollo elegido ha sido Eclipse.

Curioseando qué tal van los desarrollos, con respecto a las interfaces gráficas de usuario (llamadas GUI para los amigos), veo que tengo otra nueva actualización del Window Builder. El Window Builder es un conjunto de plugins de Eclipse que nos van a permitir hacer GUIs en Java sin gastar casi tiempo.

A fecha de hoy tengo la versión Juno de Eclipse, y me acabo de instalar el plugin Swing Designer que está disponible dentro del propio Eclipse, en la famosa opción Help -> Install New Software. Instalada la versión 1.5.1 del Swing Designer, me he puesto manos a la obra.

En el Explorador de Proyectos, donde estés creando tu aplicación Java, le das con el botón derecho del ratón a New -> Other… Y verás una ventana como la siguiente donde puedes elegir todo el tipo de ficheros, clases, o lo que sea que quieras hacer:
Se parece a Visual Studio, NetBeans o IDEs similares ¿verdad? Personalmente no creo que Eclipse tenga nada que envidiar a ningún otro entorno de desarrollo de pago, o no de pago. ¿Qué más queremos teniendo Eclipse? Parezco un vendedor de Eclipse (jejejje es broma). Bromas aparte, depende de dónde te encuentres te irá mejor un entorno de desarrollo u otro…
Seguimos con lo que tenemos entre manos. He creado mi nueva Application Window que he llamado HolaMundoSwing y se me abre una ventana dentro de Eclipse tal que así:
Me ha generado 44 líneas de código, con las que ya tengo mi ventana con el programa básico. Tenemos disponible absolutamente todo el código necesario para crear aplicaciones con GUIs, es decir, que no se nos esconde nada del código fuente. Podríamos usar éste mismo código fuente en línea de comandos, y compilar nuestro programa Java con el javac.exe sin usar Eclipse. Lo que quiero explicar, es que Eclipse te genera y te da todo el código fuente, sin crear archivos secundarios en tu proyecto donde gestione la parte gráfica. No te atas a Eclipse. Es decir, en éste caso todo lo necesario está dentro del mismo fichero, te puedes llevar ésta recién creada aplicación de ventanas a otro sitio con sólo llevarte el fichero HolaMundoSwing.java y seguir programando.
Vamos ahora a lo que más nos va a interesar, el diseñador de formularios que nos va a ahorrar mucho tiempo en el diseño de la interfaz de usuario. Abajo tenemos una pestaña que pone ‘Design’, diseño en castellano. Le damos y nos sale una ventana como la siguiente. Aquí es donde podemos editar visualmente todo tipo de componentes visuales del estilo de botones, cajas de texto, grupos de selección, podemos poner imágenes, menús, y un largo etcétera…
Cómo se usa cada componente merece un post, así que éste lo voy a dejar así.

Lo lógico es que quieras juguetear poniendo componentes en tu nueva ventana. Para poder posicionarlos donde quieras hay que poner antes de nada en el formulario un ‘Absolute layer’ que tenemos en la sección ‘Layouts’. Después ya podrás poner los componentes donde quieras. En pocos segundos he puesto un botón, una etiqueta y una caja de selección, como podemos ver en la imagen de aquí arriba. Si volvemos a la pestaña de abajo donde pone ‘Source’, en nuestro Eclipse, veremos que automáticamente se ha generado todo el código correspondiente para dibujar los componentes en nuestro GUI. Queda después añadir el código para hacer funcionar cada cosa.

Puedes hacer doble click en el botón para ver la facilidad con que puedes empezar a programar. Se te pondrá delante el código fuente y la función donde puedes programar el click del botón. Verás un código tal que así:

JButton btnNewButton = new JButton(«Botu00F3n»);
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// AL HACER CLICK EJECUTA ÉSTO
}
});
btnNewButton.setBounds(10, 11, 89, 23);
frmholaMundoSwing.getContentPane().add(btnNewButton);

Aquí queda ésta pequeña introducción a los Swings de Java. Si quieres hacer un fichero ejecutable de Java, un .JAR y distribuir el programa que acabas de hacer; en la ventana del explorador de proyectos, le das con el botón derecho del ratón al fichero HolaMundoSwing.java. Se despliega el menú y le haces click en Exportar. Luego eliges Java JAR file. Eliges destino. Y ya tienes un ejecutable .jar que puedes usar en cualquier ordenador con el JRE instalado.
Un saludo.

Cómo montar un servidor propio con Joomla y Uniform Server

2012-11-05 - Categorías: General
Hola! Ya tengo algo de tiempo, estoy poniéndome al día y navegando veo que hay una nueva versión de Joomla, la 3.0.1. También veo que tengo disponible una nueva versión del Uniform Server, tengo la 8.5.7 y ya existe la 8.6.7, así que me he puesto las pilas para actualizarme y de paso os hago éste post.
Joomla ya es compatible con móviles, es la primera plataforma web compatible 100% con móviles, eso escriben en JoomlaSpanish.org. Así que con ésto, es un buen momento de probar la nueva versión.
Si estas aquí supongo que ya sabrás que Joomla es un CMS, un sistema para manejo de contenidos, y que el Uniform Server es un servidor de páginas web con base de datos MySQL y otros extras más… Si no lo sabías ya lo sabes, Joomla es una aplicación web, que instalada en un servidor web, te proporciona todas las utilidades necesarias para gestionar una página web medianamente compleja.
No voy a entrar en detalle sobre las diferencias entre usar un CMS ya hecho, usar un framework de desarrollo de webs, o programar todo directamente desde cero. Tal vez en otro post.
Asi que empezemos a montar un servidor propio…
Un poco de teoría
Antes de entrar directamente a instalar programas, sin saber lo que estamos haciendo debemos saber algunas cosas. Si eres un veterano, o muy valiente, pásate éste apartado xD
Todo en Internet, mientras navegamos, ocurre de la misma manera. Tenemos nuestro navegador, en el que ponemos las direcciones de Internet, le damos al Enter o al botón de turno, y mágicamente nos sale la página web. A ver, hay que entender que es lo que ocurre. Tenemos lo que se llama un cliente (navegador), y un servidor (el programa que nos envía a nuestro ordenador la página web y la podemos ver en nuestro navegador). Éste servidor web es lo que vamos a instalar. Y en concreto, el Uniform Server, que me atrevo a decir es muy buena opción.
Lo que vamos a hacer es simular lo que ocurre en Internet mientras navegamos, pero en nuestro ordenador en red local.

Ingredientes
  1. Uniform Server.
  2. Joomla en versión castellano.
El Joomla, en castellano, lo tienen en http://www.joomlaspanish.org/
Uniform Server es un proyecto en SourceForge.net, disponible en:
Y su página oficial es:
Sobre los ingredientes
He probado el XAMPP, que también es una buena opción, pero he elegido el Uniform Server para el trabajo de servidor web Apache con PHP y MySQL porque no hay que instalarlo, símplemente se descomprime. Y además es portable, es decir, que lo puedes llevar en un USB con toda tu web configurada y ejecutarla en cualquier ordenador con Windows sin tener que instalar todos los programas asociados a un servidor web (que pueden llegar a ser muchos).
Por otro lado, Joomla no es sólo un CMS, sino que también es un framework de desarrollo de aplicaciones web. La comunidad de Joomla, surgió del antiguo Mambo. He leido que hubo conflicto entre algunos de los actuales desarrolladores de Mambo y algunos de Joomla, que antes programaban juntos en Mambo, entonces se dividieron creando Joomla a partir de una versión de Mambo. No voy a entrar en la rumorología, el hecho es que Joomla surgió de Mambo, otro CMS anterior. Y ahora según las últimas estadísticas Joomla es el CMS más utilizado.
Joomla está construido en PHP, y actualmente trabaja sobre MySQL y se está añadiendo que pueda trabajar con otras bases de datos a fecha de hoy. Ésto es muy resumido porque Joomla es muy extenso e incluye gran cantidad de componentes. Es decir, tenemos un monton de archivos que descargaremos de la página, y éstos archivos van a ejecutarse de manera que todos los datos de Joomla se van a guardar en una base de datos. Es importante saber ésto porque tanto los archivos del directorio, como lo que haya en la base de datos forman tu web, no puedes separarlos.
El servidor web
Muy bien, llegado éste momento. Ya debemos tener descargados los archivos para el Joomla y el UniServer. Vamos a descomprimir primero el UniServer la versión completa del server, se llama Coral, debe ser uno llamado Coral_version.exe. Al arrancarlo te pide la carpeta donde lo quieres instalar, yo le he puesto C: y entonces me queda una estructura tal que así:
Arrancas el archivo Start_as_service.exe para usarlo como servicio instalándolo dentro del propio Windows. De ésta manera cada vez que arranques de nuevo Windows estará funcionando. Si lo prefieres usar como un programa sin instalarlo, puedes arrancar Start_as_program.exe y no necesitarás instalarlo como servicio. Yo lo tengo instalado como servicio, como podeis ver en la imagen.
Si no queremos complicarnos, sólo queda descomprimir el archivo de Joomla en el directorio C:UniServerwww y ya tendremos el servidor propio de Joomla en nuestro ordenador. Y accediendo a http://localhost/ veremos el Joomla que nos pide los datos para configurar la web.
Ésto es lo estrictamente necesario, de ésta manera te limitas a sólo tener una página web, y pierdes la página principal del UniServer. Yo prefiero configurarlo de otra manera, usando «hosts virtuales» y poniendo cada web en la carpeta que yo quiera. Me gusta tenerlo todo muy organizado, cada cosa en su carpeta, y poder acceder a cada página web de nuestro ordenador de la forma siguiente, por ejemplo:
http://localhost/  <- ésta es la página principal de nuestro servidor
http://unapaginajoomla/ <- ésta es la página web que vamos a configurar
http://temporal/ <- otra página web
etcétera…
Imaginemos que hemos puesto en D:MisPaginasWebunapaginajoomla los archivos de Joomla descomprimido, y en D:MisPaginasWebtemporal otra página web.
Vamos entonces a configurar los llamados «hosts virtuales», de manera que tengamos varios hosts en nuestra misma máquina. Entonces abrimos el panel de control del Uniform Server. Vamos a Server Configuration -> Apache -> Apache Vhosts. Entonces elegimos directorio D:MisPaginasWebunapaginajoomla, le ponemos el nombre debajo (en éste caso «unapaginajoomla») y confirmamos, y si no hemos tenido error le damos a Create Vhost. Reiniciamos el Apache con el panel de control del UniServer y ahora ya podremos acceder al Joomla que acabamos de descomprimir mediante el navegador poniendo http://unapaginajoomla/
Lo mismo podemos hacer con el directorio D:MisPaginasWebtemporal poniéndole como nombre de host virtual ‘temporal’ por ejemplo. Y así tantos hosts como queramos.
Yo prefiero tenerlo así para tener todas las páginas web localizadas en un directorio. Y a la vez puedes configurar tu entorno de desarrollo web para que acceda a esos directorios. Esto te puede ayudar a programar más organizadamente, pero ya entramos en otro tema que no viene al caso en éste post.
Podemos configurar el servidor de forma que nos sirva para un entorno de producción, o para desarrollo. Si estás programando en PHP o construyendo una web nueva con Joomla, te interesará activar ésto:
Dentro del panel de control del UniServer, entras a:
Server Configuration -> PHP -> Switch to Developement Configuration file
Así verás cualquier error o advertencia mientras que trabajas con el Joomla.
El CMS
Recapitulando, si todo ha ido bien ya tenemos Joomla en una carpeta, que yo he puesto en D:MisPaginasWebunapaginajoomla y que tiene un host virtual asociado. Ahora resulta que accedemos a la siguiente dirección:
Y ahora sí, vamos a configurar Joomla para poder crear contenido. La primera vez nos veremos el sistema de instalación tal que así:
Aquí arriba vemos que se ha simplificado enormemente los pasos de instalación en sólo tres. La ayuda proporcionada por el sistema está muy bien como para yo tener que explicar nada más.
A continuación veo que se ha añadido soporte para PostgreSQL, una gran base de datos. La comunidad de usuarios de Joomla llevaba tiempo queriendo tener soporte para otras bases de datos y ya por fin llegó.
Ponemos los datos de conexión a nuestra base de datos y al darle a siguiente tendremos el tercer y último paso con información sobre la instalación. Podemos aquí instalar datos de ejemplo para poder ver algo mientras que lo probamos.
Para terminar le damos a instalar y ya está, tendremos nuestra nueva y flamante página web, toda gestionada por Joomla, y en un servidor propio instalado en nuestro ordenador.
Terminando
Me sorprende todos los cambios de los últimos meses en Joomla, la interfaz es mucho más limpia. En fin, me parece una gozada el buen trabajo que esta haciendo la gente de Joomla. A ver si en otro post puedo entrar a destripar el Joomla, que tiene muy buena pinta ¿verdad? jejeje
Con ésto ya les dejo.
Un saludo

Java Medio 5: Clases tipo Interfaz

2012-11-02 - Categorías: Java

Vamos a ver cómo se usan las clases de tipo interface. Se usan de igual manera que las clases abstractas, pero tienen unas características peculiares propias de ellas que las diferencian. Las interfaces establecen las variables y funciones que se van a tener, pero no se implementan las funciones dentro de ellas, sino que se implementan en las clases derivadas.

No podemos heredar de varias clases abstractas, pero sí que se puede hacer herencia múltiple usando interfaces.

Un ejemplo para explicarlo todo ésto es el siguiente:

package javaMedio;

public class JavaMedio5Interfaz {

public static void main(String[] args) {
unaClase a;
a = new unaClase();
a.nombre = «María»;
a.escribir();
a.contar();
}

}

abstract class cBase {
public String nombre;

public void escribir() {
System.out.println(nombre);
}
}

interface iBase {
public static int version = 2;

public void contar();
}

class unaClase extends cBase implements iBase {

public void contar() {
System.out.println(«versión: » + version
+ «rnvamos a contar: 0,1,10,11,100,101,110,111,1000…»);
}
}

Su salida es la siguiente:

María
versión: 2
vamos a contar: 0,1,10,11,100,101,110,111,1000…

Vamos con la clase que hereda todo:

class unaClase extends cBase implements iBase {

public void contar() {
System.out.println(«versión: » + version
+ «rnvamos a contar: 0,1,10,11,100,101,110,111,1000…»);
}

Observa que extiende cBase e implementa iBase, extends e implements son palabras clave. Dentro de ésta clase sólo se implementa la función contar(), y la función escribir ya está implementada.

No tiene más complicaciones, espero que haya servido de aclaración si eres nuevo o de recuerdo si ya eres veterano en ésto.

Un saludo


Java Medio 4: Miembros tipo Static

2012-11-01 - Categorías: Java

Algo raro pasa con static. Surge de la necesidad de compartir datos o código entre todas los objetos de una misma clase.

Por ello, los atributos declarados como static dentro de una clase, existen incluso sin tener ningún objeto de la clase, y se puede acceder a ellos con sólo haber cargado la clase en la JVM. Es decir, por ejemplo, si tenemos una clase como la siguiente:




package javaMedio;

public class Persona {
public String nombre = new String();
public static String nombreDeLaClase = new String(«Persona»);
private static String version = new String(«1.0.0»); 

public void escribir() {
System.out.println(«Ésta persona se llama » + nombre);
System.out.println(«…» + nombreDeLaClase);
System.out.println(«…» + version);
}
}

Y en otro fichero tenemos algo tal que así:

package javaMedio;

public class JavaMedio4Static {

public static void main(String[] args) {
System.out.println(Persona.nombreDeLaClase);

// no podemos hacer ésto
// System.out.println(Persona.version);

Persona p1 = new Persona();
Persona p2 = new Persona();

p1.nombre = «Pepito»;
p2.nombre = «Juanito»;

// no debemos, pero podemos hacer ésto
p1.nombreDeLaClase = «Clase de nombre Persona»;
// deberíamos hacer así
Persona.nombreDeLaClase = «Clase de nombre Persona»;
// para evitar confusiones
// porque todas las Personas
// van a tener la misma variable
// nombreDeLaClase

p1.escribir();
p2.escribir();
}

}

Observa que al principio del main accedemos directamante a la variable Persona.nombreDeLaClase sin haber declarado tan siquiera un objeto de tipo Persona. Sólo porque están en el mismo package las dos clases entonces ya podemos acceder a la variable. Y se puede acceder a ésta variable porque ya está cargada en la máquina virtual de Java y es accesible.

Luego más abajo tenemos cómo cambiar una variable static pública. Para terminar observa que no se puede acceder desde fuera a una variable static privada. Si declaramos más objetos de tipo Persona, todos van a tener el mismo valor de las variables static.

La salida del programa es la siguiente:

Persona
Ésta persona se llama Pepito
…Clase de nombre Persona
…1.0.0
Ésta persona se llama Juanito
…Clase de nombre Persona
…1.0.0

Retomando el ejemplo. Viendo la salida del programa, tenemos la variable nombre, que cada objeto tiene un valor distinto (Pepito y Juanito). Y por otro lado el nombreDeLaClase y versión, que tienen el mismo valor tanto para p1 como para p2, es decir, comparten éstas dos mismas variables. Éste es un ejemplo sencillo pero da mucho más juego el uso de static.

Un saludo


Java Medio 3: Clases abstractas

2012-10-28 - Categorías: Java

Continuando con la herencia y polimorfismo de las clases vamos a ver qué son los métodos y clases abstractas. Cuando una clase va a ser la base para otras, pero no van a codificarse las funciones que tiene, sino que se van a hacer en las clases que la extienden, entonces declaramos la clase como abstract.

Vamos a ver con un ejemplo cómo se usa, es muy sencillo:

package javaMedio;

public class JavaMedio3Abstract {
public static void main(String[] args) {
claseBase objeto1, objeto2;

// ésto no lo podemos hacer porque es abstract
// objeto1 = new claseBase();
objeto1 = new claseA();
objeto2 = new claseB();

objeto1.cadena = «cadena del objeto1»;
objeto2.cadena = «cadena del objeto2»;

objeto1.escribir();
objeto2.escribir();
}
}

abstract class claseBase {
public byte x, y;
public String cadena;

public abstract void escribir();
}


class claseA extends claseBase {
public void escribir() {
System.out.println(«Esto es un objeto de la claseA: » + cadena);
}
}

class claseB extends claseBase {
public void escribir() {
System.out.println(«Esto es un objeto de la claseB: » + cadena);
}
}

Como vemos, no podemos reservar memoria para un objeto de tipo claseBase, porque éste tipo de objeto es base de otros, es decir, que al ser abstract sólo se puede usar para construir a partir de ellos otros.

¿Sencillo verdad? No tiene más complicaciones el tipo abstract.

Queda decir que la salida del programa anterior es:

Esto es un objeto de la claseA: cadena del objeto1
Esto es un objeto de la claseB: cadena del objeto2

Un saludo


Java Medio 2: Extendiendo clases a partir de otras clases

2012-10-27 - Categorías: Java


Sábado sabadete, aquí va otro tutorialete… xD para los que esten siguiendo estos minitutoriales para aprender a programar en Java, vamos a continuar con los conocimientos indispensables antes de empezar a hacer programas más o menos grandes. O si ya te has enfrascado con alguno y necesitas saber ésto de los extends espero que aclare las cosas.

Ésta vez voy a explicar cómo reutilizar código, para no tener que hacer una y otra vez lo mismo o para mantener el código bien organizado utilizando la herencia y polimorfismo.

Vamos a ver cómo crear clases reutilizando el código de clases ya creadas, de manera que podremos ampliar su uso añadiendo nuevas funciones o miembros de la clase, o podremos modificar los existentes. Todo ésto se hace con la palabra reservada extends.

A saber, al utilizar extends, la clase que extiende a otra hereda todas las variables y funciones de la otra. A ésto se le llama herencia. Y por otro lado, en la clase que ha heredado, por ejemplo una función, podemos volver a declararla en la clase que extiende, de manera que haga otra cosa. A ésto otro se le llama polimorfismo.

Ésto es todo lo que hay que saber, ahora lo vamos a ver todo de una vez con un ejemplo sencillo que incluya todo ésto que hemos visto. Al grano:

package javaMedio;

public class JavaMedio2Extends {

public static void main(String[] args) {

Circulo ci = new Circulo();
ci.coordenadaX = 0;
ci.coordenadaY = 1;
ci.color = «verde»;
  ci.radio = 2;

Cuadrado cu = new Cuadrado();
cu.coordenadaX = 2;
cu.coordenadaY = 3;
cu.color = «rojo»;
  cu.lado = 2;

ci.escribir();
cu.escribir();

}

}

class Objeto {
byte coordenadaX, coordenadaY;
String color;

public void escribir() {
System.out.println(«(» + coordenadaX + «, » + coordenadaY + «) «
+ color);
}
}

class Circulo extends Objeto {
int radio;
}

class Cuadrado extends Objeto {
int lado;

public void escribir() {
System.out.println(«Esto es un cuadrado de color » + color);
}
}

Éste programilla nos va a dar de resultado:

(0, 1) verde
Esto es un cuadrado de color rojo

Vamos a ver ahora el porqué por ejemplo podemos escribir ci.escribir(); si la clase Circulo no tiene una función escribir(). En el main hemos declarado la variable ci de tipo Circulo:

Circulo ci = new Circulo();


… y en la clase Circulo tenemos:

class Circulo extends Objeto {
int radio;
}

… notad que sólo hay una variable llamada radio, y en el main estamos utilizando la siguiente instrucción:

ci.escribir();

… y no nos da error. Esto es porque Circulo extiende la clase Objeto y la clase Objeto SÍ que tiene la función escribir():

class Objeto {
byte coordenadaX, coordenadaY;
String color;

public void escribir() {
System.out.println(«(» + coordenadaX + «, » + coordenadaY + «) «
+ color);
}
}

Podemos ver que la clase Circulo ha heredado la función escribir(), de igual manera del resto de variables coordenadaX, coordenadaY y color. Estan declaradas en la clase Objeto pero se usan con la variable ci que es de tipo Circulo:

  ci.coordenadaX = 0;
  ci.coordenadaY = 1;
ci.color = «verde»;

ci.escribir();

Círculo ha heredado todo de la clase Objeto y le ha añadido la variable radio. Sin embargo Cuadrado he heredado también pero en vez de tener radio, lo que tienes es lado.

Ahora vamos con el polimorfismo, que en ejemplo lo tenemos con el Cuadrado. Ya tenemos una función escribir() en la clase Objeto, al declarar Cuadrado que hereda de Objeto tendrá la función escribir() ya de por sí, pero al haberla declarado dentro de Cuadrado y haber hecho que haga algo diferente entonces está ocurriendo el llamado polimorfismo. Poli-morfismo, que significa varias formas, viene a decir que el Cuadrado y Circulo, aunque los dos sean Objetos tienen distinta forma porque la función escribir funciona  de diferente manera. Por ésto cuando en el main pusimos:

  ci.escribir();
cu.escribir();


Nos escribe cosas diferentes, porque el Circulo utiliza la función escribir() de Objeto, mientras que Cuadrado utiliza la suya propia que se ha reprogramado:

(0, 1) verde <- resultado de ci.escribir();
Esto es un cuadrado de color rojo <- resultado de cu.escribir();

Ya a partir de aquí hay que seguir con las interfaces, las clases abstractas y otras cosas más, pero no es objetivo de éste post. Tal vez más adelante en otro.

Espero que sirva para aprender si eres nuevo, o te haya aclarado algo si estas refrescando la memoria.

Un servidor se va a ver una peli…
Saludos


Java Medio 1: Clases y paquetes, organización en ficheros

2012-10-25 - Categorías: Java

Vamos a ver cómo organizar los programas Java, en clases u objetos como prefiramos llamarlos. Cómo dividir los códigos fuentes en distintos ficheros o cómo plantearse la creación de un programa bien grande estructurándolo para poder hacerlo poco a poco, repartiendo el trabajo o haciéndolo en partes más simples.

Todo son clases en Java, y estas clases se organizan packetes, llamados packages en inglés. Podemos crear clases a partir de otras clases utilizando el extends. Y cada clase la podemos separar individualmente en cada fichero. Por otro lado los paquetes de clases los podemos importar para usarlos en una clase mediante la instrucción import. Resumiendo ésto es todo, a continuación lo veremos explicado.


Cada fichero se debe nombrar con el nombre de la clase principal. Un ejemplo que nos va a servir para comprender varios conceptos es el siguiente:


package javaMedio;

import java.util.Date;

public class JavaMedio1ClasesPaquetes {

public static void main(String[] args) {
Persona p = new Persona();
p.nombre = «Pepito»;
p.escribir();
}

}

class Persona {
String nombre = new String();
Date fechaCreacion = new Date();

public void escribir() {
String aux = new String();
aux = «Objeto de tipo Persona con nombre: » + nombre + «n» 
+ «Creado en fecha: » + fechaCreacion;
System.out.println(aux);
}
}

Éste programa de aquí arriba debemos guardarlo en un fichero llamado JavaMedio1ClasesPaquetes.java para que funcione y no nos de error. Para empezar escribimos el paquete al que pertenece una clase mediante una línea como la que sigue:

package JavaMedio;

Podemos tener muchas clases dentro del paquete JavaMedio, y si queremos usar todas las clases del paquete en una nueva clase deberemos importar el paquete mediante la instrucción import. En el ejemplo, a continuación, vemos que se ha importado la clase fecha (Date en inglés), que está dentro del paquete de utilidades que proporciona Java de la siguiente manera:

import java.util.Date;

Si queremos importar todas las utilidades de Java, lo haríamos de la forma siguiente:

import java.util.*;

A continuación se declara la clase principal con la función main principal, porque es una aplicación de consola, es decir, se ejecuta en línea de comandos:


public class JavaMedio1ClasesPaquetes {

public static void main(String[] args) {
Persona p = new Persona();
p.nombre = «Pepito»;
p.escribir();
}

}

Podemos leer la clase JavaMedio1ClasesPaquetes es una clase pública, es así porque tiene el main. Y dentro del main tenemos que se declara la variable p de tipo Persona, se reserva memoria, se le pone el nombre Pepito y a continuación se llama a la función escribir() de la clase Persona.

Hay varios tipos de clases que son: abstract, final, public y synchronizable. Abstract son clases que se usan para hacer otras con ellas. Final son clases con las que no se pueden hacer otras a partir de ellas. Las public son las normales. Y las synchronizable son clases que no se pueden usar en paralelo desde dos hilos de ejecución distintos. Para más información sobre las clases de tipo synchronizable acudir a la programación multihilos de Java.

En la declaración de la clase Persona podemos ver que no es una clase pública, esto se hace así porque la he puesto dentro del mismo fichero, y no debe haber más que una clase pública en cada fichero. Vamos a analizar el código de la clase:


class Persona {
String nombre = new String();
Date fechaCreacion = new Date();

public void escribir() {
String aux = new String();
aux = «Objeto de tipo Persona con nombre: » + nombre + «n» 
+ «Creado en fecha: » + fechaCreacion;
System.out.println(aux);
}
}

Vemos que la clase Persona tiene dos variables: nombre y fechaCreacion. Y tiene una función pública: escribir(). La función lo que hace es escribir las variables internas de Persona. La variable nombre podemos acceder a ella desde fuera, es decir, es pública, como podemos observar en el main:

p.nombre = «Pepito»;

Ésta instrucción nos lo permite. Siempre que una variable no se le ponga el tipo de control de acceso permitido, se supone pública. Podríamos haber escrito mejor en la clase Persona:


class Persona {
public String nombre = new String();
public Date fechaCreacion = new Date();

Así estaría más claro el nivel de acceso desde fuera de la clase.

El control de acceso dentro de una clase se especifica mediante las palabras public, protected y private. Public indica que la variable o función se puede usar desde fuera. Private es lo contrario que public, protected indica que sólo acceder si la clase que accede es del mismo paquete.

Si queremos usar la clase Persona desde otras clases o ficheros deberíamos separar en un fichero la clase, quedaría un fichero llamado Persona.java que tendría lo siguiente:

package javaMedio;

import java.util.Date;

public class Persona {
public String nombre = new String();
public Date fechaCreacion = new Date();

public void escribir() {
String aux = new String();
aux = «Objeto de tipo Persona con nombre: » + nombre + «n»
+ «Creado en fecha: » + fechaCreacion;
System.out.println(aux);
}

}

Entonces el primer fichero llamado JavaMedio1ClasesPaquetes.java quedaría:
package javaMedio;

public class JavaMedio1ClasesPaquetes {

public static void main(String[] args) {
Persona p = new Persona();
p.nombre = «Pepito»;
p.escribir();
}

}

Podemos ver que tanto la clase JavaMedio1ClasesPaquetes como Persona están en el mismo paquete, entonces para usar Persona en el fichero JavaMedio1ClasesPaquetes.java no hace falta usar el import.

Para terminar, saber que algunos de los paquetes principales que proporciona Java son los siguientes para el que quiera continuar investigando:

java.applet Para la creación de Applets.
java.io Para manejo de la entrada y salida.
java.lang Paquete de clases variadas.
java.net Aquí tenemos clases que usan TCP/IP.
java.util Utilidades variadas.
java.awt Para hacer interfaces de usuario con botones, ventanas, etcétera.
java.swing Más compatible con los distintos Sistemas Operativos que la AWT, yo usaría ésta en vez de la AWT porque te aseguras de que tu programa va a funcionar en más plataformas.

Por ahora queda terminado este minitutorial sobre clases y paquetes.
Saludos;}

© 2024 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.