Java - Applet pista de baile

 
Vista:
sin imagen de perfil
Val: 19
Ha disminuido su posición en 3 puestos en Java (en relación al último mes)
Gráfica de Java

Applet pista de baile

Publicado por Gabriel (11 intervenciones) el 21/06/2019 19:06:17
DISCULPEN ME PUEDEN AYUDAR HACER UNA APPLET QUE SIMULE LA CUADRICULA DE UN PISO DE BAILE O ANTRO EN LA CUAL CADA CUADRO SE ILUMINA ALEATORIAMENTE Y DE FORMA CONTINUA, CON OPCIONES PARA INICIAR, DETENER Y CONTINUAR.
QUIEN ME PUEDE AYUDAR POR FAVOR SERIA DE MUCHISIMA AYUDA
NO SE COMO ELABORAR EL CODIGO
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
-1
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Applet pista de baile

Publicado por Kabuto (1381 intervenciones) el 22/06/2019 00:10:31
Hola.

Ni idea de applets, y como ha dado entender el compañero con ese meme.. los applets de Java hace tiempo que los navegadores han dejado de soportar los plugins necesarios para usar applets y la propia Oracle abandonó el desarrollo de este plugin hace ya tiempo también.

Un applet es una aplicación Java que se "incrusta" y utiliza desde un documento HTML. No se si realmente necesitas un applet, o has usado esa palabra sin saber muy bien a lo que te refieres.


En cualquier caso, he hecho una aplicación (no applet) Java que hace lo que creo entender que pides.
Dibuja una cuadricula de 100 cuadros (100 JPanels) que cambian al azar entre dos colores: negro(apagado) y amarillo(encendido)
Esta es la clase que modela estos cuadros:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Cuadro extends JPanel {
 
    public Cuadro() {
        setPreferredSize(new Dimension(50,  50));
        setBackground(cambiaColor());
    }
 
    private Color cambiaColor() {
        int azar = (int) (Math.random()*100);
        if (azar%2 == 0)
            return Color.BLACK;
        else
            return Color.YELLOW;
    }
 
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        setBackground(cambiaColor());
    }
}

