Java - Posicionar Objetos dentro de un JPanel

 
Vista:
Imágen de perfil de Ivan
Val: 16
Ha aumentado 1 puesto en Java (en relación al último mes)
Gráfica de Java

Posicionar Objetos dentro de un JPanel

Publicado por Ivan (7 intervenciones) el 18/04/2019 02:14:11
Hola, estoy realizando un programa con interfaz grafica, la cosa aquí es que, cuando inserto mi JPanel con un botón dentro de el y lo agrego al JFrame, el botón dentro del JPanel aparece alineado hacia la izquierda, ya he intentado ocupar los Layout, también con la condición setBounds, pero cuando los aplico el JPanel desaparece, les dejo el código y espero me puedan ayudar diciéndome que estoy haciendo mal o por que aparecen así los botones

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
public class Elecciones2 extends JFrame implements ActionListener{
    private JFrame panel;
    private JLabel texto;
    private JButton b1,b2,b3,b4,b5,b6;
    private JPanel pan,pan2,pan3,pan4,pan5,pan6;
    private JProgressBar bar1,bar2,bar3;
    private JTextArea a1,a2,a3;
    private JCheckBoxMenuItem JCheckMenu1,JCheckMenu2,JCheckMenu3;
    private int ancho,alto;
    private double e1,e2,e3,r;
 
    public Elecciones2(){
        panel=new JFrame("Aplicacion Elecciones");
        panel.setSize(600,500);
        panel.setLocationRelativeTo(null);
        panel.setVisible(true);
        panel.setResizable(false);
        panel.setLayout(null);
        this.iniciarcomponentes();
        panel.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public void iniciarcomponentes(){
        pan=new JPanel();
        pan2=new JPanel();
        pan3=new JPanel();
        pan4=new JPanel();
        pan5=new JPanel();
        pan6=new JPanel();
        bar1=new JProgressBar();
        bar2=new JProgressBar();
        bar3=new JProgressBar();
        a1=new JTextArea();
        b1=new JButton("informacion");
        b2=new JButton("Boton 1");
        b2.setIcon(re1);
        b2.setContentAreaFilled(false);
        b3=new JButton("Boton 2");
        b3.setContentAreaFilled(false);
        b4=new JButton("Boton 3");
        b4.setContentAreaFilled(false);
        b5=new JButton("presupuestos");
        b6=new JButton("totales");
        texto= new JLabel("Indique la fuente de informacion");
        JCheckMenu1=new JCheckBoxMenuItem("Publicidad por Radio");
        JCheckMenu2=new JCheckBoxMenuItem("Publicidad por prensa");
        JCheckMenu3=new JCheckBoxMenuItem("Publicidad por Television");
        pan.setBorder(javax.swing.BorderFactory.createTitledBorder("Indique la fuente de informacion"));
        pan.add(JCheckMenu1);
        pan.add(JCheckMenu2);
        pan.add(JCheckMenu3);
        pan2.add(b2);
        pan3.add(b3);
        pan4.add(b4);
        pan5.add(b5);
        pan6.add(b6);
        pan2.setBorder(BorderFactory.createLoweredBevelBorder());
        pan3.setBorder(BorderFactory.createLoweredBevelBorder());
        pan4.setBorder(BorderFactory.createLoweredBevelBorder());
        pan5.setBorder(javax.swing.BorderFactory.createTitledBorder("Presupuestos"));
        pan6.setBorder(javax.swing.BorderFactory.createTitledBorder("Totales"));
       pan.setLocation(35,3);
       pan.setSize(550,60);
       pan2.setLocation(20,75);
       pan2.setSize(250,250);
       pan3.setLocation(210,75);
       pan3.setSize(250,100);
       pan4.setLocation(405,75);
       pan4.setSize(250,100);
       pan5.setLocation(20,200);
       pan5.setSize(550,60);
       pan6.setLocation(20,300);
       pan6.setSize(550,60);
       panel.getContentPane().add(pan);
       panel.getContentPane().add(pan2);
       panel.getContentPane().add(pan3);
       panel.getContentPane().add(pan4);
       panel.getContentPane().add(pan5);
       panel.getContentPane().add(pan6);
       panel.setVisible(true);
    }
    @Override
    public void actionPerformed (ActionEvent evento){
        eventosObjetos(evento);
    }
    public void eventosObjetos(ActionEvent e){
 
    }
    public static void main(String[] args) {
        Elecciones2 interfaz=new Elecciones2();
    }
 
}
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

Posicionar Objetos dentro de un JPanel

Publicado por Tom (1831 intervenciones) el 18/04/2019 10:46:47
Es bastabnte difícil saber qué quieres hacer o cual es exactamente el problema.
Por si acaso, prueba
b2.setAlignmentX(Component.CENTER_ALIGNMENT);
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

Posicionar Objetos dentro de un JPanel

Publicado por Kabuto (1380 intervenciones) el 18/04/2019 11:52:33
Nullear el layout principal luego suele complicar mucho las cosas porque afecta de un modo u otro al resto de componentes.
Yo nunca lo hago. Lo que hago es jugar y combinar los distintos layouts disponibles (FlowLayout, BoxLayout, GridLayout,...) hasta conseguir el diseño que busco.
Pero vamos, no soy ningún experto.

Se me ocurre que podrías intentar dibujar con paint, o con lapiz y papel, o lo que sea... el diseño aproximado de cómo quieres que te quede la interfaz y así la gente puede proponerte formas de conseguirla o bien como arreglar tu código para lograrlo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
Imágen de perfil de Ivan
Val: 16
Ha aumentado 1 puesto en Java (en relación al último mes)
Gráfica de Java

Posicionar Objetos dentro de un JPanel

Publicado por Ivan (7 intervenciones) el 18/04/2019 19:44:28
Si, es que es una tarea que me asignaron, la cosa es que puse como null el JFrame para modificar los elementos a mi gusto, por que la idea del programa es realizar algo similar a la imagen que anexo, el asunto los los JPanel que tengo que agregar al centro para hacer los tres recuadros con esos iconos y botones ¿De que otra manera crees que podría realizar el acomodo de los componentes? A mi no se me ocurre nada



WhatsApp-Image-2019-04-15-at-4.50.57-PM-2
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

Posicionar Objetos dentro de un JPanel

Publicado por Kabuto (1380 intervenciones) el 19/04/2019 02:24:52
Mira, yo suelo dividirlo todo en tantos JPanel como sea necesario. Y cada uno de estos JPanel, los construyo como clases separadas que heredan de JPanel.
Así evito tener una única clase JFrame con decenas de componentes volviendome loco para acomodarlos.

Prefiero sacarle partido a las ventajas de la Programacion Orientada a Objetos y escribir clases separadas para crear los paneles que crea necesarios.
Cada una de estas clases tendrían sus atributos y métodos para que desde el JFrame principal se pueda interactuar con sus componentes.

En la imagen que has puesto, visualizo 4 paneles principales, los señalo en rojo.
En el segundo panel, donde están las fotos de los candidatos, fíjate que ahí señalo en amarillo otros tres subpaneles que si te das cuenta son idénticos, solo cambia la foto del candidato.
Pues esos tres subpaneles podemos crearlos con una única clase, a cuyo constructor le pasaremos un String con la ruta donde encontrar la imagen que ha de visualizar cada uno.
Luego lo veremos...

01


He intentado replicar lo de la imagen. Es una interfaz sin funcionalidad, los botones no hacen nada.

Mi primera clase se llamaría PanelFuente, ya que sería el panel con los CheckBox de las tres fuentes publicitarias.
Es muy sencillo de crear, ni siquiera hay que modificar el layout que traen por defecto todos los paneles, que es el FlowLayout.
Simplemente declaro e inicializo los 3 CheckBox, creo un Borde compuesto similar al de la foto original y añado los checkbox al panel tal cual.
Este sería su 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
public class PanelFuente extends JPanel{
 
	private JCheckBoxMenuItem checkRadio;
	private JCheckBoxMenuItem checkPrensa;
	private JCheckBoxMenuItem checkTele;
 
	public PanelFuente() {
 
		checkRadio = new JCheckBoxMenuItem("Publicidad por Radio");
		checkPrensa = new JCheckBoxMenuItem("Publicidad por Prensa");
		checkTele = new JCheckBoxMenuItem("Publicidad por Televisión");
		setBorder(javax.swing.BorderFactory.
				createCompoundBorder(new EmptyBorder(15, 10, 5, 10), new TitledBorder("Indique la fuente de informacion") ));
		add(checkRadio);
		add(checkPrensa);
		add(checkTele);
	}
 
	/*
	 * Necesitamos que este panel disponga de algún método que nos informe
	 * de que opciones hay seleccionadas. Hay muchas posibilidades para hacer esto.
	 * 
	 * Una posibilidad es generar un String con el nombre de las fuentes
	 * seleccionadas y retornarlo.
	 */
 
	public String getFuentesSeleccionadas() {
		String fuentes = "";
		if (checkRadio.isSelected())
			fuentes += "-Radio-";
		if (checkRadio.isSelected())
			fuentes += "-Prensa-";
		if (checkTele.isSelected())
			fuentes += "-Television-";
 
		return fuentes;
	}
 
	/*
	 * Otra posibilidad es contruir un array de tres booleans
	 * y con true/false saber quienes están seleccionados o no
	 */
 
	public boolean[] getFuentesSeleccionadasAlt() {
		boolean[] fuentes = {checkRadio.isSelected(), checkRadio.isSelected(), checkTele.isSelected()};
		return fuentes;
	}
 
}

Como puedes ver, a modo de ejemplo, incluyo dos métodos que servirían para informar al JFrame de cuáles checkbox están marcados.
Puesto que los CheckBox están declarados como private, el JFRame no tendrá acceso a ellos, así que necesitamos métodos public para interactuar con ellos.
Según las funciones del programa, se decide que métodos son necesarios. Por ejemplo vendría bien un método que desmarcase todos los checkbox, cuando se pulsase el botón "Reiniciar" que tenemos en otro panel distinto.

Bien, pasemos al segundo panel. El que muestra los tres candidatos. Como dije antes, podemos crear una clase que represente cada uno de estos tres subpaneles y que acepte en su constructor un String para indicarle que imagen ha de mostrar.

A esta clase la he llamado PanelVotar, ya que es donde realizamos la acción de votar.
Esta clase, que es un JPanel porque hereda de JPanel, va a incorporar a su vez dos subpaneles.
Uno contendrá únicamente la imagen.
EL otro contendrá el boton, los dos campos y la barra de progreso.

Usaremos un BoxLayout, indicando que coloque los componentes en vertical, así el panel con imagen quedará encima y el otro panel quedará debajo.
Este panel, el que va debajo, le vamos a poner un GridLayout de 4 x 1. Es decir, 4 filas, 1 columna. Así que los componentes quedarán uno encima de otro. Es muy parecido a lo que conseguiríamos con un BoxLayout vertical, pero el GridLayout fuerza a que todos los componentes tengan un tamaño igual, así que para este caso quedará más vistoso.
Al panel le daremos unas dimensiones "preferidas", el ancho está puesto muy estrecho, a 30 pixeles, valor que no va a poder alcanzar porque la imagen va a forzar un ancho superior.
Pero no importa, lo que quiero es forzar a que el ancho total no supere al de la imagen, si no ponemos ninguan dimension, los campos de texto quedarán más anchos que la imagen y no queda tan vistoso.

El panel que va arriba, el de la imagen, es muy simple. Un JLabel con un ImageIcon construido a partir del String que recibe el constructor. Hay otras formas de mostrar imagenes, pero esta es la más rápida y simple y para este caso ya nos va bien.
Este es el 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
public class PanelVotar extends JPanel{
 
	private ImageIcon imagen;
	private JButton bt_Votar;
	private JTextField campoVotos;
	private JTextField campoPorcentaje;
	private JProgressBar barraProgreso;
 
	public PanelVotar(String rutaImagen) {
		imagen = new ImageIcon(rutaImagen);
		bt_Votar = new JButton("Votar");
		campoVotos = new JTextField();
		campoPorcentaje = new JTextField();
		barraProgreso = new JProgressBar();
		barraProgreso.setValue(20); //Este es un valor de muestra
		barraProgreso.setStringPainted(true);
		setBorder(javax.swing.BorderFactory.
				createCompoundBorder(new LineBorder(Color.BLACK, 3), new EmptyBorder(10, 20, 10, 20) ));
 
		//Creamos el subpanel que irá debajo de la imagen
		JPanel subPanel = new JPanel();
		subPanel.setPreferredSize(new Dimension(30, 110));
		GridLayout layoutGrid = new GridLayout(4, 1);
		layoutGrid.setVgap(5);
		subPanel.setLayout(layoutGrid);
		subPanel.add(bt_Votar);
		subPanel.add(campoVotos);
		subPanel.add(campoPorcentaje);
		subPanel.add(barraProgreso);
 
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		JPanel panelImagen = new JPanel();
		panelImagen.add(new JLabel(imagen));
		add(panelImagen);
		add(subPanel);
	}
 
	/*
	 * Aqui irán los métodos necesarios para interactuar
	 * con los elementos de este panel
	 */
 
}

Sigo en otro mensaje que el foro no me deja escribir tanto en uno solo.
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

Posicionar Objetos dentro de un JPanel

Publicado por Kabuto (1380 intervenciones) el 19/04/2019 02:26:06
Sigamos, siguiente panel es el de los presupuestos (sea lo que sea que signifique eso...) y lo he llamado PanelPresupuestos
Es tan sencillo como el primero, crear 3 JTextFields y añadirlos a un FlowLayout.
He creado un nuevo FLowLayout porque necesito establecer unos pixeles de separacion entre componentes para que se repartan mejor en el ancho del JFrame.
También he puesto algunos métodos de ejemplo, que serviría para interactuar con los campos de texto.

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
public class PanelPresupuestos extends JPanel{
 
	private JTextField campo1;
	private JTextField campo2;
	private JTextField campo3;
 
	public PanelPresupuestos() {
 
		campo1 = new JTextField(8);
		campo2 = new JTextField(8);
		campo3 = new JTextField(8);
		//Creamos un FlowLayout ajustado a nuestras necesidades
		FlowLayout layout = new FlowLayout();
		layout.setHgap(80); //pixeles separacion entre componentes
		setLayout(layout);
		setBorder(javax.swing.BorderFactory.
				createCompoundBorder(new EmptyBorder(10, 10, 5, 10), new TitledBorder("Presupuestos") ));
		add(campo1);
		add(campo2);
		add(campo3);
 
	}
 
	public String getCampo1() {
		return campo1.getText();
	}
 
	public void setCampo1(String txt) {
		campo1.setText(txt);
	}
 
	public String getCampo2() {
		return campo2.getText();
	}
 
	public void setCampo2(String txt) {
		campo2.setText(txt);
	}
 
	public String getCampo3() {
		return campo3.getText();
	}
 
	public void setCampo3(String txt) {
		campo3.setText(txt);
	}
 
}

LLegamos al último panel, lo he llamado PanelTotales.
Como elementos tiene (según aprecio en la imagen que no es muy buena) dos JLabel, dos JtextField y un botón.
Para conseguir que todo quede bien repartido, más o menos como la imagen, de nuevo he decidio dividirlo en dos subpaneles
Uno, irá a la izquierda y tendrá las dos etiquetas y los dos campos de texto en un GridLayout de 2x2.
El otro, el de la derecha, solo tendrá el botón

Estos dos subpaneles, izquierdo y derecho, serán añadidos a esta clase en un FLowLayout que también tendrá establecido un "gap" horizontal, es decir, unos pixeles de separacion entre ambos subpaneles

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
public class PanelTotales extends JPanel{
 
	private JTextField campoVotos;
	private JTextField campoPresupuesto;
	JButton bt_reiniciar;
 
	public PanelTotales() {
		campoVotos = new JTextField();
		campoPresupuesto = new JTextField();
		bt_reiniciar = new JButton("Reiniciar");
		setBorder(javax.swing.BorderFactory.
				createCompoundBorder(new EmptyBorder(5, 10, 15, 10), new TitledBorder("Totales") ));
		/*
		 * Para este panel, haremos dos subpaneles.
		 * Uno, el izquierdo, será un GridLayout de 2x2 para dos JLabel y
		 * los dos JTextField.
		 * 
		 * El derecho será un FlowLayout pro defecto con el boton centrado
		 */
		JPanel panelIzq = new JPanel();
		GridLayout layoutGrilla = new GridLayout(2,2);
		layoutGrilla.setHgap(40);
		layoutGrilla.setVgap(10);
		panelIzq.setLayout(layoutGrilla);
		panelIzq.add(new JLabel("Votos"));
		panelIzq.add(campoVotos);
		panelIzq.add(new JLabel("Presupuesto"));
		panelIzq.add(campoPresupuesto);
 
		JPanel panelDer = new JPanel();
		panelDer.add(bt_reiniciar);
 
		//Configuramos el layout de panel principal y añadimos subpaneles
		FlowLayout layoutFLow = new FlowLayout();
		layoutFLow.setHgap(50);
		setLayout(layoutFLow);
		add(panelIzq);
		add(panelDer);
	}
 
	/*
	 * Aquí irían los métodos que pudieran ser necesarios 
	 * para modificar los campos de texto
	 */
 
}

OK, pues ya tenemos todos los paneles necesarios para componer el marco principal.
ESto lo hacemos con otra clase, que esta vez hereda de JFrame.
Fíjate que sus atributos son los objetos de las clases paneles que acabamos de crear, un PanelFuente, un PanelPresupuestos, un PanelTotales y tres PanelVotar (uno por cada candidato)

Inicializo estos paneles y a PanelVotar le indico a cada uno donde ha de buscar la foto que ha de mostrar.

Estos paneles los vamos a añadir la JFrame mediante un BoxLayout vertical, así quedarán uno encima del otro.
Para los paneles de los candidatos, crearemos un Panel extra, que con un FlowLayout haremos que los tres candidatos queden en horizontal y con 30 pixeles de separacion entre ellos.

Luego en el método main(), simplemente instanciamos a nuestra clase JFrame

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
public class Elecciones extends JFrame{
 
	private PanelFuente panelFuentes;
	private PanelPresupuestos panelPresupuestos;
	private PanelTotales panelTotales;
	private PanelVotar panelCandidato1;
	private PanelVotar panelCandidato2;
	private PanelVotar panelCandidato3;
 
	public Elecciones() {
		super("Aplicacion Elecciones");
		panelFuentes = new PanelFuente();
		panelPresupuestos = new PanelPresupuestos();
		panelTotales = new PanelTotales();
		panelCandidato1 = new PanelVotar("../PanelElecciones/candidatos/ralph.jpg");
		panelCandidato2 = new PanelVotar("../PanelElecciones/candidatos/smithers.jpg");
		panelCandidato3 = new PanelVotar("../PanelElecciones/candidatos/milhouse.jpg");
 
		Container contenedor = getContentPane();
		contenedor.setLayout(new BoxLayout(contenedor, BoxLayout.Y_AXIS));
		contenedor.add(panelFuentes);
		//Para los candidatos haremos un panel con tres subpaneles
		JPanel panelCandidatos = new JPanel();
		FlowLayout layoutFLow = new FlowLayout();
		layoutFLow.setHgap(30);
		panelCandidatos.setLayout(layoutFLow);
		panelCandidatos.add(panelCandidato1);
		panelCandidatos.add(panelCandidato2);
		panelCandidatos.add(panelCandidato3);
		contenedor.add(panelCandidatos);
		//Fin panel candidatos
		contenedor.add(panelPresupuestos);
		contenedor.add(panelTotales);
 
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setResizable(true);
		setVisible(true);
	}
 
