从线程调用时,Java GUI不会修改/更新

时间:2018-12-01 22:49:24

标签: java multithreading swing user-interface

我有一个项目,必须使用Java Swing创建roulette wheel。当方向盘“旋转”时,方向盘上的数字为randomly highlighted,然后降落为最终数字。

我必须创建一个GUI类,以上述布局提供JLabel。此GUI类中也需要旋转轮子的方法,我们明确必须使用线程和Runnable接口来处理此问题。

在添加GUI类(RouletteWheel)之前,教授为我提供了一个驱动程序类,该类创建了JFrame和Buttons:

public WheelTest()
{
    theWindow = new JFrame("WheelTest Program");
    theWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    ActionListener listen = new ButtonListener();

    setButton = new JButton("Set Wheel");  
    setButton.setFont(myFont);
    setButton.addActionListener(listen);

    ........

    theWheel = new RouletteWheel();   //GUI class
    theWindow.add(theWheel, BorderLayout.CENTER);
}

这是我的GUI类的样子:

final RouletteSquare [] squareArray = new RouletteSquare[37];  //Array of JLabels
private Boolean spun;

public RouletteWheel(){
    createGUI();
}

private void createGUI(){  //Creates a RouletteSquare object for each place in the array
    this.setLayout(new GridLayout(6, 6));
    for(int i = 0; i <= 36; i++){
        squareArray[i] = new RouletteSquare(i);
        this.add(squareArray[i]);
        squareArray[i].choose();
    }
}

public void spin(){
    Runnable wheel = new RouletteWheel();
    new Thread(wheel).start();
}

public void run(){
    Random rand = new Random();
    long startTime = System.nanoTime();
    long endTime = System.nanoTime();
    long elapsedTime = endTime - startTime;
    long nanoTime = 10000;
    while(elapsedTime <= nanoTime)
    {
        i = rand.nextInt(37);
        System.out.println("i = " + i);
        squareArray[i].choose();  //Highlights square CYAN color
        try {Thread.sleep(500);}  //Adds a delay between selections
        catch (InterruptedException e){}
        squareArray[i].unChoose();  //Un-highlights square
        endTime = System.nanoTime();
        elapsedTime = endTime - startTime;
    }
    i = rand.nextInt(37);
    squareArray[i].choose();
}

为便于记录,该GUI类使用了先前项目RouletteSquare中的另一个类,该项目仅创建了一个单独的JLabel,并提供了突出显示该JLabel的方法。我使用一组RouletteSquares来创建RouletteWheel(此项目也是必需的)。这是RouletteSquare类的外观:

private boolean cvar;
private int value;
public RouletteSquare(int val)
{
    value = val;
    this.setLayout(new GridLayout(1, 1));

    number2 = new JLabel();
    number2.setText(String.valueOf(value));
    number2.setFont(new Font("Serif", Font.BOLD, 50));
    number2.setForeground(getColorType(getColor()));
    number2.setHorizontalAlignment(CENTER);
    number2.setOpaque(true);
    number2.setBackground(Color.WHITE);

    this.setPreferredSize(new Dimension(75, 75));
    this.add(number2);
}

public boolean isChosen() {
    return cVar;
}

public void unChoose() {
    cVar = false;
    number2.setBackground(Color.WHITE);
}

public void choose() {
    cVar = true;
    number2.setBackground(Color.CYAN);
}

GUI已正确创建和初始化,我可以在线程方法调用之外对其进行更改。

据我所遇到的问题,据打印语句可以看出,我的代码可以正确执行,但是通过线程调用时,GUI不会更新。我尝试使用SwingUtilities.InvokeLater(Runnable),但这在解决我的问题方面没有成功。我也不能使用javax.swing.timer,因为我必须使用线程。

我的想法不多了,并且开始变得越来越沮丧。任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

您创建RouletteWheel类:

theWheel = new RouletteWheel();  

,然后在您的spin()方法中,创建RouletteWheel的另一个实例:

public void spin(){
    Runnable wheel = new RouletteWheel();
    new Thread(wheel).start();
}

您只想要RouletteWheel类的单个实例。

我想代码应该是:

//new Thread(wheel).start();
new Thread(this).start();