2016-02-17 74 views
2

我已經嘗試了下面的代碼,它可以很好地處理鼠標事件,但是當我使用按鍵事件時,例如在沒有顯示結果的任何按鈕上輸入按鍵。在Javafx中輸入關鍵事件不能用於對話框?

Alert alert = new Alert(AlertType.CONFIRMATION); 
alert.setTitle(null); 
alert.setHeaderText(null); 
alert.setGraphic(null); 
alert.setContentText("Choose your option."); 

ButtonType buttonTypeOne = new ButtonType("One"); 
ButtonType buttonTypeTwo = new ButtonType("Two"); 
ButtonType buttonTypeThree = new ButtonType("Three"); 

alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree); 

Optional<ButtonType> result = alert.showAndWait(); 
if (result.get() == buttonTypeOne) { 
    System.out.println("One"); 
} else if (result.get() == buttonTypeTwo) { 
    System.out.println("Two"); 
} else if (result.get() == buttonTypeThree) { 
    System.out.println("Three"); 
} 

回答

1

我不知道這是不是一種過分一種解決辦法,但至少它的工作原理:

import javafx.event.EventHandler; 
import javafx.scene.control.Button; 
import javafx.scene.input.KeyCode; 
import javafx.scene.input.KeyEvent; 

    [...] 
ButtonType buttonTypeTwo = new ButtonType("Two"); 
ButtonType buttonTypeThree = new ButtonType("Three"); 

alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree); 

//Create a button for every ButtonType you add to your alert and give it a Eventhandler 
Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeOne); 
Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo); 
Button button3 = (Button) alert.getDialogPane().lookupButton(buttonTypeThree); 


button1.setOnKeyReleased(new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { 
     if(event.getCode() == KeyCode.ENTER) 
    alert.setResult(buttonTypeOne);  
    } 
}); 
button2.setOnKeyReleased(new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { 
     if(event.getCode() == KeyCode.ENTER) 
    alert.setResult(buttonTypeTwo);  
    } 
}); 
button3.setOnKeyReleased(new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { 
     if(event.getCode() == KeyCode.ENTER) 
    alert.setResult(buttonTypeThree);  
    } 
}); 
//go ahead with your code 
Optional<ButtonType> result = alert.showAndWait(); 
[...] 

你剛纔創建一些按鈕和分配他們的實際按鈕上你的警報。在下一步中,您可以爲每個按鈕指定一個EventHandler(在此示例中)檢查 - 何時釋放任何鍵 - 如果該鍵是ENTER並設置結果。

我想有更好的解決方案。但這是目前我想到的最簡單的方法。希望它可以幫助你。

+0

它不起作用 –

6

我不建議讓所有按鈕都響應輸入,因爲這與大多數UI對話框的工作方式相反。

通常情況下,當你按下空間與焦點的按鈕將火,不是進入。然而,有特殊的按鈕,將激活特定的鍵:A default button將觸發輸入cancel button將觸發esc。通常,對話框中只有這些特殊類型的按鈕中的一種,因此無論當前哪個按鈕具有焦點,都可以通過特殊的鍵盤加速器進行觸發。

此外,不同的桌面操作系統系統在對話系統中放置默認和取消按鈕時有不同的標準。這是爲了幫助用戶在任何對話框中輕鬆找到這些特殊按鈕。 JavaFX對話系統在內部實現了一些邏輯,用於在用戶希望在不同的桌面操作系統上看到它們的對話框中定位按鈕。

比方說,你想從你的例子按鈕類型被定義爲默認或取消按鈕,並放置在正確的位置這樣的按鈕爲您的操作系統,那麼你可以如下操作:

ButtonType buttonTypeTwo = new ButtonType(
    "Two", 
    ButtonBar.ButtonData.OK_DONE 
); 
ButtonType buttonTypeThree = new ButtonType(
    "Three", 
    ButtonBar.ButtonData.CANCEL_CLOSE 
); 

注JavaFX系統自動改變了按鈕的位置和一些顏色突出顯示。當用戶按下時輸入,那麼當用戶按下esc時,「2」將會發射,那麼「三」將會發射。如果你在Windows或者Linux上運行相同的代碼,根據這些操作系統使用的任何按鈕定位標準,按鈕的位置可能會有所不同。

enter image description here

如果你不希望的JavaFX按照OS標準重新定位你的按鈕,但你希望他們仍應對進入ESC鍵,那麼你就可以查找按鈕,直接修改按鈕屬性如下圖所示:

Button buttonTwo = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo); 
buttonTwo.setDefaultButton(true); 
Button buttonThree = (Button) alert.getDialogPane().lookupButton(buttonTypeThree); 
buttonThree.setCancelButton(true); 

adjusted button types

我recomme讓JavaFX適當地定位特定類型的按鈕,而不是像上面那樣執行查找。

我還建議在您的JavaFX Alert中設置至少一個CANCEL_CLOSE按鈕或OK_DONE按鈕,否則用戶可能會很難實際關閉警報,因爲對話框可能不會按照用戶預期的方式響應按鍵。

+0

這是一個有用的解釋。 – Arceus

0

這裏我怎麼解決它。 它工作正常以下是我確認提醒功能。

public static boolean confirmAlert(String title, String msg){ 

     ButtonType buttonTypeYes = new ButtonType("Yes", ButtonBar.ButtonData.OK_DONE); 
     ButtonType buttonTypeNo = new ButtonType("No",ButtonBar.ButtonData.CANCEL_CLOSE); 

     Alert alert = new Alert(Alert.AlertType.NONE, msg,buttonTypeNo,buttonTypeYes); 
     alert.setTitle(title); 

     Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeYes); 
     button1.setDefaultButton(false); //***set default to false*** 

     Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeNo); 

     button1.setOnKeyReleased(event -> { 
      if(event.getCode() == KeyCode.ENTER) 
       alert.setResult(buttonTypeYes); 
     }); 
     button2.setOnKeyReleased(event -> { 
      if(event.getCode() == KeyCode.ENTER) 
       alert.setResult(buttonTypeNo); 
     }); 
     alert.showAndWait(); 
     return alert.getResult()==buttonTypeYes; 
    }