Java - mover ventanas

 
Vista:
sin imagen de perfil

mover ventanas

Publicado por Joel (1 intervención) el 06/11/2022 20:28:56
como puedo mover una ventana que este al centro de la pantalla en diagonal primero que vaya para la esquina superior izquierda luego vuelva al centro, otra vez que vaya a la esquina superior izquierda y vuelva al centro, que vaya a la esquina inferior izquierda y que vuelva al centro, luego a la esquina inferior derecha y vuelva al centro otra vez
por favor si tienen ya hecho y si gustan me lo podrian facilitar 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
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 ventanas

Publicado por Kabuto (1381 intervenciones) el 07/11/2022 00:12:09
Se puede hacer con un JFrame con unos atributos tipo int para indicar su posición X y posición Y en la pantalla.
Incrementando o decrementando esas posiciones podemos cambiar la localización de la ventana.

Hay que controlar los límites de la pantalla.
Hacia la izquierda y hacia arriba ya sabemos que los límites son 0.
Pero hacia abajo y hacia la derecha el límite dependerá del tamaño de cada pantalla. Así que habrá que pregunta al sistema las dimensiones de la pantalla, por ejemplo 2560x1440, y eso serían los límites, pero restando el tamaño de nuestro JFrame.
Si nuestro JFrame es 300x300, pues el límite de X hacia la derecha será 2560 - 300.
Y el límite de Y hacia abajo será 1440 - 300.

Para alterar la localización del JFrame en "tiempo real", necesitamos crear un hilo de ejecución paralelo al programa principal.
Podemos usar la clase Thread o mejor aún, la clase SwingWorker.


Aquí pongo el código de un primer intento, donde simplemente se desplaza la ventana desde el centro hacia la esquina superior izquierda.
Sin embargo, no es del todo satisfactorio y veremos que la ventana llega arriba del todo antes de tocar la esquina.

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
public class Ventana extends JFrame {
 
	private int posX;
	private int posY;
	private int maxX;
	private int maxY;
	private JLabel lbPosicion;
 
	public Ventana( ) {
 
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300,300);
		setLocationRelativeTo(null);
		setVisible(true);
 
		setLayout(new FlowLayout());
 
		maxY = Toolkit.getDefaultToolkit().getScreenSize().width - 300;
		maxY = Toolkit.getDefaultToolkit().getScreenSize().height - 300;
		posX = getLocationOnScreen().x;
		posY = getLocationOnScreen().y;
 
		lbPosicion = new JLabel(String.format("Pos X: %d , Pos Y: %d", posX, posY));
		getContentPane().add(lbPosicion);
 
		Mover mover = new Mover(this);
		mover.execute();
	}
 
	private class Mover extends SwingWorker {
 
		private JFrame ventana;
 
		public Mover(JFrame ventana) {
			this.ventana = ventana;
		}
 
		@Override
		protected Object doInBackground() throws Exception {
			//Mover a esquina superior izquierda
			while (posX > 0 || posY > 0) {
				if (posX > 0)
					posX--;
				if (posY > 0)
					posY--;
				ventana.setLocation(posX, posY);
				lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
				Thread.sleep(10);
			}
			return null;
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new Ventana();
			}
		});
	}
}


Esto es porque las pantallas no son cuadradas, hay mucha más distancia en el eje X que en el eje Y.

Y no se muy bien como resolver esto. Incluso tal vez no se pueda, porque las posiciones son valores enteros y nunca se va a conseguir ir exactamente recto hacia la esquina.
Se podría si las posiciones se pudieran indicar con números reales, es decir, que contemplen decimales, lo que nos daría mejor precisión.

Sí se puede mejorar un poco. Si dividimos la posición de X entre la posición de Y, sabremos el ratio que hay entre ellos (aproximado porque son enteros).
Así sabremos cuántos "pasos" ha de dar X en cada ciclo, es decir, cuántos pixeles ha de desplazarse el eje X para ir a la par con el eje Y.
Marco en negrita este cálculo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private class Mover extends SwingWorker {
 
		private JFrame ventana;
 
		public Mover(JFrame ventana) {
			this.ventana = ventana;
		}
 
		@Override
		protected Object doInBackground() throws Exception {
			int pasosX = posX / posY; 
			//Mover a esquina superior izquierda
			while (posX > 0 || posY > 0) {
				if (posX > 0)
					posX-=pasosX;
				if (posY > 0)
					posY--;
				ventana.setLocation(posX, posY);
				lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
				Thread.sleep(10);
			}
			return null;
		}
	}


No es perfecto, pero queda mejor.

Pues bien, siguiendo esta lógica, ya podemos hacer el resto de movimientos.
Vamos a mejorar la clase Mover.
Vamos a añadir atributos para "recordar" donde está el centro y poder volver a él.
Los "pasos" también lo vamos a configurar como un atributo.

Y los desplazamientos, como algunos se repiten, los vamos a escribir en métodos separados.
Con el que hay que tener especial cuidado será con el método de "volver al centro". Porque este desplazamiento será distinto según desde que esquina queremos volver, así que usaremos varios IF para saber donde estamos y establecer cuál es el camino a seguir para volver al centro.

El programa final quedaría 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
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
147
148
149
150
151
152
public class Ventana extends JFrame {
 
	private int posX;
	private int posY;
	private int maxX;
	private int maxY;
	private JLabel lbPosicion;
 
	public Ventana( ) {
 
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300,300);
		setLocationRelativeTo(null);
		setVisible(true);
 
		setLayout(new FlowLayout());
 
		maxX = Toolkit.getDefaultToolkit().getScreenSize().width - 300;
		maxY = Toolkit.getDefaultToolkit().getScreenSize().height - 300;
		posX = getLocationOnScreen().x;
		posY = getLocationOnScreen().y;
 
		lbPosicion = new JLabel(String.format("Pos X: %d , Pos Y: %d", posX, posY));
		getContentPane().add(lbPosicion);
 
		Mover mover = new Mover(this);
		mover.execute();
	}
 
	private class Mover extends SwingWorker {
 
		private JFrame ventana;
		private int pasosX;
		private int centroY;
		private int centroX;
 
		public Mover(JFrame ventana) {
			this.ventana = ventana;
			centroX = posX;
			centroY = posY;
			pasosX = posX / posY;
		}
 
		@Override
		protected Object doInBackground() throws Exception {
 
			irSuperiorIzquierda();
			irCentro();
			irSuperiorIzquierda();
			irCentro();
			irInferiorIzquierda();
			irCentro();
			irInferiorDerecha();
			irCentro();
 
			return null;
		}
 
		private void irSuperiorIzquierda() throws InterruptedException {
			while (posX > 0 || posY > 0) {
				if (posX > 0)
					posX-=pasosX;
				if (posY > 0)
					posY--;
				ventana.setLocation(posX, posY);
				lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
				Thread.sleep(10);
			}
		}
 
		private void irCentro() throws InterruptedException {
			if (posX < centroX) {
				if (posY < centroY)
					while (posX < centroX || posY < centroY) {
						if (posX < centroX)
							posX += pasosX;
						if (posY < centroY)
							posY++;
						ventana.setLocation(posX, posY);
						lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
						Thread.sleep(10);
					}
				else
					while (posX < centroX || posY > centroY) {
						if (posX < centroX)
							posX += pasosX;
						if (posY > centroY)
							posY--;
						ventana.setLocation(posX, posY);
						lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
						Thread.sleep(10);
					}
			}
			else {
				if (posY < centroY)
					while (posX > centroX || posY < centroY) {
						if (posX > centroX)
							posX -= pasosX;
						if (posY < centroY)
							posY++;
						ventana.setLocation(posX, posY);
						lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
						Thread.sleep(10);
					}
				else
					while (posX > centroX || posY > centroY) {
						if (posX > centroX)
							posX -= pasosX;
						if (posY > centroY)
							posY--;
						ventana.setLocation(posX, posY);
						lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
						Thread.sleep(10);
					}
			}
 
		}
 
		private void irInferiorIzquierda() throws InterruptedException {
			while (posX > 0 || posY < maxY) {
				if (posX > 0)
					posX-=pasosX;
				if (posY < maxY)
					posY++;
				ventana.setLocation(posX, posY);
				lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
				Thread.sleep(10);
			}
		}
 
		private void irInferiorDerecha() throws InterruptedException {
			while (posX < maxX || posY < maxY) {
				if (posX < maxX)
					posX+=pasosX;
				if (posY < maxY)
					posY++;
				ventana.setLocation(posX, posY);
				lbPosicion.setText(String.format("Pos X: %d , Pos Y: %d", posX, posY));
				Thread.sleep(10);
			}
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new Ventana();
			}
		});
	}
}


Pregunta si algo no se entiende.
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