java - 如何使用 JFrames 设置 "current"窗口?

标签 java netbeans

我不知道如何真正表达这一点,但我有一个基于箭头键的游戏。 无论如何,有一个选项菜单,但是当我选择选项后,当我尝试按箭头键并移动时,什么也没有发生...... 我假设这是因为我在另一个现在隐藏的 JFrame(选项菜单)而不是游戏屏幕中“Activity ”。

有没有办法让程序知道我希望键盘操作在关闭选项菜单时引用回原始 JFrame?

当我这样做时,我正在尝试弄清楚如何使游戏窗口全屏显示。现在我已经设置了 setUndecorated 所以没有边框,我尝试了代码: setExtendedState(JFrame.MAXIMIZED_BOTH);但游戏已经转移到了屏幕的右下角。 我现在是外接显示器,这有关系吗? 我还检查了不可调整大小(我在 netbeans 上),并且我为 Jframe 和 Jpanels 设置了“设置”大小,我应该删除它们吗?

我希望这是有道理的, 谢谢, -奥斯汀

*也全部在 netbeans 中。

最佳答案

我假设您正在使用 KeyListener 来捕获击键,如果是这样,则 KeyListener 仅在正在监听的组件具有焦点时才起作用。您的问题是,在交换 View 时,您收听的组件没有焦点。解决此问题的一种方法是在交换后在监听组件上调用 requestFocusInWindow()

但是还有一个更大的问题正在出现,那就是您对 KeyListener 的使用,这在 Swing 应用程序中通常应该避免。相反,请使用按键绑定(bind),这是一种更高级别的概念,因此应该用于支持低级别的 KeyListener。

此外,要最大化 JFrame,您需要调用它的 setExtendedState(...) 方法,并传入 Frame.MAXIMIZED_BOTH 作为参数,就像您正在做的那样。您正在调用 pack() 吗?此外,您没有在JFrame,对吗?

编辑:我发现您实际上在 JFrame 上调用了 setSize(...) 。是的,删除它,因为如果您最大化 JFrame,它就没有意义。

编辑
我建议的代码示例:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.TitledBorder;

public class AnimationWithKeyBinding {
   @SuppressWarnings("serial")
   private static void createAndShowUI() {

      final JPanel cardPanel = new JPanel(new CardLayout()); 
      MenuPanel menuPanel = new MenuPanel();
      AnimationPanel animationPanel = new AnimationPanel();

      cardPanel.add(menuPanel, "Menu");
      cardPanel.add(animationPanel, "Animation");

      menuPanel.setNextBtnAction(new AbstractAction("Next") {
         {
            putValue(NAME, "Next");
            putValue(MNEMONIC_KEY, KeyEvent.VK_N);
         }
         @Override
         public void actionPerformed(ActionEvent arg0) {
            ((CardLayout)cardPanel.getLayout()).next(cardPanel);
         }
      });

      JFrame frame = new JFrame("Animation With Key Binding");
      frame.getContentPane().add(cardPanel);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

@SuppressWarnings("serial")
class MenuPanel extends JPanel {
   private JButton nextBtn = new JButton();

   public MenuPanel() {
      TitledBorder titledBorder = BorderFactory.createTitledBorder("Menu Panel");
      titledBorder.setTitleFont(titledBorder.getTitleFont().deriveFont(Font.BOLD, 24));
      setBorder(titledBorder);
      setLayout(new GridBagLayout());
      add(nextBtn);
   }

   public void setNextBtnAction(Action action) {
      nextBtn.setAction(action);
   }
}

@SuppressWarnings("serial")
class AnimationPanel extends JPanel {
   public static final int SPRITE_WIDTH = 20;
   public static final int PANEL_WIDTH = 400;
   public static final int PANEL_HEIGHT = 400;
   private static final int MAX_MSTATE = 25;
   private static final int SPIN_TIMER_PERIOD = 16;
   private static final int SPRITE_STEP = 3;

   private int mState = 0;
   private int mX = (PANEL_WIDTH - SPRITE_WIDTH) / 2;
   private int mY = (PANEL_HEIGHT - SPRITE_WIDTH) / 2;
   private int oldMX = mX;
   private int oldMY = mY;
   private boolean moved = false;

   // an array of sprite images that are drawn sequentially
   private BufferedImage[] spriteImages = new BufferedImage[MAX_MSTATE];

   public AnimationPanel() {
      // create and start the main animation timer
      new Timer(SPIN_TIMER_PERIOD, new SpinTimerListener()).start();
      setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
      setBackground(Color.white);
      createSprites(); // create the images
      setupKeyBinding();
   }

   private void setupKeyBinding() {
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inMap = getInputMap(condition);
      ActionMap actMap = getActionMap();

      // this uses an enum of Direction that holds ints for the arrow keys
      for (Direction direction : Direction.values()) {
         int key = direction.getKey();
         String name = direction.name();

         // add the key bindings for arrow key and shift-arrow key
         inMap.put(KeyStroke.getKeyStroke(key, 0), name);
         inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK),
               name);
         actMap.put(name, new MyKeyAction(this, direction));
      }
   }

   // create a bunch of buffered images and place into an array,
   // to be displayed sequentially
   private void createSprites() {
      for (int i = 0; i < spriteImages.length; i++) {
         spriteImages[i] = new BufferedImage(SPRITE_WIDTH, SPRITE_WIDTH,
               BufferedImage.TYPE_INT_ARGB);
         Graphics2D g2 = spriteImages[i].createGraphics();
         g2.setColor(Color.red);
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
         double theta = i * Math.PI / (2 * spriteImages.length);
         double x = SPRITE_WIDTH * Math.abs(Math.cos(theta)) / 2.0;
         double y = SPRITE_WIDTH * Math.abs(Math.sin(theta)) / 2.0;
         int x1 = (int) ((SPRITE_WIDTH / 2.0) - x);
         int y1 = (int) ((SPRITE_WIDTH / 2.0) - y);
         int x2 = (int) ((SPRITE_WIDTH / 2.0) + x);
         int y2 = (int) ((SPRITE_WIDTH / 2.0) + y);
         g2.drawLine(x1, y1, x2, y2);
         g2.drawLine(y1, x2, y2, x1);
         g2.dispose();
      }
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(spriteImages[mState], mX, mY, null);
   }

   public void incrementX(boolean right) {
      oldMX = mX;
      if (right) {
         mX = Math.min(getWidth() - SPRITE_WIDTH, mX + SPRITE_STEP);
      } else {
         mX = Math.max(0, mX - SPRITE_STEP);
      }
      moved = true;
   }

   public void incrementY(boolean down) {
      oldMY = mY;
      if (down) {
         mY = Math.min(getHeight() - SPRITE_WIDTH, mY + SPRITE_STEP);
      } else {
         mY = Math.max(0, mY - SPRITE_STEP);
      }
      moved = true;
   }

   public void tick() {
      mState = (mState + 1) % MAX_MSTATE;
   }

   private class SpinTimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         tick();

         int delta = 20;
         int width = SPRITE_WIDTH + 2 * delta;
         int height = width;

         // make sure to erase the old image
         if (moved) {
            int x = oldMX - delta;
            int y = oldMY - delta;
            repaint(x, y, width, height);
         }

         int x = mX - delta;
         int y = mY - delta;

         // draw the new image
         repaint(x, y, width, height);
         moved = false;
      }
   }
}

enum Direction {
   UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN), LEFT(KeyEvent.VK_LEFT), RIGHT(
         KeyEvent.VK_RIGHT);

   private int key;

   private Direction(int key) {
      this.key = key;
   }

   public int getKey() {
      return key;
   }
}

// Actions for the key binding
@SuppressWarnings("serial")
class MyKeyAction extends AbstractAction {
   private AnimationPanel draw;
   private Direction direction;

   public MyKeyAction(AnimationPanel draw, Direction direction) {
      this.draw = draw;
      this.direction = direction;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      switch (direction) {
      case UP:
         draw.incrementY(false);
         break;
      case DOWN:
         draw.incrementY(true);
         break;
      case LEFT:
         draw.incrementX(false);
         break;
      case RIGHT:
         draw.incrementX(true);
         break;

      default:
         break;
      }
   }
}

关于java - 如何使用 JFrames 设置 "current"窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9855234/

相关文章:

java - 在 MVC 中测试 Facades |断言返回类型

java - 如何编写一个方法来读取数组列表中的特定内容并计算数组内容的数量

java - JavaFX Scene Builder 在 Linux 支持上可用吗?

java - Netbeans 在构建(编译)之前运行一个进程

java - 包 com.sun.org.apache.xml.internal.security.utils.Base64 不存在

java - 使用 BlazeDS 将 ActionScript/Flex ArrayCollection 将 Number 对象转换为 Java Collection<Long>

java - Android Studio 类名自动完成建议红色

FXML 中的 JavaFX MediaView

java - 如何使用 JPA (Java EE) 将 XML 数据结构映射到数据库

java - 在 Netbeans 7.3.1 中解析文件 JSP 或 JAVA 时出错