简体   繁体   中英

Javafx call method from controller to application thread

i am trying to create a little messaging program with activeMQ. The message should be shown in a little window in the right bottom corner. This message is created with javafx. Now i am struggling with the call of the metohod to change the windows text. The problem is, that i don't know how to call the method in the application thread, rather then in the consumer thread.

public class Notification implements Initializable, MessageReciever {

private static Logger log                = LoggerFactory.getLogger( Notification.class );

String                infourl            = "/info.png";
String                warningurl         = "/warning.png";
String                errorurl           = "/error.png";
final String          HeroldStartMessage = "Herold started.";
@FXML
Rectangle             rectangleColor;
@FXML
ImageView             imageIcon;
@FXML
Label                 topicLabel;
@FXML
Label                 messageLabel;
@FXML
Label                 closeLabel;
@FXML
AnchorPane            controlAnchor;

public void messageRecieved( final Message message, final Topic topic ) {


    Notification.this.topicLabel.setText( message.getHeader() );
    Notification.this.messageLabel.setText( message.getText() );

    if ( message.getLevel().contains( "info" ) ) {
        log.info( "message level contains info" );
        Notification.this.rectangleColor.setFill( Paint.valueOf( "#1b2db5" ) );
        Notification.this.imageIcon.setImage( new Image( Notification.this.infourl ) );
        log.info( "Color and Image has been changed." );
    } else if ( message.getLevel().contains( "warning" ) ) {
        log.info( "message level contains warning" );
        Notification.this.rectangleColor.setFill( Paint.valueOf( "#f8790b" ) );
        Notification.this.imageIcon.setImage( new Image( Notification.this.warningurl ) );
        log.info( "Color and Image has been changed." );
    } else if ( message.getLevel().contains( "error" ) ) {
        log.info( "message level contains error" );
        Notification.this.rectangleColor.setFill( Paint.valueOf( "#ff0000" ) );
        Notification.this.imageIcon.setImage( new Image( Notification.this.errorurl ) );
        log.info( "Color and Image has been changed." );
    } else {
        //
    }
    NotificationStage.show();
}

@Override
public void initialize( final URL location, final ResourceBundle resources ) {
    this.closeLabel.setOnMouseClicked( e -> NotificationStage.dismiss() );
    this.rectangleColor.setFill( Paint.valueOf( "#1b2db5" ) );
    this.imageIcon.setImage( new Image( this.infourl ) );
    this.topicLabel.setText( "Herold" );
    this.messageLabel.setText( this.HeroldStartMessage );
    MasterConsumer.getMasterConsumer().addMessageReciever( this );
}

}

Exception in thread "Thread-8" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-8

The method messagereciever() is called by an interface from a consumer.

EDIT with javaFx version

    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            Notification.this.topicLabel.setText(message.getHeader());
            Notification.this.messageLabel.setText(message.getText());
        }
    });

Use Platform.runLater with a Runnable parameter that contains the code for updating the UI.

Example:

TextArea textArea = ...

new Thread(() -> {
    String s;
    while ((s = getMessage()) != null) {
        final String newText = "\n" + s;
        Platform.runLater(() -> {
            // run update on application thread
            textArea.appendText(newText);
        });
    }
}).start();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM