gpt4 book ai didi

java - 通过键盘在 JPanel 之间切换

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:25:58 25 4
gpt4 key购买 nike

我有一个带有多个面板的 JFrame 类,我通过使用 paintComponent(Graphics g) 方法绘制所有图形,因此使用 CardLayout 没有用。要切换框架,我只需点击一个按钮,例如 enter,但问题是当我切换面板时,paintCompenent 留下的图形仍然存在。我还尝试使用 panel.setVisible(false) 使面板可见,这有点帮助,除了我正在过渡到的面板即使在将可见设置为 true 之后仍然不可见。新面板的按钮和命令工作并转换回第一个面板,所以我知道转换正在工作,只是没有显示我想要的方式。这是 2 个交互面板的代码和处理它们的 JFrame 类:

//JFRAME CLASS
package main;

import gameStates.Instruction;
import gameStates.Menu;
import gameStates.State;

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class GameFrame extends JFrame implements KeyListener{

//panels for Game States in order:
static ArrayList<State> panels = new ArrayList<State>();//holds all of the game states that the game will eventually reach

private static int currentState=0;//STATES: 0 - Menu
//1 - Instruction
//2 - Level 1 and States 3 through 7 are the levels up one respectively up to level 6

public GameFrame() {
panels.add(new Menu(this));
panels.add(new Instruction(this));

addKeyListener(this);
setSize(640,480);
setPreferredSize(new Dimension(640,480));
setResizable(false);
setLocation(20,50);
setName("FBLA: A Success Story");
setDefaultCloseOperation(EXIT_ON_CLOSE);

add(panels.get(1));
add(panels.get(0));
panels.get(1).setVisible(false);
panels.get(0).setVisible(true);

pack();
setVisible(true);


}

@SuppressWarnings("unused")
public static void main(String[] args) {
GameFrame g = new GameFrame();
}


public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
System.exit(0);
else {
panels.get(currentState).buttons(e);
}
}
public void keyReleased(KeyEvent e) {
}

public void nextState(int state) {
panels.get(currentState).setVisible(false);
panels.get(state).setVisible(true);
currentState = state;
}

}
//////////////////////INITIAL PANEL//////////////////////////
package gameStates;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.Timer;

import main.GameFrame;

@SuppressWarnings("serial")
public class Menu extends State {

//general items
public BufferedImage bg;
public String[] options = new String[3];
public double x, y, velX, velY;
public int selected;
public Graphics2D g2;

//time stuff
Timer t = new Timer(5,this);

public Menu(GameFrame g) {
super(g);
setup();
}
public void setup() {
try {
bg = ImageIO.read(Menu.class.getResourceAsStream("/backgrounds/FBLAmenubg.gif"));
}
catch (Exception e) {
e.printStackTrace();
}

options[0] = "PLAY";
options[1] = "INSTRUCTIONS";
options[2] = "QUIT";
selected = 0;

x=y=velY=0;
velX=-.1;

t.start();
}

public void paintComponent(Graphics g) {
g2 = (Graphics2D)g;
g2.drawImage(bg, (int)x, (int)y, null);
g2.drawImage(bg, (int)x + 640, (int)y, null);
Font f = new Font("FreeSerif", Font.ROMAN_BASELINE, 48);
g2.setFont(f);
g2.setColor(Color.WHITE);
for(int j=0;j<3;j++){
if(selected == j)
g2.setColor(Color.RED);
g2.drawString(options[j], 120, 80 + j*48);
g2.setColor(Color.WHITE);
}

}

private void processSelection() {

if(selected == 2)
System.exit(0);
else if (selected == 1) {
parent.nextState(1);
}
else {

}
}

public void buttons(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
selected++;
if(selected == 3)
selected=0;
}
if(e.getKeyCode() == KeyEvent.VK_UP) {
selected--;
if(selected == -1)
selected=2;
}
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
processSelection();
}
}

public void actionPerformed(ActionEvent e) {
x += velX;
if(x<=-640)
x=0;;
repaint();
}

}

/////////////////////TRANSITION TO THIS PANEL////////////////////////////
package gameStates;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.Timer;

import main.GameFrame;

@SuppressWarnings("serial")
public class Instruction extends State{

public BufferedImage bg;
public Graphics2D g2;
public Timer t;

public Instruction(GameFrame g) {
super(g);
setup();
}


public void buttons(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE)
parent.nextState(0);
}

public void setup() {

try {
bg = ImageIO.read(Menu.class.getResourceAsStream("/backgrounds/Instructionsbg.gif"));
}
catch (Exception e) {
e.printStackTrace();
}

t = new Timer(5,this);
t.start();

}

public void actionPerformed(ActionEvent e) {
repaint();
}

public void paintComponent(Graphics g) {

g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
g2.fillRect(0,0,640,480);
g2.drawImage(bg,0,0,null);
Font f = new Font("FreeSerif", Font.ROMAN_BASELINE, 20);
g2.setFont(f);
g2.setColor(Color.RED);
g2.drawString("SPACE BAR to go back to menu.", 600, 400);

}

}

最佳答案

so there is no use in using a CardLayout.

这与自定义绘画无关。您应该能够使用 CardLayout(或者实际上,您想要的任何布局管理器)。

您永远不会调用 super.paintComponent,它负责为绘画准备 Graphics 上下文....

 // Should be protected...
// Should have @Override annotation
public void paintComponent(Graphics g) {
// super.paintComponent(g) goes here...
//...
}

public Graphics2D g2; 也让我感到害怕,你永远不应该维护对任何你没有明确创建自己的 Graphics 上下文的引用(并且没有 g.创建不算)

Swing 中的Graphics 上下文通常为附加到同一 native 对等体(或大多数情况下的窗口)的所有组件共享。这意味着,除非您清洁它,否则最后涂在上面的东西仍会存在。

这也意味着无论您之前绘制到 Graphics 上下文的任何内容都将被清除,因此我们通常不鼓励维护对 Graphics 的引用或绘制到它在正常的油漆周期之外。

看看Painting in AWT and Swing了解更多详情

您可能还会发现,随着时间的推移,您的 KeyListener 停止响应,甚至是随机停止响应。 KeyListener 有焦点问题,这使得它适合管理多个组件,您会发现 Key Bindings API更适合您的需求

关于java - 通过键盘在 JPanel 之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21396233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com