	public static void main(String[] args) {
 
		new Elecciones();
 
	}
 
}

Y voilá, esto es lo que consigo:
02

No queda exactamente igual, pero hay que tener en cuenta que respecto al original es distinto sistema operativo, distintas imagenes, distinto tamaño de fuente...

Pero se acerca bastante, y se consigue combinando paneles y distintos layouts.
Esto no se consigue a la primera, hay que ir probando y las primera veces cuesta, luego con la experiencia ya se va viendo cada vez más claro como componer el JFrame de forma óptima.

Adjunto zip con todo el codigo

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
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

Posicionar Objetos dentro de un JPanel

Publicado por Kabuto (1380 intervenciones) el 19/04/2019 14:00:21
Hola de nuevo.

No he podido evitar añadir algo de funcionalidad a la interfaz, así de paso te explico como lo hago yo, que no se si es la mejor forma o no, pero es con la cuál yo me siento más cómodo.

Es muy habitual hacer que la clase principal que hereda de JFrame, implemente también la interfaz ActionListener y luego en el método que se activa cuando hay una acción, preguntar que componente ha generado la acción (o sea, donde ha hecho click el usuario) y según el componente pues realizamos una acción u otra.

Personalmente no me termina de gustar esta forma. Yo prefiero crear nuevas clases que implementen el ActionListener, una por cada botón o elemento que lo requiera, y así cada una de estas clases tendrán el código específico para dicha acción.

Estas clases que implementan el ActionListener, las suelo escribir dentro de la misma clase principal, es decir, son clases anidadas.
Esto me da la ventaja de que así estas clases anidadas tienen acceso fácil a todos los atributos de la clase JFrame principal (paneles, variables,...lo que sea).

En esta interfaz tenemos 4 botones. 1 botón reiniciar y 3 botones para votar candidatos.
La acción de reiniciar el formularo es muy sencilla, consiste en que todos los paneles pongan sus campos de texto a sus valores iniciales, ya sea valor 0, campo vacío, etc...
Como tenemos toda la interfaz dividida en clases JPanel, clases que hemos escrito nosotros y podemos añadirle los métodos que necesitemos, lo que haremos será previamente indicar a cada panel como reiniciarse.
Por ejemplo el PanelFuente con los 3 checkbox, tenemos que decirle que deseleccione cualquier checkbox que pueda estar marcado:
1
2
3
4
5
public void resetPanel() {
		checkRadio.setSelected(false);
		checkPrensa.setSelected(false);
		checkTele.setSelected(false);
	}
El PanelTotales tendrán que poner en blanco sus campos de texto:
1
2
3
4
public void resetPanel() {
		campoVotos.setText(null);
		campoPresupuesto.setText(null);
	}
Lo mismo hará PanelPresupuestos:
1
2
3
4
5
public void resetPanel() {
		campo1.setText(null);
		campo2.setText(null);
		campo3.setText(null);
	}

Los paneles PanelVotar tendrá que poner valores 0 en sus campos y reiniciar la barra de progreso:
1
2
3
4
5
public void resetPanel() {
		campoVotos.setText("0");
		campoPorcentaje.setText("0,0%");
		barraProgreso.setValue(0);
	}

Una vez creados estos métodos, ya podemos crear una clase que implemente ActionListener y en su método que se dispara cuando hay una acción, llamamos a los métodos de cada panel para que se reinicien.
Además pone a 0 un contador de votos, este es un atributo que le he añadido a la clase principal JFrame que nos servirá para ir contando el total de votos computados.

1
2
3
4
5
6
7
8
9
10
11
12
private class AccionReiniciar implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			panelFuentes.resetPanel();
			panelCandidato1.resetPanel();
			panelCandidato2.resetPanel();
			panelCandidato3.resetPanel();
			panelPresupuestos.resetPanel();
			panelTotales.resetPanel();
			votosTotales = 0;
		}
	}

Y ahora que ya tenemos esta clase de Acción, simplemente se la añadimos al botón al que queremos que esté asociado.
Esto lo hacemos en el constructor de la clase principal, justo después de instanciar el panel que contiene este botón:
1
2
panelTotales = new PanelTotales();
		panelTotales.bt_reiniciar.addActionListener(new AccionReiniciar());

Para poder acceder a bt_reiniciar, que es el JButton declarado en PanelTotales, este no puede ser private. Así desde la clase principal tenemos fácil acceso a él y podemos añadirle nuestra clase ActionListener.

Luego vienen los 3 botones de voto.
Estos 3 botones, en realidad van a realizar la misma acción, solo que cada uno la hará en relación a un candidato determinado.

Así que para este caso, no hace falta escribir tres clases ActionListener distintas. Bastará con escribir solo una, que podemos llamar AccionVotar e instanciaremos tres objetos a partir de ella, uno por cada botón de votar.
Pero tenemos que pensar en una forma de hacer que cada objeto instanciado sepa de forma rápida a que candidato está asociado. Una forma de hacerlo es pasarle por contructor un entero entre 1 y 3, así según el valor del entero, cada objeto AccionVotar sabrá con que candidato ha de interactuar.

Este valor entre 1 y 3 se ha de recoger en un atributo, y así luego podrá evaluarse

Este sería el código de AccionVotar:
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
private class AccionVotar implements ActionListener {
 
		private int candidatoVotado;
 
		public AccionVotar(int numCandi) {
			candidatoVotado = numCandi;
		}
 
		@Override
		public void actionPerformed(ActionEvent e) {
			//Contamos voto en el computo total
			votosTotales++;
			panelTotales.setVotos(votosTotales);
			//Sumamos voto al candidato votado
			switch(candidatoVotado) {
			case 1:
				panelCandidato1.sumarVoto();
				break;
			case 2:
				panelCandidato2.sumarVoto();
				break;
			case 3:
				panelCandidato3.sumarVoto();
				break;
			}
			//Recalculamos el porcentaje de votos para cada candidato
			panelCandidato1.setPorcentajes(calculaPorcentaje(votosTotales, panelCandidato1.getVotos()));
			panelCandidato2.setPorcentajes(calculaPorcentaje(votosTotales, panelCandidato2.getVotos()));
			panelCandidato3.setPorcentajes(calculaPorcentaje(votosTotales, panelCandidato3.getVotos()));
 
		}
 
	}

