首页 文章

如何使用JFrame设置“当前”窗口?

提问于
浏览
1

我不知道怎么说这个,但我有一个基于箭头键的游戏 . 无论如何有一个选项菜单,但在我选择选项后,当我尝试按箭头键并移动没有任何反应...我假设它是因为我“活跃”在另一个现在隐藏的JFrame(选项菜单)而不是游戏画面 .

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

虽然我在这里,但我正试图弄清楚如何使游戏窗口全屏显示 . 现在我有setUndecorated所以没有边框,我尝试了代码:setExtendedState(JFrame.MAXIMIZED_BOTH);但是游戏转移到了屏幕的右下方 . 我现在是外接显示器,这有关系吗?我也有不可调整大小的格式(我在netbeans上),我有Jframe和Jpanels的“设置”大小,我应该删除它们吗?

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

*全部都是netbeans .

1 回答

  • 0

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

    但是还有一个更大的问题,那就是你开始使用KeyListeners时,通常应该避免使用Swing应用程序 . 而是使用Key Bindings,这是一个更高级别的概念,因此应该用于支持低级KeyListeners .

    另外,为了最大化JFrame,您可以将Frame.MAXIMIZED_BOTH作为参数传递给您正在执行的参数 . 你在打电话 pack() 吗?另外,你不是在JFrame上调用 setLocation(...)setBounds(...)setSize(...) ,对吗?

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

    Edit
    我建议的代码示例:

    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;
          }
       }
    }
    

相关问题