方法使窗口不关闭 [英] Method keeps window from closing

查看:108
本文介绍了方法使窗口不关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个Simon说的游戏,当我在KeyListener的按()方法中调用randomColorChange()方法时,它会让winow不会关闭。 randomColorChange()方法随机更改颜色。方法完成后,我希望keyPressed()方法点亮键:

Im making a Simon Says game and when I call the randomColorChange() method in the KeyListener pressed() method, it keeps the winow from closing. The randomColorChange() method changes colors randomly. After the method is finished, I want the keyPressed() method to light up the keys:

public void randomColorChange(){

decrement = simonIncrease;


    try{
        int random;
        for (int i = 0; i < simonIncrease; i++)
        {
            random = (int) (Math.random() * 4);

            Thread.sleep(lightUpSpd);

            if (random == 0)
            {
                green = green.brighter();
                repaint();
                Thread.sleep(lightUpSpd);
                green= green.darker();
                repaint();
            }

            if (random == 1)
            {
                red = red.brighter();
                repaint();
                Thread.sleep(lightUpSpd);
                red = red.darker();
                repaint();
            }

            if (random == 2)
            {
                blue = blue.brighter();
                repaint();
                Thread.sleep(lightUpSpd);
                blue = blue.darker();
                repaint();
            }

            if (random == 3)
            {
                yellow = yellow.brighter();
                repaint();
                Thread.sleep(lightUpSpd);
                yellow = yellow.darker();
                repaint();

            }

        }
    }
        catch (InterruptedException e){
            e.printStackTrace();
        }


}



public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub  

    if (e.getKeyCode() == KeyEvent.VK_DOWN)
    {
        blue = blue.brighter();
        repaint();

    }
    if (e.getKeyCode() == KeyEvent.VK_LEFT)
    {
        red = red.brighter();
        repaint();
    }
    if (e.getKeyCode() == KeyEvent.VK_UP)
    {
        green = green.brighter();
        repaint();
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT)
    {
        yellow = yellow.brighter();
        repaint();

    }

    decrement--;

    if (decrement == 0)
    {
        simonIncrease++;
        randomColorChange();
        decrement = simonIncrease;
    }   

}

问题在于细分市场将会点亮,但是当我在simonIncrease ++之后添加randomColorChange()方法时,该程序根本无法工作,我无法关闭窗口

The problem is that the segments will light up, but when I add the randomColorChange() method after simonIncrease++, the program doesn't work at all and I can't close the window

这是全班:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Arc2D;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class SimonShape extends JFrame implements KeyListener {

   private int width;
   private int height;
   private int x;
   private int y;
   private int TURN = 45;
   private int simonIncrease = 1;
   private int lightUpSpd = 1000;
   private int decrement = simonIncrease;

   private Color blue = Color.BLUE.darker();
   private Color red = Color.RED.darker();
   private Color yellow = Color.YELLOW.darker();
   private Color green = Color.GREEN.darker();

   public SimonShape(int width, int height, int x, int y) {

      this.width = width;
      this.height = height;
      this.x = x;
      this.y = y;

      JLabel label = new JLabel();

      setSize(800, 800);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLocationRelativeTo(null);
      setVisible(true);

      label.addKeyListener(this);
      label.setFocusable(true);
      label.setOpaque(true);
      label.addKeyListener(this);
      this.add(label);
      setVisible(true);
      label.requestFocusInWindow();

      randomColorChange();

   }

   public void randomColorChange() {

      decrement = simonIncrease;

      try {
         int random;
         for (int i = 0; i < simonIncrease; i++) {
            random = (int) (Math.random() * 4);

            Thread.sleep(lightUpSpd);

            if (random == 0) {
               green = green.brighter();
               repaint();
               Thread.sleep(lightUpSpd);
               green = green.darker();
               repaint();
            }

            if (random == 1) {
               red = red.brighter();
               repaint();
               Thread.sleep(lightUpSpd);
               red = red.darker();
               repaint();
            }

            if (random == 2) {
               blue = blue.brighter();
               repaint();
               Thread.sleep(lightUpSpd);
               blue = blue.darker();
               repaint();
            }

            if (random == 3) {
               yellow = yellow.brighter();
               repaint();
               Thread.sleep(lightUpSpd);
               yellow = yellow.darker();
               repaint();

            }

         }
      } catch (InterruptedException e) {
         e.printStackTrace();
      }

   }

   public void keyPressed(KeyEvent e) {
      // TODO Auto-generated method stub

      if (e.getKeyCode() == KeyEvent.VK_DOWN) {
         blue = blue.brighter();
         repaint();

      }
      if (e.getKeyCode() == KeyEvent.VK_LEFT) {
         red = red.brighter();
         repaint();
      }
      if (e.getKeyCode() == KeyEvent.VK_UP) {
         green = green.brighter();
         repaint();
      }
      if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
         yellow = yellow.brighter();
         repaint();

      }

      decrement--;

      if (decrement == 0) {
         simonIncrease++;
         randomColorChange();
         decrement = simonIncrease;
      }

   }

   public void keyReleased(KeyEvent e) {

      if (e.getKeyCode() == KeyEvent.VK_UP) {
         green = green.darker();
         repaint();
      }

      if (e.getKeyCode() == KeyEvent.VK_DOWN) {
         blue = blue.darker();
         repaint();
      }

      if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
         yellow = yellow.darker();
         repaint();
      }

      if (e.getKeyCode() == KeyEvent.VK_LEFT) {
         red = red.darker();
         repaint();
      }

   }

   public void keyTyped(KeyEvent e) {
   }

   public void paint(Graphics g) {

      Graphics2D g2 = (Graphics2D) g;

      // Blue Section
      g2.setStroke(new BasicStroke(2.0f));
      g2.setPaint(blue);
      g2.fill(new Arc2D.Double(x, y, width, height, 180 + TURN, 90, Arc2D.PIE));

      // Red Section
      g2.setStroke(new BasicStroke(2.0f));
      g2.setPaint(red);
      g2.fill(new Arc2D.Double(x, y, width, height, 90 + TURN, 90, Arc2D.PIE));

      // Yellow Section
      g2.setStroke(new BasicStroke(2.0f));
      g2.setPaint(yellow);
      g2.fill(new Arc2D.Double(x, y, width, height, -90 + TURN, 90, Arc2D.PIE));

      // Green Section
      g2.setStroke(new BasicStroke(2.0f));
      g2.setPaint(green);
      g2.fill(new Arc2D.Double(x, y, width, height, 360 + TURN, 90, Arc2D.PIE));

   }
}

测试类:

public class SimonTest  {

public static void main(String[] args)
{
    new SimonShape(500,500,150,150);
}

}


推荐答案

您正在Swing事件线程上调用 Thread.sleep(...),该线程将睡眠或锁定整个GUI。不要这样做。请改用Swing Timer。

You're calling Thread.sleep(...) on the Swing event thread which will sleep or lock the entire GUI. Don't do this. Use a Swing Timer instead.

  • Swing Timer Tutorial.

另外:


  • 你应该避免在Swing应用程序中使用KeyListeners,而应该使用Key Bindings。

  • 你应该在JPanel的<$ c的覆盖中绘画$ c> paintComponent(Graphics g)方法,而不是直接在JFrame中或覆盖其 paint(Graphics g)方法。这有助于防止您的颜色在闪烁时闪烁。

  • 务必在油漆覆盖中调用超级油漆方法。例如,当覆盖JPanel的 paintComponent(Graphics g)方法时,请务必调用 super.paintComponent(g)方法一开始,所以你的组件可以先保留图形内容。

  • 你需要设置Graphics2D的RenderingHints以允许消除锯齿以平滑你的图形。

  • You should avoid use of KeyListeners with Swing applications but instead should favor Key Bindings.
  • You should paint in the override of a JPanel's paintComponent(Graphics g) method and not directly in the JFrame or in an override of its paint(Graphics g) method. This will help prevent your colors from flickering as they're doing.
  • Always be sure to call the super paint method in your paint override. For example when overriding the JPanel's paintComponent(Graphics g) method, be sure to call the super.paintComponent(g) method at the start, so your component can do its graphic house keeping first.
  • You will want to set your Graphics2D's RenderingHints to allow for anti-aliasing to smooth out your graphics.

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Arc2D;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.swing.*;

/**
 * link: http://stackoverflow.com/questions/21867283/method-keeps-window-from-
 * closing
 * 
 * @author Pete
 * 
 */
@SuppressWarnings("serial")
public class SimonPanelTest extends JPanel {
    private static final String PRESSED = "pressed";
    private static final String RELEASED = "released";
    private static final int TIMER_DELAY = 1000;
    private static final int TIME_SLICES = 8;
    private Random random = new Random();
    private SimonPanel simonPanel = new SimonPanel();

    public SimonPanelTest() {
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(new JButton(new ShowRandomPatternAction()));

        setLayout(new BorderLayout());
        add(simonPanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);

        setKeyBindings(simonPanel, KeyEvent.VK_UP, MyColor.GREEN);
        setKeyBindings(simonPanel, KeyEvent.VK_RIGHT, MyColor.YELLOW);
        setKeyBindings(simonPanel, KeyEvent.VK_DOWN, MyColor.BLUE);
        setKeyBindings(simonPanel, KeyEvent.VK_LEFT, MyColor.RED);

        simonPanel.addPropertyChangeListener(SimonPanel.MY_COLOR, pce -> {
            System.out.println(pce.getNewValue());
        });
    }

    private void setKeyBindings(SimonPanel panel, int keyCode, MyColor myColor) {
        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        InputMap inMap = panel.getInputMap(condition);
        ActionMap actMap = panel.getActionMap();

        KeyStroke keyPressed = KeyStroke.getKeyStroke(keyCode, 0, false);
        KeyStroke keyReleased = KeyStroke.getKeyStroke(keyCode, 0, true);

        inMap.put(keyPressed, myColor.toString() + PRESSED);
        inMap.put(keyReleased, myColor.toString() + RELEASED);

        actMap.put(myColor.toString() + PRESSED, new MyKeyAction(panel, myColor, true));
        actMap.put(myColor.toString() + RELEASED, new MyKeyAction(panel, myColor, false));
    }

    private class ShowRandomPatternAction extends AbstractAction {
        private static final int MIN_RANDOM_COLORS = 5;
        private static final int MAX_RANDOM_COLORS = 10;

        public ShowRandomPatternAction() {
            super("Show Random Pattern");
            putValue(MNEMONIC_KEY, KeyEvent.VK_S);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            List<MyColor> colorList = new ArrayList<MyColor>();
            for (int i = 0; i < random.nextInt(MAX_RANDOM_COLORS - MIN_RANDOM_COLORS)
                    + MIN_RANDOM_COLORS; i++) {
                int colorIndex = random.nextInt(MyColor.values().length);
                MyColor myColor = MyColor.values()[colorIndex];
                colorList.add(myColor);
            }

            ActionListener timerListener = new TimerListener(simonPanel, colorList);
            Timer timer = new Timer(TIMER_DELAY / TIME_SLICES, timerListener);
            timer.start();
        }
    }

    private class TimerListener implements ActionListener {
        @SuppressWarnings("hiding")
        private SimonPanel simonPanel;
        private int colorListIndex = 0;
        private int sliceCount = 0;
        private List<MyColor> myColorList;
        private int maxCount;

        public TimerListener(SimonPanel simonPanel, List<MyColor> myColorList) {

            this.simonPanel = simonPanel;
            this.myColorList = myColorList;
            maxCount = myColorList.size();
        }

        @Override
        public void actionPerformed(ActionEvent evt) {
            if (colorListIndex == maxCount) {
                for (MyColor myColor : MyColor.values()) {
                    simonPanel.setMyColorPressed(myColor, false);
                }
                ((Timer) evt.getSource()).stop();
                return;
            }

            if (sliceCount == 0) {
                MyColor myColor = myColorList.get(colorListIndex);
                simonPanel.setMyColorPressed(myColor, true);
                sliceCount++;
            } else if (sliceCount < TIME_SLICES - 1) {
                sliceCount++;
                return;
            } else if (sliceCount == TIME_SLICES - 1) {
                sliceCount = 0;
                MyColor myColor = myColorList.get(colorListIndex);
                simonPanel.setMyColorPressed(myColor, false);
                colorListIndex++;
                return;
            }
        }
    }

    private class MyKeyAction extends AbstractAction {
        private SimonPanel panel;
        private MyColor myColor;
        private boolean pressed;

        public MyKeyAction(SimonPanel panel, MyColor myColor, boolean pressed) {
            this.panel = panel;
            this.myColor = myColor;
            this.pressed = pressed;
        }

        @Override
        public void actionPerformed(ActionEvent evt) {
            panel.setMyColorPressed(myColor, pressed);
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Simon Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new SimonPanelTest());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

@SuppressWarnings("serial")
class SimonPanel extends JPanel {
    public static final String MY_COLOR = "my color";
    private static final int PREF_W = 600;
    private static final int PREF_H = PREF_W;
    private static final int ARC_ANGLE = 90;
    private Map<MyColor, MyArc> colorPressedMap = new EnumMap<MyColor, MyArc>(MyColor.class);
    private List<MyArc> myArcs = new ArrayList<>();

    public SimonPanel() {
        int i = 0;
        for (MyColor myColor : MyColor.values()) {
            int startAngle = 45 - i * 90;
            Arc2D arc = new Arc2D.Double(0, 0, PREF_W, PREF_H, startAngle, ARC_ANGLE, Arc2D.PIE);
            MyArc myArc = new MyArc(arc, myColor);
            myArcs.add(myArc);
            colorPressedMap.put(myColor, myArc);
            i++;
        }
        addMouseListener(new MyMouse());
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(PREF_W, PREF_H);
    }

    public void setMyColorPressed(MyColor myColor, boolean pressed) {
        colorPressedMap.get(myColor).setSelected(pressed);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        for (MyColor myColor : MyColor.values()) {
            colorPressedMap.get(myColor).fill(g2);
        }
    }

    private class MyMouse extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            for (MyArc myArc : myArcs) {
                if (myArc.contains(e.getPoint())) {
                    myArc.setSelected(true);
                    firePropertyChange(MY_COLOR, null, myArc.getMyColor());
                    repaint();
                }
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            for (MyArc myArc : myArcs) {
                myArc.setSelected(false);
            }
            repaint();
        }
    }
}

class MyArc {
    private Arc2D arc;
    private MyColor myColor;
    private boolean selected;

    public MyArc(Arc2D arc, MyColor myColor) {
        this.arc = arc;
        this.myColor = myColor;
    }

    public boolean contains(Point p) {
        return arc.contains(p);
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public Arc2D getArc() {
        return arc;
    }

    public MyColor getMyColor() {
        return myColor;
    }

    public Color getColor() {
        return selected ? myColor.getBrightColor() : myColor.getDarkColor();
    }

    public void fill(Graphics2D g2) {
        Color oldColor = g2.getColor();
        g2.setColor(getColor());
        g2.fill(arc);
        g2.setColor(oldColor);
    }

}

enum MyColor {
    GREEN(Color.green.brighter(), Color.green.darker()), 
    YELLOW(Color.yellow.brighter(), Color.yellow.darker()), 
    BLUE(Color.blue.brighter(), Color.blue.darker()), 
    RED(Color.red.brighter(), Color.red.darker());

    private MyColor(Color brightColor, Color darkColor) {
        this.brightColor = brightColor;
        this.darkColor = darkColor;
    }

    private Color brightColor;
    private Color darkColor;

    public Color getBrightColor() {
        return brightColor;
    }

    public Color getDarkColor() {
        return darkColor;
    }
}






显示为:


Which displays as:

这篇关于方法使窗口不关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