Java - Mover una figura con un slider

 
Vista:

Mover una figura con un slider

Publicado por Paula (1 intervención) el 10/04/2020 17:41:10
Hola me gustaria saber si me pueden ayudar con un codigo que me mueva digamos un circulo vertical y horizontalmente con ayuda de un slider, sin Jframe si no con el Jpanel.

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

Mover una figura con un slider

Publicado por Kabuto (1381 intervenciones) el 10/04/2020 20:26:33
Lo primero es crear una clase JPanel en la que se dibuje un círculo.

Para dibujar un circulo, necesitamos 4 argumentos:
- posición en el eje de coordenadas x (horizontal)
- posición en el eje de coordenadas y (vertical)
- ancho
- alto

El ancho y el alto lo dejaremos con un valor fijo, pero las coordenadas x e y irán variando a través de los JSlider, así que x e y serán atributos de nuestra clase.
Y tendremos métodos para modificar sus valores, cada vez que se modifique uno de los JSlider.

Esta clase JPanel, no va a contener JSliders, ni método main(), ni nada.
Simplemente va a modelar un panel con un circulo, que mediante dos métodos se irá redibujando en las distintas posiciones x e y que vaya recibiendo.
Hay que darle un tamaño, por ejemplo 500 x 500. El tamaño de este panel influirá luego en los valores máximo de los JSlider, ya que si por ejemplo dan valores que superen estas dimensiones, perderíamos de vista el círculo.

En mi caso, he decidido que el panel tenga el fondo blanco y lo que se dibuje sea una circunferencia (no un círculo) de color rojo.
Además le he puesto un borde biselado para que luego quede un poco más vistoso.

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
public class PanelCirculo extends JPanel{
 
	private int x = 250; //Comenzamos dibujando en el centro aproximadamente
	private int y = 250;
 
	public PanelCirculo() {
		setPreferredSize(new Dimension(500, 500));
		setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		super.setBackground(Color.WHITE);
	}
 
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		g.setColor(Color.RED);
		g.fillOval(x, y, 50, 50);
	}
 
	public void desplazarX(int x) {
		this.x = x;
		repaint();
	}
 
	public void desplazarY(int y) {
		this.y = y;
		repaint();
	}
 
}

Fíjate que para dibujar la figura, sobreescribimos el método paint().
Los métodos para desplazarla, lo que hacen es modificar los atributos x e y con el nuevo valor y ordenan "repintar" el panel.

Bien, este sería el panel con círculo.
Ahora, en otra clase que será la principal, construiremos un marco con dos JSlider.
El marco podemos maquetarlo con un BorderLayout. Este layout nos distribuye el marco en 5 zonas.
Una zona es la central, que será donde insertaremos nuestro panel con la figura.
Las otras 4 zonas son NORTE (arriba), SUR (abajo), ESTE(derecha) y OESTE(izquierda).

En el sur podemos poner el JSlider que modifique la horizontal, o sea, el eje X
En el este podemos poner el otro Jslider, orientado verticalmente, y será quien modifique el eje Y

Cada JSlider, irá dentro de un JPanel, así que en esta clase, tendremos anidadas otras clases "menores" para modelar estos paneles que serán añadidos al marco principal.
También haremos otro panel central, que a su vez contendrá el panel de la figura.
Se podría haber usado directamente el panel de la figura para poner en el centro, pero usando otro panel "externo", podemos darle un borde vacío de 20 pixeles por cada lado y así queda algo de separación entre paneles y es más bonito.
Este borde vacío, primero probé a ponerselo al panel de la figura, pero entonces la figura se desplazaba por encima del borde vacío y del borde biselado.

Por eso opté por usar otro panel contenedor, así la dimensión extra que ganamos por el borde de 20 píxeles, no afecta al espacio por donde puede moverse la figura.

Los JSlider cada uno , va a tener su propio ChangeListener.
Estos ChangeListener lo que hacen es detectar si los JSlider se están desplazando, en cuyo caso recogerán el valor actual del Jslider para enviárselo al panel de la figura, que con sus métodos hará que la figura se "mueva".

Este sería 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
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 MoverCirculo extends JFrame{
 
	JSlider horizontal;
	JSlider vertical;
	PanelCirculo panelCirculo;
 
	public MoverCirculo() {
 
		setLayout(new BorderLayout());
		add(new PanelHorizon(), BorderLayout.SOUTH);
		add(new PanelVerti(), BorderLayout.EAST);
		add(new PanelCentral(), BorderLayout.CENTER);
 
		setTitle("Mover Círculo");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setResizable(false);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}
 
	//******Clases panel******
 
	class PanelCentral extends JPanel {
 
		public PanelCentral() {
			panelCirculo = new PanelCirculo();
			setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
			add(panelCirculo);
		}
	}
	class PanelHorizon extends JPanel{
 
		public PanelHorizon() {
			horizontal = new JSlider();
			horizontal.setMaximum(450);
			horizontal.setValue(250);
			horizontal.setPreferredSize(new Dimension(500, 60));
			horizontal.setMajorTickSpacing(50);
			horizontal.setMinorTickSpacing(5);
			horizontal.setPaintTicks(true);
			horizontal.setPaintLabels(true);
			horizontal.addChangeListener(new MueveEjeX());
			add(horizontal);
		}
	}
 
	class PanelVerti extends JPanel{
 
		public PanelVerti() {
			vertical = new JSlider();
			vertical.setOrientation(SwingConstants.VERTICAL);
			vertical.setMaximum(450);
			vertical.setValue(250);
			vertical.setPreferredSize(new Dimension(60, 500));
			vertical.setMajorTickSpacing(50);
			vertical.setMinorTickSpacing(5);
			vertical.setPaintTicks(true);
			vertical.setPaintLabels(true);
			vertical.setInverted(true);
			vertical.addChangeListener(new MueveEjeY());
			add(vertical);
		}
	}
 
	//*****Clases Listener*****
 
	class MueveEjeX implements ChangeListener {
		@Override
		public void stateChanged(ChangeEvent e) {
			if (horizontal.getValueIsAdjusting())
				panelCirculo.desplazarX(horizontal.getValue());
 
		}
	}
 
	class MueveEjeY implements ChangeListener {
		@Override
		public void stateChanged(ChangeEvent e) {
			if (vertical.getValueIsAdjusting())
				panelCirculo.desplazarY(vertical.getValue());
 
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new MoverCirculo();
			}
		});
	}
 
}


Los JSlider requieren cierta configuración para que queden presentables.
Se les pone como limite máximo 450, a pesar de que el panel donde se mueve la figura es de 500, ¿por qué?
Porque a ese límite hay que descontar el ancho y alto que tiene la figura, si no al llegar a los límite se sale del panel.
En mi caso puse que la circunferencia mide 50x50, por eso descontamos 50 pixeles de las dimensiones del panel para establece los máximos.
Al JSlider vertical además hay que pedir que invierta el orden establecido de la regla de medidas que muestra en pantalla.
1
vertical.setInverted(true);
Como sale por defecto, no coincide con el desplazamiento de Y, entonces cuando incrementas la Y, la figura en lugar de bajar, sube... y queda raro.
Puedes jugar a modificar ese valor para ver como queda de un modo y otro.

Y no hay mucho más que contar.
La lógica es muy sencilla. Cuando un JSlider cambia (ChangeListener) se le envía a los métodos del panel de la figura los nuevos valores X e Y para que redibuje la figura en la nueva posición. Eso es todo.


moverCirculo

Abajo adjunto en un zip el código de las dos clases, por si te es más cómodo.
Por favor, no te conformes con obtener el código. Pregunta cualquier cosa que no entiendas.
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