2014-02-18 47 views
1

我正在做一个Simon说游戏,当我在KeyListener pressed的pressed()方法中调用randomColorChange()方法时,它保持winow关闭。 randomColorChange()方法随机更改颜色。该方法完成后,我想的keyPressed()方法,以点亮键:方法保持窗口关闭

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()方法在所有的不工作,我不能关闭窗口

这里是全班同学:

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

} 
+0

它是冷冻和反应迟钝?您的代码中可能存在无限循环。 – Ring

回答

5

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

另外:

  • 你应该避免使用与Swing应用程序KeyListeners的,而是应该有利于键绑定。
  • 您应该覆盖JPanel的paintComponent(Graphics g)方法,而不是直接在JFrame中或覆盖其paint(Graphics g)方法。这将有助于防止你的颜色闪烁,因为他们正在做。
  • 务必确保在油漆覆盖中调用超级油漆方法。例如,当覆盖JPanel的paintComponent(Graphics g)方法时,一定要在开始时调用super.paintComponent(g)方法,以便您的组件可以首先进行图形处理。
  • 您将需要设置您的Graphics2D的RenderingHints以允许消除锯齿来平滑图形。

例如:

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

其中显示为:

enter image description here