Cada vez que se pulse un boton de votar cualquiera:
- Se suma un voto al contador de votos totales
- Se actualiza el campo de PanelTotales que muestra los votos totales
- Se evalua el valor del entero recibido para que saber a que candidato hay que sumarle un voto.
- Una vez sumado el voto al candidato, cambian los porcentajes de voto de los tres candidatos, así que para cada panel de candidato recalculamos el porcentaje de voto y actualizamos la informacion.

Y ahora ya, a cada PanelVotar, le agregamos a su boton una instancia de esta clase, especificando a que candidato está asignado:
1
2
3
4
5
6
panelCandidato1 = new PanelVotar("../PanelElecciones/candidatos/ralph.jpg");
		panelCandidato1.bt_Votar.addActionListener(new AccionVotar(1));
		panelCandidato2 = new PanelVotar("../PanelElecciones/candidatos/smithers.jpg");
		panelCandidato2.bt_Votar.addActionListener(new AccionVotar(2));
		panelCandidato3 = new PanelVotar("../PanelElecciones/candidatos/milhouse.jpg");
		panelCandidato3.bt_Votar.addActionListener(new AccionVotar(3));

Ahora ya se puede votar, y los votos se cuentan, se muestran porcentajes y la barra progresos aumenta o disminuye para cada candidato según los votos recibidos.
Lo que no hace nada es con lo de los presupuestos, porque no se bien como se supone se gestiona eso.

03

Adjunto un nuevo zip con todo estos añadidos, así podrás ver también los métodos que suman votos al candidato, el que recalcula porcentajes, etc...

Repito que esta es la forma como yo hago estas cosas. Hay otras manera y no sabría decirte cuál es mejor.
Yo con esta forma, es como mejor me organizo las ideas y me va mejor para separar todo el código en pequeñas porciones y luego ensamblarlas fácilmente.

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
1
Comentar
Imágen de perfil de Ivan
Val: 16
Ha aumentado 1 puesto en Java (en relación al último mes)
Gráfica de Java

Posicionar Objetos dentro de un JPanel

Publicado por Ivan (7 intervenciones) el 19/04/2019 18:52:06
Oh, vaya, esta genial todo lo que hiciste, yo, como soy nuevo en este mundo de la programación, pues a veces se me complica realizar algunas cosas, pero voy aprendiendo, por lo que veo tengo que reforzar bastante la POO, de hecho estoy viendo que tengo que reforzar muchas cosas sobre las que pensaba que si sabia, voy a estudiar bastante el código que realizaste, muchas gracias de veras, ya andaba rompiéndome la cabeza bastante :)
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

Posicionar Objetos dentro de un JPanel

Publicado por Kabuto (1380 intervenciones) el 19/04/2019 20:08:56
Te aseguro que con esto, siempre hay algo que aprender.
Fíjate que haciendo este ejercicio he usado por primera vez lo de crear bordes compuestos y ya he visto que puede ser útil para espaciar paneles entre ellos, además de las opciones de espaciado que puedan proporcionar los layouts.

Aquí lo importante es dividir y separar en partes pequeñas. Yo no hice todo de golpe. Primero hice el panel con los checkbox y la clase principal JFrame.
Le añadí dicho panel, ví que más o menos quedaba como esperaba e hice el siguente panel, el de los Presupuestos.
Lo añadí, miré a ver si quedaba bien, y pase al siguiente, al de los Totales, y así..

El panel de votar, lo dejé para lo último porque en apariencia es el que iba a dar un poquito más de trabajo, aunque luego no fue tanto.

Pero la clave es esa, dividir en partes pequeñas y usar tantos JPanel como sean necesarios, en lugar de intentar organizar montones de componentes en un único contenedor.

Usar un layout null, digamos que te da más poder para acomodar las cosas a tu gusto. Pero requiere mucha más labor y precisión. Y luego los componentes no se adaptan si la ventana cambia de tamaño.

En fín, cualquier duda que te surja no dudes en preguntar.
Y a ver si alguien se anima a mostrarnos como crearía él la interfaz, así conocemos los enfoques de otras personas y aprendemos más.

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
1
Comentar