设置 JavaFX 标签文本时,Java MIDI 抛出 IllegalStateException

问题描述 投票:0回答:1

我正在尝试编写一个应用程序,该应用程序读取 MIDI 控制更改消息并在 JavaFX GUI 中设置适当滑块和标签的值。设置滑块的值工作正常,但尝试设置标签的文本会引发 IllegalStateException(文本不会更改)。这是什么原因以及如何解决?

我的测试代码如下:

transmitter.setReceiver(new Receiver() {
    @Override
    public void send(MidiMessage message, long timeStamp) {
        byte midiBytes[] = message.getMessage();
        int  status = midiBytes[0] & 0xf0;
        
        // midi CC message
        if(status == 0xb0) {
            // the following line works fine
            controller.testSlider.setValue(midiBytes[2]);
            // but the following line causes an error
            controller.testLabel.setText(String.valueOf(midiBytes[2]));
        }
    }
    //...
});

这是错误消息(在 Eclipse 中):

Exception in thread "Java Sound MidiInDevice Thread" java.lang.IllegalStateException: Not on FX application thread; currentThread = Java Sound MidiInDevice Thread
    at javafx.graphics/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:297)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:458)
    at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:474)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
    at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:282)
    at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.lambda$new$11(LabeledSkinBase.java:219)
    at javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$1(LambdaMultiplePropertyChangeListenerHandler.java:88)
    at javafx.base/javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:86)
    at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
    at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
    at javafx.base/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
    at javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
    at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
    at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
    at javafx.base/javafx.beans.property.StringProperty.setValue(StringProperty.java:71)
    at javafx.controls/javafx.scene.control.Labeled.setText(Labeled.java:147)
    at midi.Midi$1.send(Midi.java:88)
    at java.desktop/com.sun.media.sound.AbstractMidiDevice$TransmitterList.sendMessage(AbstractMidiDevice.java:629)
    at java.desktop/com.sun.media.sound.MidiInDevice.callbackShortMessage(MidiInDevice.java:155)
    at java.desktop/com.sun.media.sound.MidiInDevice.nGetMessages(Native Method)
    at java.desktop/com.sun.media.sound.MidiInDevice.run(MidiInDevice.java:127)
    at java.base/java.lang.Thread.run(Thread.java:833)
java midi javax.sound.midi
1个回答
0
投票

VGR 的回答非常有效 - 谢谢!

我将以下内容添加到我的控制器中:

private class RunnableSetText implements Runnable {
    private String text;

    public RunnableSetText(String text) {
        this.text = text;
    }
    
    public void run() {
        testLabel.setText(text);
    }
}

public void setTextTest(String text) {
    Platform.runLater(new RunnableSetText(text));
}

并从我的 MIDI 接收器调用 setTextTest 方法。

© www.soinside.com 2019 - 2024. All rights reserved.