gpt4 book ai didi

Java Button 暂停图形更新

转载 作者:行者123 更新时间:2023-11-30 08:44:33 25 4
gpt4 key购买 nike

所以我有一门课,我必须制作一个程序来制作西蒙。我知道我这样做的方式不一定是最好的方式,但是,他有一些模糊的要求,所以这就是我这样做的原因。

我的程序即将完成,但我有一个主要问题。当我按下重置按钮时,我调用了一个名为重置的方法,该方法又将计算机设置为下他们的第一步。

在此期间,有图形更新。

当我自己调用重置方法时,它按预期工作 当我按下重置按钮时,它会在完成之前执行所有图形更新。有没有办法让方法在按下按钮后运行?

我的主程序

package game;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import components.*;


@SuppressWarnings("serial")
public class Simonish extends JFrame implements ActionListener, MouseListener {


private Color[][] ColorSwatch = {{Color.RED,Color.PINK},{Color.GREEN,Color.YELLOW}};
private int width = 2;
private int height = 2;
private int panSize = 200;
private SPane[][] panBoard;
private int[] Sequence;
private int CurrentSequenceLeingth = 0;
private int SequenceLeingth = 10000;
private Random r = new Random();
boolean LastButtonClicked = false;
private int LastButtonPressed = 0;
private int sequencePart = 0;
private boolean turn = false; //f=computer t=player
Container pane;
JPanel boardPanel;
ScoreBoard scorePanel;
private Simonish(){

scorePanel = new ScoreBoard(0,width,panSize);
scorePanel.getResetBtn().addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
resetGame();
}
});
this.setTitle("Simonish");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
pane = this.getContentPane();
pane.setLayout(null);
resetGame();
}

private void play(){
if(!turn)
ComputerTurn();
else
PlayerTurn();
}

private void ComputerTurn(){
CurrentSequenceLeingth++;
scorePanel.AddScore(1);
PlaySequenc();
turn = true;
}

private void PlayerTurn(){
if((LastButtonPressed == Sequence[sequencePart]))
{
sequencePart++;
LastButtonClicked = false;
}else
{
loose();
return;
}
if(sequencePart >= CurrentSequenceLeingth)
{
sequencePart = 0;
turn = false;
play();
}
}

private void loose(){
System.out.println("you loose");
resetGame();
}

private void PlaySequenc(){
for(int i = 0 ; i < CurrentSequenceLeingth ; i++)
{
panBoard[Sequence[i]/2][Sequence[i]%2].pressPane();
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}

private void resetGame() {
pane.removeAll();
pane.setPreferredSize(new Dimension(width*panSize, (height) * panSize + 75));
pane.add(scorePanel);
initPanes();
LastButtonClicked = false;
LastButtonPressed = 0;
initBtns();
turn = false;
CurrentSequenceLeingth = 3;
Sequence = new int[SequenceLeingth];
initSeq();
pane.update(pane.getGraphics());
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);

play();

}
private void initSeq() {

for(int i = 0 ; i < SequenceLeingth ; i++)
{
Sequence[i] = r.nextInt(4);

}

}

private void initBtns() {
this.panBoard = new SPane[width][height];

for(int w = 0; w < width; w++) {
for(int h = 0; h < height; h++) {
panBoard[w][h] = new SPane(w, h, panSize,ColorSwatch[w][h]);
panBoard[w][h].addMouseListener(this);
pane.add(panBoard[w][h]);
pane.addMouseListener(this);
}
}
}
public static void main(String[] args){
new Simonish();
}


private void initPanes() {
//TODO
}


@Override
public void actionPerformed(ActionEvent e) {
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent e) {
}

@Override
public void mouseReleased(MouseEvent e) {
}
}

记分牌类

package components;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;

@SuppressWarnings({ "serial", "unused" })
public class ScoreBoard extends JPanel {
private int score;
private JLabel SimonNumberLabel;
private JLabel timerLabel;
private JButton resetBtn;


public ScoreBoard(int bombsCnt,int w,int w2) {
score = bombsCnt;
SimonNumberLabel = new JLabel("Sequence Leingth: " + Integer.toString(bombsCnt), SwingConstants.CENTER);
resetBtn = new JButton("reset");

setBounds(0, 0, w*w2, 3*25);

this.setLayout(new GridLayout(1,3));

add(SimonNumberLabel);
add(resetBtn);
}

public void AddScore(int update) {
score += update;
SimonNumberLabel.setText("Sequence Leingth: " + Integer.toString(score));
}


public JButton getResetBtn() {
return resetBtn;
}
}

SPAne 类

package components;

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

@SuppressWarnings("serial")
public class SPane extends JPanel{

Color C;
Color DC;
int x;
int y;
public SPane(int x, int y, int size, Color colorSwatch) {
this();
this.x = x;
this.y = y;
this.setLayout(new GridLayout(x+1,y+1));
this.setBounds(x*size, y*size+75, size, size);
C = colorSwatch;
DC = C;
DC = DC.darker();
this.setBackground(DC);
this.setVisible(true);
}


public SPane() {
this.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
}

public void resetSPane() {
// TODO Auto-generated method stub

}

public void pressPane()
{
this.setBackground(C);
System.out.println("dsfdsfsdfsdf");
try{
Thread.sleep(1000);
}catch (Exception e) {}
this.setBackground(DC);
}

public void clicked() {
this.setBackground(Color.GREEN);
}
}

最佳答案

这是第一个罪魁祸首......

private void PlaySequenc(){
for(int i = 0 ; i < CurrentSequenceLeingth ; i++)
{
panBoard[Sequence[i]/2][Sequence[i]%2].pressPane();
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}

这是从事件调度线程的内容中调用的,这会阻止它处理任何新的更新或更新 UI。

看看Concurrency in Swing有关更多详细信息并考虑改用 Swing Timer,请参阅 How to use Swing Timers了解更多详情

pane.update(pane.getGraphics()); 在您可能在 Swing 中做过的一些最糟糕的事情中排名非常非常高(Thread.sleep 是在那里)。

看看Painting in AWT and SwingPerforming Custom Painting了解在 Swing 中绘画是如何工作的

避免使用 null 布局,像素完美布局是现代 ui 设计中的一种错觉。影响组件单个尺寸的因素太多,没有一个是您可以控制的。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

您可能希望阅读 Code Conventions for the Java TM Programming Language ,它会让人们更容易阅读你的代码,也让你更容易阅读别人的代码

例如……

所以,这个例子真的很基础。它有三个按钮...

  • “错误的方式”,基本上就是您正在做的事情
  • “计时器方式”,使用 Swing Timer
  • “ worker 方式”,使用 SwingWorker

在您的情况下,我仍然认为 Swing Timer 是最佳选择,因为 SwingWorker 有可能获得更新备份,将它们全部吐出一次,这违背了您可能想要使用它的目的。

The Sequence

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Sequence {

public static void main(String[] args) {
new Sequence();
}

public Sequence() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private List<SequencePane> panels = new ArrayList<>(4);

private Timer timer;
private int sequenceIndex;

public TestPane() {
setLayout(new BorderLayout());
Color colors[] = new Color[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW};
for (int index = 0; index < 4; index++) {
panels.add(new SequencePane(colors[index]));
}
JPanel content = new JPanel(new GridLayout(2, 2));
for (SequencePane pane : panels) {
content.add(pane);
}

add(content);

JButton wrong = new JButton("The wrong way");
JButton timerButton = new JButton("The Timer way");
JButton workerButton = new JButton("The Worker way");

JPanel actions = new JPanel();
actions.add(wrong);
actions.add(timerButton);
actions.add(workerButton);

add(actions, BorderLayout.SOUTH);

wrong.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Collections.shuffle(panels);
for (SequencePane pane : panels) {
try {
pane.setHighlighted(true);
Thread.sleep(250);
pane.setHighlighted(false);
} catch (InterruptedException ex) {
}
}
}
});

timer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sequenceIndex > 0) {
panels.get(sequenceIndex - 1).setHighlighted(false);
}

if (sequenceIndex < panels.size()) {
panels.get(sequenceIndex).setHighlighted(true);
sequenceIndex++;
} else {
timer.stop();
// All done, call some "play" method to begin playing
}
}
});

timerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.stop();
Collections.shuffle(panels);
sequenceIndex = 0;
timer.start();
}
});

SwingWorker worker = new SwingWorker<Object, SequenceState>() {
@Override
protected Object doInBackground() throws Exception {
for (SequencePane pane : panels) {
publish(new SequenceState(pane, true));
Thread.sleep(100);
publish(new SequenceState(pane, false));
}
return null;
}

@Override
protected void process(List<SequenceState> chunks) {
SequenceState state = chunks.get(chunks.size() - 1);
state.applyState();
}

@Override
protected void done() {
// Back in the EDT, call what ever "play" method you need
}

};

workerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Collections.shuffle(panels);
SequenceWorker worker = new SequenceWorker();
worker.execute();
}
});

}

public class SequenceWorker extends SwingWorker<Object, SequenceState> {
@Override
protected Object doInBackground() throws Exception {
for (SequencePane pane : panels) {
publish(new SequenceState(pane, true));
Thread.sleep(250);
publish(new SequenceState(pane, false));
}
return null;
}

@Override
protected void process(List<SequenceState> chunks) {
for (SequenceState state : chunks) {
state.applyState();
}
}

@Override
protected void done() {
// Back in the EDT, call what ever "play" method you need
}

}

public class SequenceState {

private SequencePane sequencePane;
private boolean highlighted;

public SequenceState(SequencePane sequencePane, boolean highlighted) {
this.sequencePane = sequencePane;
this.highlighted = highlighted;
}

public SequencePane getSequencePane() {
return sequencePane;
}

public boolean isHighlighted() {
return highlighted;
}

public void applyState() {
getSequencePane().setHighlighted(isHighlighted());
}
}

}

public class SequencePane extends JPanel {

private boolean highlighted;

public SequencePane(Color color) {
setOpaque(false);
setBackground(color);
}

public void setHighlighted(boolean highlighted) {
this.highlighted = highlighted;
repaint();
}

public boolean isHighlighted() {
return highlighted;
}

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

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (!isHighlighted()) {
g2d.setComposite(AlphaComposite.SrcOver.derive(0.25f));
}
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
}

}

}

关于Java Button 暂停图形更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33727830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com