Java - Dimensionamiento ejecutable Java

 
Vista:
sin imagen de perfil

Dimensionamiento ejecutable Java

Publicado por kat (2 intervenciones) el 27/04/2023 01:22:44
Hola buenas tardes, quería saber una duda que tengo...

Cuando se crea un ejecutable .exe o .jar, en el computador A donde se creo sale tal cual la resolución o el dimensionamiento que se le dio, pero al probarlo en un computador B sale de un tamaño distinto.........alguien sabe porque ocurre esto o si hay un código para corregirlo me serviría de mucho....... (en mi caso uso Java NetBeans)


Saludos :)
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

Dimensionamiento ejecutable Java

Publicado por Kabuto (1381 intervenciones) el 27/04/2023 20:01:31
Hola.

Si el computador B tiene distintas dimensiones de pantalla respecto del A, y has usado medidas absolutas para el diseño de la interfaz, entonces es normal que se vea distinto en ambos computadores.

Yo por ejemplo, la resolución de mi pantalla es bastante grande, 2560x1440.
Si hago una interfaz con unas dimensiones absolutas que se ajusten a mi pantalla, luego esa interfaz se puede ver pequeña si se ejecuta en una pantalla 4K..., o peor aún, se puede ver enorme en pantallas de menor resolución como 1920x1080 ó 1366x768, que son además las resoluciones más comunes según indica StatCounter

Puedes paliar esas diferencias empleando medidas relativas en lugar de absolutas. Es decir, unas medidas que se ajusten según el tamaño de pantalla del sistema donde se vaya a ejecutar el programa.

La complejidad para realizar esto ya dependerá de cómo este diseñado el programa, pero en esencia, consiste en pedirle al programa que lo primero que haga es preguntar al sistema operativo donde se está ejecutando cuáles son las dimensiones de la pantalla.
Así podrás poner como atributos de acceso global el ancho y alto de la pantalla y así hacer que las dimensiones de los elementos que componen la interfaz se calculen en relación a esas dimensiones.


Hagamos un ejemplo sencillo.
Supongamos que yo hago una interfaz acorde a las dimensiones de mí pantalla.
Quiero que la interfaz ocupe 3/4 partes de mi pantalla.

Se va a componer de tres partes:
Un panel superior será un título que ocupará 1/4 parte del alto de la interfaz y el ancho completo

Un panel central que ocupará 2/4 partes del alto(o sea, la mitad). Este panel se va a subdividir en dos paneles horizontales que contendrán texto y cada uno va a ocupar la mitad del ancho de la interfaz

Y un panel inferior con un botón que, al igual que el superior, ocupará 1/4 del alto y todo el ancho.


Bien, si yo hago esto con medidas absolutas, el código podría ser este:
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
public class Gui_Absoluta extends JFrame {
 
	public Gui_Absoluta() {
 
		setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
		add(new PanelTitulo());
		add(new PanelTexto());
		add(new PanelBoton());
 
		setTitle("Medidas absolutas");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}
 
	private class PanelTitulo extends JPanel {
		public PanelTitulo() {
			setPreferredSize(new Dimension(1920, 270));
			setBackground(Color.DARK_GRAY);
 
			JLabel titulo = new JLabel("Esto es un título");
			titulo.setFont(new Font("Verdana", Font.BOLD, 85));
			titulo.setForeground(Color.WHITE);
			add(titulo);
		}
	}
 
	private class PanelTexto extends JPanel {
		public PanelTexto() {
			setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
			JPanel pnIzquierdo = new JPanel();
			pnIzquierdo.setPreferredSize(new Dimension(960, 540));
			pnIzquierdo.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
			pnIzquierdo.setBackground(Color.WHITE);
			JPanel pnDerecho = new JPanel();
			pnDerecho.setPreferredSize(new Dimension(960, 540));
			pnDerecho.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
			pnDerecho.setBackground(Color.WHITE);
 
			JTextArea txtIz = new JTextArea(TEXTO_DUMMY,JScrollPane.VERTICAL_SCROLLBAR_NEVER,
					JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
			txtIz.setFont(new Font("Ink Free", Font.PLAIN, 35));
			txtIz.setForeground(Color.RED);
			txtIz.setWrapStyleWord(true);
			txtIz.setLineWrap(true);
			txtIz.setEditable(false);
			pnIzquierdo.add(txtIz);
			JTextArea txtDr = new JTextArea(TEXTO_DUMMY, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
					JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
			txtDr.setFont(new Font("Ink Free", Font.PLAIN, 35));
			txtDr.setForeground(Color.RED);
			txtDr.setWrapStyleWord(true);
			txtDr.setLineWrap(true);
			txtDr.setEditable(false);
			pnDerecho.add(txtDr);
 
			JScrollPane scrollIZ = new JScrollPane(pnIzquierdo);
			JScrollPane scrollDer = new JScrollPane(pnDerecho);
 
			add(scrollIZ);
			add(scrollDer);
		}
	}
 
 
	private class PanelBoton extends JPanel {
		public PanelBoton() {
			setPreferredSize(new Dimension(1920, 270));
 
			JButton boton = new JButton("Soy un botón");
			boton.setFont(new Font("Verdana", Font.ITALIC, 25));
			boton.setForeground(Color.BLUE);
			add(boton);
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new Gui_Absoluta();
			}
		});
	}
 
	private final String TEXTO_DUMMY = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
			+ "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,"
			+ " quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
			+ " Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
			+ " Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est"
			+ " laborum.";
}

Con estas medidas absolutas, que he obtenido haciendo números con una calculadora, vemos que en mi pantalla si se ajusta bien y ocupa las 3/4 partes del total.
guiSwing

Pero si lo ejecuta alguien con una pantalla de menor resolución, lo verá todo más grande e incluso puede que la interfaz se exceda de los límites de su pantalla y no pueda trabajar bien con ella.


En lugar de calcular las dimensiones con una calculadora basándome en las dimensiones de pantalla, puedo hacer esos mismos cálculos en el código y basándome en la pantalla donde se esté ejecutando el programa.

Con la instrucción:
1
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
Puedo obtener las dimensiones de la pantalla y establecer un ancho y un alto para mi interfaz, a partir del cuál se calcularán el resto de componentes.

Es lo primero que haré en el constructor:
1
2
3
4
5
6
7
8
9
10
11
public class Gui_Relativa extends JFrame {
 
	private double ancho;
	private double alto;
 
