Buscar
Social
Ofertas laborales ES

Foro sobre Java SE > Dudas con codigo

Hola,
estoy intentando aprender java, estoy siguiendo el curso de javaya, hay un ejercicio con el cual tengo dudas, les muestro el codigo completo y luego les digo cuales son las dudas especificas

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Grafico1 extends JFrame {
private JPanel contentPane;
private int columna;

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

public Grafico1() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

JButton bi = new JButton("Izquierda");
bi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
columna=columna-10;
repaint();
}
});
bi.setBounds(105, 482, 89, 23);
contentPane.add(bi);

JButton bd = new JButton("Derecha");
bd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
columna=columna+10;
repaint();
}
});
bd.setBounds(556, 482, 89, 23);
contentPane.add(bd);
setBounds(0,0,800,600);
columna=400;
}

public void paint (Graphics g)
{
super.paint(g);
g.setColor (Color.red);
g.fillOval (columna, 300, 100, 100);
}
}

las dudas o mejor dicho lo que no se es: en el main:

EventQueue.invokeLater(new Runnable() {
public void run() {

en Grafico1:


bi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {

por ejemplo esto entiendo:

JButton bd = new JButton("Derecha");

pero esto no:

bi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {

Gracias de antemano por la ayuda,
saludos.

enero 31, 2015 | Registered Commenterlucas5000

EventQueue.invokeLater(new Runnable() {
public void run() {

Envia el codigo que se ejecuta dentro del metodo run() a la cola de eventos de swing. O sea, el codigo definido dentro de run() sera ejecutado por el hilo de despacho de sucesos graficos.

bi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {

"bi" hace referencia a un boton, por lo tanto, lo que estas haciendo es asignarle un "escuchador" al boton para poder captar los eventos que sucedan en el.

Cabe aclarar que en ambos casos se estan definiendo clases ANONIMAS y si no las viste aun en el curso, debieras googlear un poco para aprender sobre ellas.

enero 31, 2015 | Registered Commenteralaguslaz

Hola alaguslaz,
gracias por la respuesta, me dio muchas luces.

tengo otras dudas, la primera porque se ejecuta el metodo paint al comienzo de correr el programa si no esta definido en el constructor es decir en Grafico1().

la segunda: en el main borre algunas cosas de manera que el codigo quedo asi

public static void main(String[] args) {
//EventQueue.invokeLater(new Runnable(){
// public void run(){
Grafico5 frame=new Grafico5();
frame.setVisible(true);
//}
//});
}

y el codigo funciona igual, si antes lo ejecutaba el swing, ahora quien lo ejecuta?, por que funciona igual?, por que llamaron a :

EventQueue.invokeLater(new Runnable() {
public void run() {

si el codigo funciona igual? hasta donde veo yo
recien estoy aprendiendo java, y es un poco dificil,
Gracias de antemano por la ayuda,
saludos.

febrero 3, 2015 | Registered Commenterlucas5000

Hola lucas5000.
Que bueno que te hayan servido los comentarios!

Vamos por partes:

tengo otras dudas, la primera porque se ejecuta el metodo paint al comienzo de correr el programa si no esta definido en el constructor es decir en Grafico1().

No se exactamente a que te referis con "el comienzo del programa". El programa arranca su ejecucion en la primera linea del metodo "main()".

El metodo paint() es llamado automáticamente por la JVM cuando hace falta re-pintar la interfaz gráfica. A la declaracion del metodo le falta la anotacion "@Override" que significa que es un metodo que pertenece a la clase padre (JFrame) y esta siendo sobrescrito por la clase Grafico1 que hereda de esta.

La primer linea dentro del metodo paint() es "super.paint()" que es el llamado al metodo paint de JFrame y el que "sabe" lo que debe hacer para re-pintar la interfaz grafica. Una vez que el metodo termina su ejecucion en la clase JFrame retornara y se ejecutara el codigo que sigue a dicha linea.

Importante: La documentacion de Oracle recomienda utilizar el metodo paintComponent() en lugar de paint().

Conclusion: Cada vez que java necesite re-pintar la interfaz grafica llamara a este metodo. En el codigo de tu primer comentario hay dos llamados al metodo repaint(), en este caso el programa esta "forzando" a java a que llame al metodo paint() por que hubo cambios y necesitan ser refrescados en la interfaz grafica.

la segunda: en el main borre algunas cosas de manera que el codigo quedo asi

public static void main(String[] args) {
//EventQueue.invokeLater(new Runnable(){
// public void run(){
Grafico5 frame=new Grafico5();
frame.setVisible(true);
//}
//});
}

y el codigo funciona igual, si antes lo ejecutaba el swing, ahora quien lo ejecuta?, por que funciona igual?, por que llamaron a :

EventQueue.invokeLater(new Runnable() {
public void run() {

El haber deshabilitado esas lineas no va a provocar que el programa no funcione, de hecho has comprobado que funciona igual.

La diferencia es que ahora todo lo relacionado con el manejo de la interfaz grafica se esta ejecutando desde el hilo "main" y no desde el hilo de swing, que es un hilo DEDICADO SOLA Y ESPECIALMENTE a eso y es el que deberia tratar con la parte grafica.

El problema de usar el mismo hilo (en este caso main) para trabajar con el flujo del programa y el manejo de los graficos es que no se garantiza "fluidez" en los graficos ya que, por ejemplo, si haces una llamada a un metodo "bloqueante" o que desarrolle una tarea de larga duracion, la interfaz grafica se quedara "congelada" hasta que ese metodo termine su ejecucion y el programa siga con su ejecucion.

Utilizando el hilo de swing dedicado a los graficos lo antes mencionado NO sucede, ya que una parte del programa (la que se ejecuta en el hilo "main") podria estar realizando una tarea de larga duracion o "bloqueante" y el hilo de swing actualizando la parte grafica sin que uno interfiera en el otro.

Como te mencione en el post anterior, la llamada a invokeLater() hace que el codigo que esta dentro de run() se ejecute sobre el hilo de swing. Todo el resto del codigo sera ejecutado por el hilo "main".


Te recomiendo leer esto (en ingles) para entender mejor el tema del hilo de despacho de eventos graficos.
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Y esto otro (tambien en ingles) para el tema de paint()
http://docs.oracle.com/javase/tutorial/2d/index.html

Saludos.

febrero 3, 2015 | Registered Commenteralaguslaz

Hola alaguslaz, que tal,
Gracias por la ayuda, me costo un poco entender,
creo que todavia tengo mucho por recorrer si quiero aprender java,
saludos.

febrero 7, 2015 | Registered Commenterlucas5000

Hola lucas5000.
De nada, para eso estamos.
No se en que nivel de aprendizaje estas, pero los temas sobre los que consultas son tirando a avanzados, y si no formas primero una buena base no son faciles...
De todas formas en el mundo de la informatica nunca se termina de aprender! Hay que mantenerse activo y seguir adquiriendo conocimientos dia a dia. Lo importante es no dejarse abrumar, por mas complicado que parezca un tema a la larga se termina entendiendo.

Suerte!

febrero 8, 2015 | Registered Commenteralaguslaz