Estos Cuadros se guardan en un arreglo de 100 elementos para poder acceder a ellos y se pintan en un JFrame maquetados en un GridLayout de 10x10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Pista extends JFrame{
 
	private Cuadro[] cuadricula; //Arreglo de cuadros
	private JButton iniciar;
	private JButton detener;
	private Activar activarPista; //Objeto Thread
 
 
	public Pista() {
		super("Pista Baile");
		cuadricula = new Cuadro[100];
		iniciar = new JButton("Iniciar");
		iniciar.addActionListener(new AccionIniciar());
		detener = new JButton("Detener");
		detener.setEnabled(false);
		detener.addActionListener(new AccionDetener());
 
		JPanel pnPrincipal = new JPanel();
		pnPrincipal.setLayout(new BorderLayout());
 
		JPanel pnCuadricula = new JPanel();
		pnCuadricula.setLayout(new GridLayout(10, 10, 2, 2));
		for (int i = 0; i < cuadricula.length; i++) {
			cuadricula[i] = new Cuadro();
			pnCuadricula.add(cuadricula[i]);
		}
		JPanel pnBotones = new JPanel();
		pnBotones.add(iniciar);
		pnBotones.add(detener);
 
		pnPrincipal.add(pnCuadricula, BorderLayout.CENTER);
		pnPrincipal.add(pnBotones, BorderLayout.SOUTH);
		setContentPane(pnPrincipal);
 
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
	}

En los atributos, además del arreglo de 100 Cuadros, vemos dos botones y un objeto de la clase Activar

Los dos botones, uno para iniciar/continuar y otro para detener, lo que hacen es poner en marcha y detener al objeto de la clase Activar

Esta clase hereda de la clase Thread para poder lanzarse como un hilo de ejecucion paralelo al programa principal y lo que hace es "repintar" los Cuadros accediendo al arreglo en posiciones al azar.
Cada vez que se "repinta" un Cuadro cambia (o no) de color

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Activar extends Thread {
    @Override
    public void run() {
        while(!Thread.currentThread().isInterrupted()) {
            int i = (int) (Math.random()*cuadricula.length); //Generamos indice al azar para acceder al arreglo
            cuadricula[i].repaint();
            try {
                sleep(10); //Pequeña pausa entre cada "repintado"
            } catch (InterruptedException e) {
                interrupt();
            }
        }
    }
}

Y ya está. Es muy simple y de hecho, no se si esta es la mejor manera de manejar Threads, no estoy muy puesto en este tema. Pero bueno, creo que cumple con lo que buscabas. Si no era así, indícalo y vemos como modificarlo

Aqui pego todo el código completo para quien quiera probarlo. Pero repito, no es un applet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class Pista extends JFrame{
 
	private Cuadro[] cuadricula;
	private JButton iniciar;
	private JButton detener;
	private Activar activarPista;
 
 
	public Pista() {
		super("Pista Baile");
		cuadricula = new Cuadro[100];
		iniciar = new JButton("Iniciar");
		iniciar.addActionListener(new AccionIniciar());
		detener = new JButton("Detener");
		detener.setEnabled(false);
		detener.addActionListener(new AccionDetener());
 
		JPanel pnPrincipal = new JPanel();
		pnPrincipal.setLayout(new BorderLayout());
 
		JPanel pnCuadricula = new JPanel();
		pnCuadricula.setLayout(new GridLayout(10, 10, 2, 2));
		for (int i = 0; i < cuadricula.length; i++) {
			cuadricula[i] = new Cuadro();
			pnCuadricula.add(cuadricula[i]);
		}
		JPanel pnBotones = new JPanel();
		pnBotones.add(iniciar);
		pnBotones.add(detener);
 
		pnPrincipal.add(pnCuadricula, BorderLayout.CENTER);
		pnPrincipal.add(pnBotones, BorderLayout.SOUTH);
		setContentPane(pnPrincipal);
 
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
	}
 
	public static void main(String[] args) {
		java.awt.EventQueue.invokeLater(
				new Runnable() {
					public void run() {	new Pista();}
					});
	}
 
	/*
	 * Clase para lanzar hilo ejecucion que pone en marcha
	 * la "pista de baile"
	 */
	class Activar extends Thread {
		@Override
		public void run() {
			while(!Thread.currentThread().isInterrupted()) {
				int i = (int) (Math.random()*cuadricula.length); //Generamos indice al azar para acceder al arreglo
				cuadricula[i].repaint();
				try {
					sleep(10); //Pequeña pausa entre cada "repintado"
				} catch (InterruptedException e) {
					interrupt();
				}
	        }
		}
	}
 
	/*
	 * Panel cuadrado que se "apaga" o "enciende" al azar
	 */
	class Cuadro extends JPanel {
 
		public Cuadro() {
			setPreferredSize(new Dimension(50,  50));
			setBackground(cambiaColor());
		}
 
		private Color cambiaColor() {
			int azar = (int) (Math.random()*100);
			if (azar%2 == 0)
				return Color.BLACK;
			else
				return Color.YELLOW;
		}
 
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			setBackground(cambiaColor());
		}
	}
 
	class AccionIniciar implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			activarPista = new Activar(); //Creamos nuevo Hilo
			activarPista.start(); //Lo ponemos en marcha
			detener.setEnabled(true);
			iniciar.setEnabled(false);
		}
	}
 
	class AccionDetener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			activarPista.interrupt(); //Finalizamos hilo
			detener.setEnabled(false);
			iniciar.setEnabled(true);
		}
	}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Applet pista de baile

Publicado por Kabuto (1381 intervenciones) el 22/06/2019 11:43:53
Me ha gustado esto de cambiar colores de baldosas.
He hecho una nueva versión, esta vez en de alterar entre dos colores, voy aumentando progresivamente de 5 en 5 los valores RGB de los colores.
Bueno, solo cambio G y B y así voy de negro a azulado. Cuando llega al máximo de 255 por cada uno, cambio un boolean para que ahora en lugar de aumentar, disminuyan hasta 0 para "apagarse.
Al llegar a 0, vuelve a cambiar el boolean para volver a "encenderse".

Todo esto lo hace el método llamado alterarRGB() que le he añadido a la clase Cuadro.
Cuando se inicia el Thread, invoca a este metodo para alterar los colores y acto seguido repinta el baldosín.
La verdad es que se consigue un efecto muy chulo, casi relajante ja ja.

Por cierto, una cosa rara que me ha pasado.
Inicialmente el método alterarRGB() lo había puesto dentro del mentro paint() para ser invocado directamente al pedir repintar el baldosín.
Pero resulta que si lo pongo ahí, al iniciar programa todos los baldosines empiezan a cambiar de color automáticamente ¡¡sin tener que pulsar el botón que iniciar el Thread!!
No entiendo el por qué de ese comportamiento.

Veréis que he comentado esa línea y la he dejado ahí, para que podáis probarlo. Y si alguien me sabe explicar porque se comportan así lo agradeceré.

Aqui código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
public class Pista extends JFrame{
 
	private Cuadro[] cuadricula;
	private JButton iniciar;
	private JButton detener;
	private Activar activarPista;
 
 
	public Pista() {
		super("Pista Baile");
		cuadricula = new Cuadro[100];
		iniciar = new JButton("Iniciar");
		iniciar.addActionListener(new AccionIniciar());
		detener = new JButton("Detener");
		detener.setEnabled(false);
		detener.addActionListener(new AccionDetener());
 
		JPanel pnPrincipal = new JPanel();
		pnPrincipal.setLayout(new BorderLayout());
 
		JPanel pnCuadricula = new JPanel();
		pnCuadricula.setLayout(new GridLayout(10, 10, 2, 2));
		for (int i = 0; i < cuadricula.length; i++) {
			cuadricula[i] = new Cuadro();
			pnCuadricula.add(cuadricula[i]);
		}
		JPanel pnBotones = new JPanel();
		pnBotones.add(iniciar);
		pnBotones.add(detener);
 
		pnPrincipal.add(pnCuadricula, BorderLayout.CENTER);
		pnPrincipal.add(pnBotones, BorderLayout.SOUTH);
		setContentPane(pnPrincipal);
 
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
	}
 
	public static void main(String[] args) {
		java.awt.EventQueue.invokeLater(
				new Runnable() {
					public void run() {	new Pista();}
					});
	}
 
	/*
	 * Clase para lanzar hilo ejecucion que pone en marcha
	 * la "pista de baile"
	 */
	class Activar extends Thread {
		@Override
		public void run() {
			while(!Thread.currentThread().isInterrupted()) {
				int i = (int) (Math.random()*cuadricula.length); //Generamos indice al azar para acceder al arreglo
				cuadricula[i].alterarRGB();
				cuadricula[i].repaint();
				try {
					sleep(2); //Pequeña pausa entre cada "repintado"
				} catch (InterruptedException e) {
					interrupt();
				}
	        }
		}
	}
 
	/*
	 * Panel cuadrado que se "apaga" o "enciende" al azar
	 */
	class Cuadro extends JPanel {
		private int R;
		private int G;
		private int B;
		private boolean encendiendo;
 
		public Cuadro() {
			R = 0;
			G = 0;
			B = 0;
			encendiendo = true;
			setPreferredSize(new Dimension(50,  50));
			setBackground(new Color(R,G,B));
		}
 
		public void alterarRGB() {
			if (encendiendo) {
				if (G < 255) {
					G+=5;
					B+=5;
				}
				else {
					encendiendo = false;
					G-=5;
					B-=5;
				}
			}
			else {
				if (G > 0) {
					G-=5;
					B-=5;
				}
				else {
					encendiendo = true;
					G+=5;
					B+=5;
				}
			}
		}
 
		/*private Color cambiaColor() {
			int azar = (int) (Math.random()*100);
			if (azar%2 == 0)
				return Color.BLACK;
			else
				return Color.YELLOW;
		}*/
 
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			//alterarRGB(); //Si lo ponemos aqui, los colores cambian sin iniciar el Thread
			setBackground(new Color(R,G,B));
		}
	}
 
	class AccionIniciar implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			activarPista = new Activar(); //Creamos nuevo Hilo
			activarPista.start(); //Lo ponemos en marcha
			detener.setEnabled(true);
			iniciar.setEnabled(false);
		}
	}
 
	class AccionDetener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			activarPista.interrupt(); //Finalizamos hilo
			detener.setEnabled(false);
			iniciar.setEnabled(true);
		}
	}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Applet pista de baile

Publicado por Tom (1831 intervenciones) el 22/06/2019 12:18:36
Lo que te pasa es que setBackground() provoca un repintado del componente. Entras en un bucle sin fin.
No reimplementes paint() sino paintComponent()
No hagas modificaciones a los componentes desde un hilo distinto al de swing, usa invokeLater.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Activar extends Thread {
		@Override
		public void run() {
			while(!Thread.currentThread().isInterrupted()) {
				int i = (int)(Math.random() * cuadricula.length);
				cuadricula[i].alterarRGB();
				SwingUtilities.invokeLater(() -> {cuadricula[i].repaint();});
				//cuadricula[i].repaint();
 
				try {
					sleep(2); //Pequeña pausa entre cada "repintado"
				} catch(InterruptedException e) {
					interrupt();
				}
			}
		}
	}

Tambien puedes simplificar el asunto usando un timer (java.swing.Timer) en lugar de tu thread.
https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Applet pista de baile

Publicado por Kabuto (1381 intervenciones) el 22/06/2019 12:27:57
1
Lo que te pasa es que setBackground() provoca un repintado del componente. Entras en un bucle sin fin.

OK. Vale, tiene sentido.

Gracias por la explicación y por el consejo de usar invokeLater()
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Applet pista de baile

Publicado por Tom (1831 intervenciones) el 22/06/2019 16:19:02
Solo para dar ideas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class Pista extends JFrame implements ActionListener {
	private Timer timer;
	private JPanel grid;
	private JButton start, stop;
	/* */
	Pista() {
		JPanel buttons = new JPanel();
 
		grid = new JPanel();
		start = new JButton("Iniciar");
		stop = new JButton("Detener");
 
		grid.setLayout(new GridLayout(10, 10, 2, 2));
		for(int i = 0; i < 100; i++) {
			JPanel p = new JPanel();
			p.setBackground(Color.BLACK);
			p.setPreferredSize(new Dimension(40, 40));
			grid.add(p);
		}
 
		start.addActionListener(this);
		stop.addActionListener(this);
		buttons.add(start);
		buttons.add(stop);
 
		timer = new Timer(0, this);
		timer.setDelay(100);
 
		getContentPane().add(grid, BorderLayout.CENTER);
		getContentPane().add(buttons, BorderLayout.SOUTH);
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		Object src = e.getSource();
		if(src == start) {
			timer.restart();
			start.setEnabled(false);
			stop.setEnabled(true);
		} else if(src == stop) {
			timer.stop();
			start.setEnabled(true);
			stop.setEnabled(false);
		} else if(src == timer) {
			int i = (int)(Math.random() * 100.0);
			Component p = grid.getComponent(i);
			int c = p.getBackground().getRGB();
			int off = (int)(Math.random() * 64.0);
 
			p.setBackground(new Color(c + off));
		}
	}
	/* */
	public static void main(String args[]) {
		new Pista().setVisible(true);
	}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar