方法使窗口不关闭

我正在制作一个Simon说的游戏,当我在KeyListener的按()方法中调用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()方法时,程序根本无法工作,我无法关闭窗口

这是全class:

 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。

  • Swing Timer教程 。

也:

  • 您应该避免将KeyListeners与Swing应用程序一起使用,而应该使用Key Bindings。
  • 您应该在JPanel的paintComponent(Graphics g)方法的覆盖中paint(Graphics g)而不是直接在JFrame中或在其paint(Graphics g)方法的覆盖中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 colorList = new ArrayList(); 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 myColorList; private int maxCount; public TimerListener(SimonPanel simonPanel, List 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 colorPressedMap = new EnumMap(MyColor.class); private List 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; } } 

显示为:

在此处输入图像描述