Java 如何停止撞车JLabels
我正在做一个小GUI应用程序来模拟游泳比赛。我为游泳池和记分板提供了一个单独的图形用户界面,在这里,游泳运动员通过5个线程移动,当他们到达触摸板时,我已经编码在记分板上显示时间 问题是,每当记分板上显示标签的时间被更新时,游泳运动员突然回到起始位置(不是一个连续的动作,只是在起始点消失和出现),而不停留在触摸板附近。但如果标签不更新,这是可行的 这是GUI的图像。 这不是完整的代码,但这是负责游泳者移动和在游泳者完成长度时更新时间标签的代码段Java 如何停止撞车JLabels,java,multithreading,user-interface,jlabel,Java,Multithreading,User Interface,Jlabel,我正在做一个小GUI应用程序来模拟游泳比赛。我为游泳池和记分板提供了一个单独的图形用户界面,在这里,游泳运动员通过5个线程移动,当他们到达触摸板时,我已经编码在记分板上显示时间 问题是,每当记分板上显示标签的时间被更新时,游泳运动员突然回到起始位置(不是一个连续的动作,只是在起始点消失和出现),而不停留在触摸板附近。但如果标签不更新,这是可行的 这是GUI的图像。 这不是完整的代码,但这是负责游泳者移动和在游泳者完成长度时更新时间标签的代码段 private final Map<Swim
private final Map<Swimmer, JLabel> mapLaneTime = new HashMap<>();
private void startTheGame(final String swimmingStyle) {
final ArrayList<Swimmer> listSwimmer =
new ArrayList<> (mapSwimmers.keySet());
for (int i = 0; i < mapSwimmers.size(); i++) {
final Swimmer swmr = listSwimmer.get(i);
// set up the intial position of the JLabel to the swimmer
swmr.setCurrentPosition(mapSwimmers.get(swmr).getX());
new Thread(new Runnable() {
@Override
public void run() {
try {
swmr.slowDown();
JLabel lblSwmr = mapSwimmers.get(swmr);
swmr.doSwimmingStyle(swimmingStyle);
int startPosition = swmr.getCurrentPosition();
while ((swmr.getCurrentPosition()
!= swmr.getSwimLane().getLength()
+ startPosition)) {
lblSwmr.setLocation(swmr.doLegMovements(),
lblSwmr.getY());
swmr.doHandMovements();
swmr.speedUp();
}
// time takes for the swimmer to touch the touch pad
double time = swmr.touchTheTouchPad(swimmingEvent);
/** problem comes when the below line is present it is the way to set text
** to the label if this is not here swimmers properly end the length
** without appearing at the starting position when ever they finish the
** length
**/
mapLaneTime.get(swmr).setText(time + "");
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
swmr.giveUp();
}
}
}).start();
}
}
private final Map mapLaneTime=new HashMap();
private void开始游戏(最终字符串滑动样式){
最终ArrayList列表游泳者=
新的ArrayList(mapswillers.keySet());
对于(int i=0;i
线程根本没有问题。不要在意其他方法。其他实现没有任何问题
很抱歉,我忘了提到swmr.giveUP()是释放锁的方法(lock lock=new ReentrantLock())。锁是在游泳者类中定义的。Silvery类中还有另一个线程用于更新使用相同锁的游泳者的位置 这是游泳类、记分板类的完整代码 游泳者类(这是一个抽象类,它有两个子类MaleSwimmer和FemaleSwimmer)
import java.util.Random;
导入java.util.concurrent.locks.Condition;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReentrantLock;
公共抽象类游泳者扩展人{
私人终点线性别;//游泳运动员的性别
私有最终字符串countColor;//服装的颜色
私人决赛;
私人职位;
私人泳道泳道;
private final Lock;//线程的锁
私人最终条件;
受保护游泳者(字符串名称、字符串性别、字符串颜色){
超级(姓名);
这个。性别=性别;
this.countcolor=countcolor;
随机=新随机();
this.personalBest=random.nextInt(20)+8;
锁=新的可重入锁();
condition=lock.newCondition();
}
公共泳道getSwimLane(){
归还这个泳道;
}
/**
*@返回游泳服的颜色
*/
受保护的字符串getDressColor(){
返回此颜色;
}
/**
*做手势
*/
受保护的无效移动(){
this.condition.signalAll();
}
/**
*做腿部运动
*
*@返回
*/
受保护的int-doLegMovements(){
返回此.currentPosition;
}
/**
*蝶泳
*
*@param睡眠时间
*/
受保护的抽象空飞行行程(int睡眠时间);
/**
*仰泳
*
*@param睡眠时间
*/
受保护的抽象空多巴克中风(int睡眠时间);
/**
*蛙泳
*
*@param睡眠时间
*/
受保护的抽象空多脑卒中(int睡眠时间);
/**
*自由泳
*
*@param睡眠时间
*/
自由泳(整夜睡眠时间);
公共void样式(字符串样式){
开关(样式){
案例“自由泳”:
自由泳(个人最佳);
打破
“仰泳”一案:
多巴克中风(个人最佳);
打破
“蝶泳”一案:
多布特飞行行程(个人最佳);
打破
案例“蛙泳”:
dobreaststrope(个人最佳);
打破
}
this.swimLane.getTouchPad().startTimer();//当游泳者开始游泳时启动计时器
}
void updatePosition(int sleepTime,双因子){
最终整数swimTime=(整数)(睡眠时间*系数);
新线程(newrunnable()){
@凌驾
公开募捐{
试一试{
lock.lock();//锁定线程
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public abstract class Swimmer extends Person {
private final String gender; // gender of the Swimmer
private final String costumeColor; //color of the costume
private final int personalBest;
private volatile int currentPosition;
private SwimLane swimLane;
private final Lock lock; // lock for the thread
private final Condition condition;
protected Swimmer(String name, String gender, String costumeColor) {
super(name);
this.gender = gender;
this.costumeColor = costumeColor;
Random random = new Random();
this.personalBest = random.nextInt(20) + 8;
lock = new ReentrantLock();
condition = lock.newCondition();
}
public SwimLane getSwimLane() {
return this.swimLane;
}
/**
* @return the color of the swimming costume
*/
protected String getDressColor() {
return this.costumeColor;
}
/**
* perform hand movements
*/
protected void doHandMovements() {
this.condition.signalAll();
}
/**
* perform leg movements
*
* @return
*/
protected int doLegMovements() {
return this.currentPosition;
}
/**
* perform Butterfly stroke
*
* @param sleepTime
*/
protected abstract void doButterflyStroke(int sleepTime);
/**
* perform Backstroke
*
* @param sleepTime
*/
protected abstract void doBackStroke(int sleepTime);
/**
* perform Breaststroke
*
* @param sleepTime
*/
protected abstract void doBreastStroke(int sleepTime);
/**
* perform Freestyle
*
* @param sleepTime
*/
protected abstract void doFreeStyle(int sleepTime);
public void doSwimmingStyle(String style) {
switch (style) {
case "Freestyle":
doFreeStyle(personalBest);
break;
case "Backstroke":
doBackStroke(personalBest);
break;
case "Butterfly Stroke":
doButterflyStroke(personalBest);
break;
case "Breaststroke":
doBreastStroke(personalBest);
break;
}
this.swimLane.getTouchPad().startTimer(); // start the timer when swimmer starts to swim
}
void updatePosition(int sleepTime, double factor) {
final int swimTime = (int) (sleepTime * factor);
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock(); // lock the thread
int endPosition = currentPosition + swimLane.getLength(); // length of the lane from staring to end
while (currentPosition <= endPosition) {
currentPosition++;
Thread.sleep(swimTime);
condition.signal();
condition.await();
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock(); // give up the lock from the thread
}
}
}).start();
}
public int getPersonalBest() {
return this.personalBest;
}
public void setCurrentPosition(int currentPosition) {
this.currentPosition = currentPosition;
}
public int getCurrentPosition() {
return this.currentPosition;
}
public void setSwimLane(SwimLane swimLane) {
this.swimLane = swimLane;
}
/**
* When swimmer finish the event swimmer should touch the touch pad. This
* method achieve that task
*
* @param swimmingEvent
* @return swimmer's finishing time
*/
public double touchTheTouchPad(SwimmingEvent swimmingEvent) {
return this.swimLane.getTouchPad().notifyScoreBoard(this,
swimmingEvent);
}
public void slowDown() throws InterruptedException {
this.lock.lock();
}
public void speedUp() throws InterruptedException {
this.condition.awaitNanos(500);
}
public void giveUp() {
this.lock.unlock();
}
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ScoreBoard implements Serializable {
Queue<Double> time;
Queue<Swimmer> swimmers;
Map<Swimmer, Double> finalResults;
private int numberOfRows;
private final Lock lock;
private final Condition condition;
public ScoreBoard() {
time = new LinkedList<>();
swimmers = new LinkedList<>();
finalResults = new LinkedHashMap<>();
lock = new ReentrantLock();
condition = lock.newCondition();
}
/**
* This method will add swimmer and timeTaken to the list
*
* @param swimmer swimmer who completed the event
* @param timeTaken time took for swimmer to complete the event
*/
public void updateList(Swimmer swimmer, double timeTaken) {
time.add(timeTaken);
swimmers.add(swimmer);
}
/**
* This method will start the process of the Score Board
*/
public void powerUp() {
new Thread(new Runnable() {
@Override
public void run() {
try {
// swimmer will take more than 4s to complete a game
Thread.sleep(4000);
lock.lock();
while (swimmers.size() != numberOfRows) {
// wait this thread untill this is awoken
Thread.sleep(100);
}
comapreTimes();
condition.signal();
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
}
/**
* This method will set the number of rows in Score Board
*
* @param numberOfRows number of rows that should be in Score Board
*/
public void setNumberOfRows(int numberOfRows) {
this.numberOfRows = numberOfRows;
}
/**
* This method will pass the lock to the thread inside the powerUp method
*/
public void lockTheScoreBoard() {
this.lock.lock();
}
public void unlockTheScoreBoard() {
this.lock.unlock();
}
public void awaitScoreBoard() throws InterruptedException {
this.condition.await();
}
void comapreTimes() {
for (Swimmer s : swimmers) {
this.finalResults.put(s, time.poll());
// need to do something more in here
}
}
public Map<Swimmer, Double> getFinalResults() {
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
condition.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
return this.finalResults;
}