第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Java/JavaFX:輪詢數(shù)據(jù)庫以進(jìn)行單值更新,同時(shí)保持 GUI 中的響應(yīng)能力

Java/JavaFX:輪詢數(shù)據(jù)庫以進(jìn)行單值更新,同時(shí)保持 GUI 中的響應(yīng)能力

烙印99 2022-09-21 16:42:51
我和一些朋友一起,試圖創(chuàng)建一個(gè)回合制游戲。我們?cè)跈z查用戶何時(shí)輪到他們時(shí)遇到了一些問題,同時(shí)保持GUI的響應(yīng)性,以及在游戲關(guān)閉時(shí)關(guān)閉我們現(xiàn)在使用的線程。我希望獲得有關(guān)如何執(zhí)行此操作的一些信息,但我不確定問題是與JavaFX相關(guān),還是與線程相關(guān),還是兩者兼而有之。我試圖盡可能多地搜索,但根本找不到我想要的東西,即使我相信它很簡單。現(xiàn)在,我們有一個(gè)線程運(yùn)行一個(gè)循環(huán),當(dāng)你點(diǎn)擊一個(gè)按鈕來檢查它是否輪到你了。當(dāng)輪到你時(shí),我們希望禁用一些用戶輸入,所以我不確定我們是否真的需要一個(gè)線程,除了保持響應(yīng)能力。我也嘗試過實(shí)現(xiàn)一個(gè)擴(kuò)展 Thread 的類,但這似乎只會(huì)讓問題變得更糟,因?yàn)槊看瓮婕覜]有輪到它時(shí)都會(huì)啟動(dòng)一個(gè)新線程,或者如果我將循環(huán)放在線程之外,則會(huì)凍結(jié) GUI。public void refreshButtonPressed(){    try{        refreshButton.setDisable(true);        Thread pollThread = new Thread(() -> {            System.out.println("Thread started");  //Stop being able to start more threads            int user_id = 0;            String gamePin = "xxxxxx";        while (!GameConnection.yourTurn(user_id, Context.getContext().getGamePin())){ //This method checks the database if it is your turn            try{                Thread.sleep(5000);  //So we don't flood the database            }            catch (InterruptedException e){                System.out.println("Interrupted");                break;            }             //If we close the game, stop the thread/while loop.             if (TurnPolling.closedGame){                break;            }        }        playerButton.setDisable(false);        refreshButton.setDisable(false);        refreshButton.setText("Refresh");        System.out.println("Thread ended");        });        pollThread.start();    }catch (Exception e){        e.printStackTrace();    }}在游戲屏幕.fxml文件的控制器中(不是主屏幕,而是通過登錄屏幕和主擴(kuò)展應(yīng)用程序加載的屏幕)。public void initialize(URL location, ResourceBundle resources) {    playerButton.setDisable(!GameConnection.yourTurn(user_id, gameTurn));    myStage.setOnCloseRequest(event -> TurnPolling.closedGame = true);}目前,TurnPolling 類只有公共靜態(tài)布爾封閉游戲,以免將其保留在控制器中。最后一行設(shè)置封閉游戲 = true 實(shí)際上給了我一個(gè)空點(diǎn)器例外,這可能是因?yàn)槲枧_(tái)尚未初始化,當(dāng)我在 initialize() 方法中執(zhí)行此操作時(shí)?我希望僅在輪到玩家時(shí)啟用玩家按鈕,并在游戲屏幕關(guān)閉時(shí)關(guān)閉線程(如果需要)?,F(xiàn)在,你必須點(diǎn)擊一個(gè)按鈕來檢查它是否輪到你了,每五秒鐘再次檢查一次,當(dāng)你關(guān)閉游戲時(shí),它不會(huì)停止。請(qǐng)告訴我,如果你需要更多的代碼或澄清,這是我的第一個(gè)大項(xiàng)目,所以我真的不知道放多少在這里。我知道這不是有效的代碼,但它是我能做的,而不會(huì)讓它感覺像是混亂。感謝您的回答!
查看完整描述

1 回答

?
犯罪嫌疑人X

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊

首先,重要的是要記住,不允許在 JavaFX 應(yīng)用程序線程以外的任何線程中更改 JavaFX 節(jié)點(diǎn)。因此,您的線程需要移動(dòng)以下行:


playerButton.setDisable(false);

refreshButton.setDisable(false);

refreshButton.setText("Refresh");

到一個(gè)可運(yùn)行的,它被傳遞給平臺(tái)。


Platform.runLater(() -> {

    playerButton.setDisable(false);

    refreshButton.setDisable(false);

    refreshButton.setText("Refresh");

});

請(qǐng)注意,對(duì)一個(gè)線程中的字段所做的更改在另一個(gè)線程中可能不可見,除非聲明為 。從 Java 語言規(guī)范:TurnPolling.closedGamevolatile


例如,在下面的(損壞的)代碼片段中,假定這是一個(gè)非字段:this.donevolatileboolean


while (!this.done)

    Thread.sleep(1000);

編譯器可以自由地讀取該字段一次,并在每次執(zhí)行循環(huán)時(shí)重用緩存的值。這意味著循環(huán)永遠(yuǎn)不會(huì)終止,即使另一個(gè)線程更改了 的值。this.donethis.done


使用任務(wù)和服務(wù)

JavaFX為所有這些提供了一個(gè)更干凈的解決方案:任務(wù)和服務(wù)。


服務(wù)創(chuàng)建任務(wù)。服務(wù)具有可綁定的值屬性,該屬性始終等于最近創(chuàng)建的任務(wù)的值。您可以將按鈕屬性綁定到服務(wù)的值屬性:


int user_id = 0;


Service<Boolean> turnPollService = new Service<Boolean>() {

    @Override

    protected Task<Boolean> createTask() {

        return new Task<Boolean>() {

            @Override

            protected Boolean call()

            throws InterruptedException {


                updateValue(true);


                String gamePin = Context.getContext().getGamePin();


                while (!GameConnection.yourTurn(user_id, gamePin)) {

                    Thread.sleep(5000);


                    if (TurnPolling.closedGame){

                        break;

                    }

                }


                return false;

            }

        };

    }

};


playerButton.disableProperty().bind(turnPollService.valueProperty());

refreshButton.disableProperty().bind(turnPollService.valueProperty());


refreshButton.textProperty().bind(

    Bindings.when(

        turnPollService.valueProperty().isEqualTo(true))

        .then("Waiting for your turn\u2026")

        .otherwise("Refresh"));

當(dāng)玩家的回合完成時(shí),您將調(diào)用 。turnPollService.restart();


無論您是使用服務(wù),還是僅使用 Platform.runLater,您仍然需要通過創(chuàng)建它或?qū)⑺袑?duì)它的訪問包含在塊(或鎖保護(hù))中來使線程安全。TurnPolling.closedGamevolatilesynchronized


查看完整回答
反對(duì) 回復(fù) 2022-09-21
  • 1 回答
  • 0 關(guān)注
  • 408 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)