Java - Cambiar propiedad a varios componentes a la vez

 
Vista:

Cambiar propiedad a varios componentes a la vez

Publicado por Dante (3 intervenciones) el 28/12/2022 20:36:50
Hola, tengo una duda. ¿se puede cambiar el valor de varios componentes a la vez?
Me explico con un ejemplo: Si una aplicacion hecho en java se quiere implementar el modo oscuro se trendria que cambiar componente por componente el color deseado:

En modo oscuro el jLabel es blanco
t1.setForeground(Color.decode("#FFFFFF"));

y en modo claro el jLabel es casi negro
t1.setForeground(Color.decode("#333333"));

La cosa es que son varios jLabels en el sistema, y se tendria que hacer lo mismo con todos los jLabels e incluso botones y paneles y el codigo seria extenso:
t1.setForeground(Color.decode("#FFFFFF"));
t2.setForeground(Color.decode("#FFFFFF"));
t3.setForeground(Color.decode("#FFFFFF"));
..
..
..

¿Habra un metodo o forma de cambiarlos a todos o creando una clase como: jLabel.setForeground(Color.decode("#FFFFFF")); haciendo referencia a todos los jLabels o componentes que se desee cambiar.

Espero su ayuda y su comprension.
De antemano gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
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

Cambiar propiedad a varios componentes a la vez

Publicado por Kabuto (1383 intervenciones) el 29/12/2022 11:43:51
Hola.
Nunca he hecho tal cosa, pero se me ocurre una solución para evitar tener que ir componente a componente cambiando sus colores.

Podrías crear tus propias clases para cada tipo de componente, haciendo que hereden de ellos.
Es decir, una clase Boton que herede de JButton, otra que herede de JLabel, etc...

De esta manera, puedes sobreescribir sus métodos paint() y hacer que cuando los objetos se pinten o repinten en la interfaz, tomen los colores adecuados de otra clase creada por ti donde podrás establecer los colores que te interesen.

Dicha clase, tendría atributos de clase Color para los distintos componentes.
El valor de esos atributos cambiarán según pasamos del "modo claro" al "modo oscuro" y viceversa.
Con un boolean podemos controlar en que modo estamos en cada momento.

Así, cuando quieras cambiar de modo en la interfaz, primero le decimos a esta clase que cambie los valores de los atributos de colores y luego "repintamos" la interfaz, la cuál adoptará los nuevos colores.

La clase con los distintos colores, podría ser algo así:
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
public class ModosColor {
 
	public boolean esModoClaro; //Indica si actualmente estamos en modo claro o no
	//JLabel
	public Color labelBack;
	public Color labelFore;
	//Jbutton
	public Color btBack;
	public Color btFore;
	//JPanel
	public Color jpBack;
 
 
	public ModosColor() {
		esModoClaro = true;
		setModoClaro();
	}
 
	public void setModoOscuro() {
		labelFore = Color.decode("#FFFFFF");
		labelBack = Color.decode("#333333");
		btFore = Color.decode("#FFFFFF");
		btBack = Color.decode("#333333");
		jpBack = Color.decode("#706B6A");
	}
 
	public void setModoClaro() {
		labelBack = Color.decode("#FFFFFF");
		labelFore = Color.decode("#333333");
		btBack = Color.decode("#FFFFFF");
		btFore = Color.decode("#333333");
		jpBack = Color.decode("#E7DCD9");
	}
 
}

Ahí he puesto colores para tres componentes: etiquetas, botones y paneles.
Para el panel solo pongo color de fondo y además con un tono algo distinto para que los componentes se distingan mejor del panel.
Tu ya luego puedes añadir o quitar más atributos, elegir los colores que quieras, etc..

Ahora vamos hacer un ejemplo con una interfaz simplona. Un JFrame con un panel, un boton y una etiqueta.
Además tendremos como atributo un objeto de la clase ModosColor que será quien decida los colores de los componentes.

Fíjate que declaro mis propias clases JButton, JLabel y JPanel para poder sobreescribir sus métodos paint(). Dentro de sus paint(), les digo que tomen los colores de los atributos correspondientes del objeto ModosColor

La acción del botón que uso para cambiar de un modo color a otro, lo que hace es consultar el boolean del objeto ModosColor para saber en que modo estamos ahora mismo y así pasar al modo siguiente, para luego repintar la interfaz.

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
public class Main extends JFrame {
 
	private ModosColor modo;
	private MiBoton btCambiar;
	private MiLabel lb1;
	private MiPanel pn1;
 
	public Main() {
		modo = new ModosColor();
		btCambiar = new MiBoton();
		btCambiar.setText("Cambiar Modo");
		btCambiar.addActionListener(new AccionRepintar());
		lb1 = new MiLabel();
		lb1.setText("Texto Prueba");
		pn1 = new MiPanel();
 
		pn1.setLayout(new BoxLayout(pn1, BoxLayout.Y_AXIS));
		pn1.setBorder(new EmptyBorder(25, 25, 25, 25));
		pn1.add(lb1);
		pn1.add(btCambiar);
 
		setContentPane(pn1);
		setTitle("Prueba Modos");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}
 
	/*
	 * Repinta todo el JFrame entero.
	 * Esto actualiza todos los componentes
	 * que cambiaran de color según el modo actual
	 */
	private void repintar() {
		this.repaint();
	}
 
	private class AccionRepintar implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (modo.esModoClaro) {
				//Pasamos a oscuro
				modo.esModoClaro = false;
				modo.setModoOscuro();
			}
			else {
				//Pasamos a claro
				modo.esModoClaro = true;
				modo.setModoClaro();
			}
 
			repintar(); //Repintamos interfaz
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new Main();
			}
		});
	}
 
	private class MiBoton extends JButton {
 
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			setForeground(modo.btFore);
			setBackground(modo.btBack);
		}
	}
 
	private class MiLabel extends JLabel {
 
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			setForeground(modo.labelFore);
			setBackground(modo.labelBack);
		}
	}
 
	private class MiPanel extends JPanel {
 
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			setBackground(modo.jpBack);
		}
	}
 
}


Si lo pruebas, verás que podemos cambiar los colores de todos los componentes, sin tener que acceder a ellos uno por uno.
Solo hay que pedir al objeto ModosColor que cambie de un modo a otro y repintar la interfaz.
Ese mismo código sirve sin importar cuántos elementos hay en la interfaz.


Esto lo he escrito para un ejemplo muy simple.
Puede que si usas una interfaz muy compleja, con distintos marcos en pantalla, pestañas, ventanas emergentes... tengas que añadir algo de código extra o desarrollar esta misma idea pero de otra manera.

Supongo que sería suficiente con pasar a las clases de todos esos elementos una referencia al objeto ModosColor que hemos declarado en la clase main principal.
Así todas tendrían acceso a este objeto y cambiaran de colores al unísono.

Un saludo.
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

Cambiar propiedad a varios componentes a la vez

Publicado por Dante (3 intervenciones) el 29/12/2022 20:08:11
Gracias amigo. Me sirvio de mucho.
Saludos.
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

Cambiar propiedad a varios componentes a la vez

Publicado por Dante (3 intervenciones) el 29/12/2022 20:12:14
Gracias por el dato estimado.
Esa era mi segunda opcion.
Saludos.
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