我正在制作一个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()方法时,程序根本无法工作,我无法关闭窗口
以下是全班:
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 :(得分:5)
您正在Swing事件线程上调用Thread.sleep(...)
,该线程将睡眠或锁定整个GUI。不要这样做。请改用Swing Timer。
此外:
paintComponent(Graphics g)
方法的覆盖中绘制,而不是直接在JFrame中或在其paint(Graphics g)
方法的覆盖中绘制。这有助于防止你的颜色在他们正在做的时候闪烁。paintComponent(Graphics g)
方法时,请务必在开始时调用super.paintComponent(g)
方法,以便您的组件可以先保留其图形内容。例如:
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;
}
}
显示为: