【スイング】JPanelがpaint()を書き換えた後、ボタンがブロックされ、ボタンをクリックするとキーボードの監視に失敗します

エフェクト画像

コンテンツの説明

上の写真は私たちのチームが作ったバブルホールです。プロジェクトの最後に、ゲームインターフェイスの下部にあるスクリーンショットに3つのボタンを追加し、いくつかの関数(関数メンバー)を実装するという小さなタスクを実行しました。いくつかのボタンのいくつかはすでに実現されていますはい、私はそれらのメソッドを呼び出す必要があります)。次に、発生した問題を抽出してブログに記録します。一部の学生はこれらの問題に遭遇すると思います。

1.パネルの下部中央にボタングループをより適切に配置するにはどうすればよいですか?そして、それは地図の上に浮かんでいるように見えます。

2. paint()メソッドがパネルで上書きされるため、ボタングループがブロックされます。ただし、マウスを上に動かすと、ボタングループが再び表示されます。

3.下部のボタンをクリックすると、キーボードの監視が無効になります。キーボードを押すと、ゲーム内のキャラクターを操作できなくなります。

質問1

実際、私はJava Swingのレイアウトにあまり詳しくなく、使いにくいと感じています。上記のレイアウト効果を実現するには、レイアウトのネストを使用できます。

(1)まず、幅に関係なく、ボタングループ(複数のボタンにすることができます)が中央に表示されます。FlowLayout.CENTERを考えることができます

(2)では、ボタングループを一番下に配置するにはどうすればよいですか?明らかに、これらの複数のボタンをJPanel(名前はbtnPanel)に配置し、BorderLayout.SOUTHを使用してパネルを下部に配置できます。

(3)別の問題があります。私たちが見たいのは、ボタングループがゲームマップ上に浮かんでいるように見えることです。ただし、ボタングループが配置されているbtnPanelのパネルは灰色であるため、ゲームマップが不明瞭になります。次に、setOpaque(false)を使用してパネルの背景を透明に設定し、ボタンのみが表示され、背景が透明になるようにします。

以下に、特定のコードを示します

// 布局嵌套。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);

質問2

テスト後、2つの解決策があります。

(1)paint()メソッドを書き換える場合は、最後にsuper.paintChildren(g)を追加してコンポーネントを書き換えます。

(2)paint()メソッドを書き直すのではなく、paintComponent()メソッドを直接書き直します。

以下に最初の(1)ソリューションがあります、コードを与えます

        /**
	 * 重写绘画方法。绘画时是有固定的顺序,先绘画的图片会在底层,后绘画的图片会覆盖先绘画的
	 * 约定:本方法只执行一次,想实时刷新需要使用多线程
	 */
	@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);
			
	}

質問3

明らかに、キーボード監視はゲーム内のキャラクターを操作するために使用されます。次に、ゲーム中に下のボタンをクリックすると、キーボードモニターが失敗するのはなぜですか?

キーボードモニタリングはフォーム(JFrame)で機能するため、下のボタンをクリックすると、フォームはフォーカスを失い、フォーカスはボタンに落ちます。したがって、キーボードは失敗します。したがって、フォームがフォーカスを取り戻すには、requestFocus()のみが必要です。

コードはどのように機能しますか?ボタンのクリックイベントで、クリックイベントのすべてのロジックを完了した後、現在のフォームのインスタンスオブジェクトを取得し、そのrequestFocus()を呼び出して、フォーカスを取り戻します。

コードは比較的単純なので、プロジェクトにコードを投稿しません。

おすすめ

転載: blog.csdn.net/qq_43290318/article/details/107612241