[Swing] El botón se bloquea después de que JPanel reescribe paint () y la monitorización del teclado falla cuando se hace clic en el botón

Imagen de efecto

Descripción del contenido

La imagen de arriba es la sala de burbujas hecha por nuestro equipo. Al final del proyecto, asumí una pequeña tarea, que es agregar 3 botones en la captura de pantalla en la parte inferior de la interfaz del juego e implementar algunas funciones (los miembros de la función de algunos botones ya se han realizado Sí, solo necesito llamar a sus métodos). A continuación, extraeré los problemas encontrados y los registraré en el blog. Creo que algunos estudiantes encontrarán estos problemas.

1. ¿Cómo diseñar mejor el grupo de botones en la parte inferior central del panel? Y parece que flota sobre el mapa.

2. Debido a que el método paint () se sobrescribe en el panel, el grupo de botones está bloqueado. Pero cuando se mueve el mouse hacia arriba, el grupo de botones se puede revelar nuevamente.

3. Después de hacer clic en cualquier botón en la parte inferior, la supervisión del teclado se desactiva. Pulsa el teclado, los personajes del juego no se pueden utilizar.

Pregunta 1

De hecho, no estoy muy familiarizado con el diseño de Java Swing y no parece fácil de usar. Para lograr los efectos de diseño anteriores, puede utilizar el anidamiento de diseños.

(1) En primer lugar, el grupo de botones (pueden ser varios botones), independientemente del ancho, se muestran en el centro, podemos pensar en FlowLayout.CENTER .

(2) Entonces, ¿cómo distribuir el grupo de botones en la parte inferior? Obviamente, podemos poner estos botones múltiples en un JPanel (se puede llamar: btnPanel), y luego usar BorderLayout.SOUTH para poner el panel en la parte inferior.

(3) Hay otro problema. Lo que queremos ver es que el grupo de botones parece estar flotando en el mapa del juego. Sin embargo, el panel del btnPanel donde se coloca el grupo de botones es gris, lo que oscurecerá el mapa del juego. Luego, podemos configurar el fondo del panel en transparente a través de setOpaque (falso), de modo que solo se muestre el botón y el fondo sea transparente.

A continuación, proporcione el código específico

// 布局嵌套。BorderLayout.SOUTH和FlowLayout.CENTER)实现按钮组底部居中
// 游戏面板的布局
this.setLayout(new BorderLayout()); 

// 按钮组面板
JPanel btnPanel = new JPanel();
btnPanel.setOpaque(false);	// 将面板设置为透明,否则灰色面板会遮挡地图
btnPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
bgmBtn = new JButton("开启BGM");
runBtn = new JButton("暂停游戏");
overBtn = new JButton("结束游戏");
btnPanel.add(bgmBtn);
btnPanel.add(runBtn);
btnPanel.add(overBtn);

// 将按钮组面板,放置到游戏面板的南部
this.add(btnPanel, BorderLayout.SOUTH);

Pregunta 2

Después de la prueba, hay dos soluciones.

(1) Al reescribir el método paint (), agregue super.paintChildren (g) al final para reescribir el componente.

(2) No reescriba el método paint (), sino que reescriba directamente el método paintComponent ()

A continuación tengo la primera (1) solución, dé el código

        /**
	 * 重写绘画方法。绘画时是有固定的顺序,先绘画的图片会在底层,后绘画的图片会覆盖先绘画的
	 * 约定:本方法只执行一次,想实时刷新需要使用多线程
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);

        /*
        // 自己的代码......
		// 所有元素的显示
		Map<GameElement, List<ElementObj>> all = em.getGameElements();
		// GameElement.values()是隐藏方法,无法点进去
		// 返回的数组的顺序时是枚举变量声明时的顺序
		for (GameElement ge : GameElement.values()) {
			List<ElementObj> list = all.get(ge);
//			if(ge.equals(GameElement.MAPS)) {
			if(ge == GameElement.MAPS) {
//				Collections.sort(list);
//			}
			for (int i = 0; i < list.size(); i++) {
				ElementObj obj = list.get(i);
				obj.showElement(g);
			}
		}
        */
		
		// !!!重新绘制子组件,否则paint之后会遮挡住组件!!!
		super.paintChildren(g);
			
	}

Pregunta 3

Obviamente, la monitorización del teclado se utiliza para manipular a los personajes del juego. Luego, durante el juego, si hago clic en el botón inferior, ¿por qué falla el monitor del teclado?

Debido a que nuestro monitoreo de teclado funciona en el formulario (JFrame), cuando se hace clic en el botón inferior, el formulario pierde el foco y el foco recae en el botón. Entonces el teclado fallará. Entonces, solo necesita requestFocus () para permitir que el formulario recupere el enfoque.

¿Cómo funciona el código? En el evento click del botón, después de completar toda la lógica del evento click, obtenga el objeto de instancia del formulario actual y llame a su requestFocus () para que recupere el foco.

El código es relativamente simple, no publicaré el código en mi proyecto.

Supongo que te gusta

Origin blog.csdn.net/qq_43290318/article/details/107612241
Recomendado
Clasificación