	public Gui_Relativa() {
 
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		//Queremos que la interfaz al completo ocupe 3/4 partes del total de la pantalla
		ancho = dim.getWidth() - (dim.getWidth() / 4);
		alto = dim.getHeight() - dim.getHeight() / 4;

Teniendo esos dos atributos con visibilidad global, puedo usarlos para calcular las dimensiones del resto de paneles, por ejemplo el panel del título:
1
2
3
4
5
6
7
8
9
10
11
12
13
private class PanelTitulo extends JPanel {
		public PanelTitulo() {
			int anchoTitulo = (int) ancho; //Ancho completo
			int altoTitulo = (int) (alto / 4); //Una cuarta parte del alto
			setPreferredSize(new Dimension(anchoTitulo, altoTitulo));
			setBackground(Color.DARK_GRAY);
 
			JLabel titulo = new JLabel("Esto es un título");
			titulo.setFont(new Font("Verdana", Font.BOLD, (int) ancho/22));
			titulo.setForeground(Color.WHITE);
			add(titulo);
		}
	}

Fíjate que incluso puedo decidir el tamaño de las fuentes de texto en relación al ancho de la interfaz. Porque de poco sirve si consigo que el marco y los paneles se hagan más pequeños para las pantallas de menor resolución, pero las fuentes siguen siendo gigantes para ellas.

Esto es un poco menos fiable porque no todo el mundo tiene las mismas fuentes, ni todo el mundo tiene la misma visión y al final si una fuente es pequeña o grande depende de los ojos que la miran.

Pero bueno, más o menos, al diseñar tu interfaz en tú pantalla puedes ir buscando un divisor para el ancho hasta encontrar uno que a ti te parezca adecuado. Y en teoría, como el tamaño se está calculando en relación al ancho de pantalla de cada uno, tu interfaz se verá similar en pantallas de distinto tamaño.

Dejo aquí el ejemplo completo, calculando todas las dimensiones y fuentes con valores relativos a las dimensiones de la pantalla.
Si yo comparo ambas interfaces en mí pantalla, tienen el mismo tamaño idéntico, solo hay ligeras diferencias en las fuentes 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
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
public class Gui_Relativa extends JFrame {
 
	private double ancho;
	private double alto;
 
	public Gui_Relativa() {
 
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		//Queremos que la interfaz al completo ocupe 3/4 partes del total de la pantalla
		ancho = dim.getWidth() - (dim.getWidth() / 4);
		alto = dim.getHeight() - dim.getHeight() / 4;
 
		setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
		add(new PanelTitulo());
		add(new PanelTexto());
		add(new PanelBoton());
 
		setTitle("Medidas absolutas");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}
 
	private class PanelTitulo extends JPanel {
		public PanelTitulo() {
			int anchoTitulo = (int) ancho; //Ancho completo
			int altoTitulo = (int) (alto / 4); //Una cuarta parte del alto
			setPreferredSize(new Dimension(anchoTitulo, altoTitulo));
			setBackground(Color.DARK_GRAY);
 
			JLabel titulo = new JLabel("Esto es un título");
			titulo.setFont(new Font("Verdana", Font.BOLD, (int) ancho/22));
			titulo.setForeground(Color.WHITE);
			add(titulo);
		}
	}
 
	private class PanelTexto extends JPanel {
		public PanelTexto() {
			int anchoTexto = (int) ancho / 2; //Tenemos dos paneles en horizontal, cada uno ocupa la mitad del ancho
			int altoTexto = (int) alto / 2; //Dos cuartas partes (la mitad) del alto
 
			setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
			JPanel pnIzquierdo = new JPanel();
			pnIzquierdo.setPreferredSize(new Dimension(anchoTexto, altoTexto));
			pnIzquierdo.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
			pnIzquierdo.setBackground(Color.WHITE);
			JPanel pnDerecho = new JPanel();
			pnDerecho.setPreferredSize(new Dimension(anchoTexto, altoTexto));
			pnDerecho.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
			pnDerecho.setBackground(Color.WHITE);
 
			JTextArea txtIz = new JTextArea(TEXTO_DUMMY,JScrollPane.VERTICAL_SCROLLBAR_NEVER,
					JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
			txtIz.setFont(new Font("Ink Free", Font.PLAIN, (int) ancho/55));
			txtIz.setForeground(Color.RED);
			txtIz.setWrapStyleWord(true);
			txtIz.setLineWrap(true);
			txtIz.setEditable(false);
			pnIzquierdo.add(txtIz);
			JTextArea txtDr = new JTextArea(TEXTO_DUMMY, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
					JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
			txtDr.setFont(new Font("Ink Free", Font.PLAIN, (int) ancho/55));
			txtDr.setForeground(Color.RED);
			txtDr.setWrapStyleWord(true);
			txtDr.setLineWrap(true);
			txtDr.setEditable(false);
			pnDerecho.add(txtDr);
 
			JScrollPane scrollIZ = new JScrollPane(pnIzquierdo);
			JScrollPane scrollDer = new JScrollPane(pnDerecho);
 
			add(scrollIZ);
			add(scrollDer);
		}
	}
 
 
	private class PanelBoton extends JPanel {
		public PanelBoton() {
			int anchoBoton = (int) ancho; //Ancho completo
			int altoBoton = (int) (alto / 4); //Una cuarta parte del alto
			setPreferredSize(new Dimension(anchoBoton, altoBoton));
 
			JButton boton = new JButton("Soy un botón");
			boton.setFont(new Font("Verdana", Font.ITALIC, (int) ancho/77));
			boton.setForeground(Color.BLUE);
			add(boton);
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new Gui_Relativa();
			}
		});
	}
 
	private final String TEXTO_DUMMY = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
			+ "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,"
			+ " quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
			+ " Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
			+ " Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est"
			+ " laborum.";
}
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
sin imagen de perfil

Dimensionamiento ejecutable Java

Publicado por Kat (2 intervenciones) el 28/04/2023 03:12:24
Muchas gracias al responder mi duda, ha sido de mucha ayuda.
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