本文介紹了在按住按鈕JavaFX的同時(shí)對(duì)多個(gè)節(jié)點(diǎn)進(jìn)行鼠標(biāo)拖動(dòng)檢測(cè)的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!
問(wèn)題描述
我將直接回答這個(gè)問(wèn)題。我如何為我的應(yīng)用程序?qū)崿F(xiàn)一個(gè)系統(tǒng),讓我在按住鼠標(biāo)左鍵的同時(shí)為下面顯示的這些矩形上色?當(dāng)它被釋放時(shí),它就會(huì)停止著色。我通過(guò)互聯(lián)網(wǎng)搜索了一下,但我仍然不明白這些鼠標(biāo)事件是如何工作的。
祝你有愉快的一天!
推薦答案
來(lái)自javafx.scene.input.MouseEvent
的文檔:
拖動(dòng)手勢(shì)
有三種類(lèi)型的拖動(dòng)手勢(shì)。它們都是由鼠標(biāo)按下事件啟動(dòng)的,并由于鼠標(biāo)釋放事件而終止,源節(jié)點(diǎn)決定將發(fā)生哪個(gè)手勢(shì)。
默認(rèn)設(shè)置為簡(jiǎn)單的按下-拖動(dòng)-釋放手勢(shì)。它最適合用于更改形狀的大小、拖動(dòng)形狀等等。整個(gè)按下-拖動(dòng)-釋放手勢(shì)被傳遞到一個(gè)節(jié)點(diǎn)。按下鼠標(biāo)按鈕時(shí),將拾取最頂端的節(jié)點(diǎn),并將所有后續(xù)鼠標(biāo)事件傳遞到同一節(jié)點(diǎn),直到釋放該按鈕。如果鼠標(biāo)單擊事件是從這些事件生成的,它仍會(huì)傳遞到同一節(jié)點(diǎn)。
在簡(jiǎn)單的按下拖動(dòng)釋放手勢(shì)期間,其他節(jié)點(diǎn)不會(huì)參與,也不會(huì)獲得任何事件。如果這些節(jié)點(diǎn)需要參與手勢(shì),則必須激活完整的按下-拖動(dòng)-釋放手勢(shì)。此手勢(shì)最適合用于通過(guò)”Wire”連接節(jié)點(diǎn)、將節(jié)點(diǎn)拖動(dòng)到其他節(jié)點(diǎn)等。
MouseDragEvent
中對(duì)此手勢(shì)類(lèi)型的描述更為詳細(xì),它包含傳遞到手勢(shì)目標(biāo)的事件。第三種手勢(shì)類(lèi)型是平臺(tái)支持的拖放手勢(shì)。它最適合于傳輸數(shù)據(jù),也適用于應(yīng)用程序之間(不一定是FX)。此手勢(shì)類(lèi)型在
DragEvent
中有更詳細(xì)的描述。簡(jiǎn)而言之,當(dāng)按下鼠標(biāo)按鍵時(shí),會(huì)自動(dòng)激活簡(jiǎn)單的按下拖動(dòng)釋放手勢(shì),并將所有
MouseEvent
發(fā)送到手勢(shì)源。當(dāng)您開(kāi)始拖動(dòng)時(shí),DRAG_DETECTED
事件最終會(huì)到達(dá)。在其處理程序中,您可以通過(guò)在節(jié)點(diǎn)或場(chǎng)景上調(diào)用startFullDrag
方法來(lái)啟動(dòng)完整的按拖放手勢(shì)–MouseDragEvent
開(kāi)始傳遞到手勢(shì)目標(biāo),或者您可以通過(guò)在節(jié)點(diǎn)或場(chǎng)景上調(diào)用startDragAndDrop
方法來(lái)開(kāi)始拖放手勢(shì)-系統(tǒng)切換到拖放模式,DragEvent
開(kāi)始傳遞,而不是MouseEvent
。如果您不調(diào)用這些方法中的任何一個(gè),則簡(jiǎn)單的按拖放手勢(shì)將繼續(xù)。[…]
如果我正確理解了您的問(wèn)題,您希望能夠?qū)⑹髽?biāo)拖動(dòng)到多個(gè)節(jié)點(diǎn)上并讓它們做出反應(yīng),所有操作都在一個(gè)手勢(shì)中完成。您將需要使用完整的
按下-拖動(dòng)-釋放手勢(shì)即可完成此操作。如前所述,您必須偵聽(tīng)DRAG_DETECTED
事件并調(diào)用Node#startFullDrag()
或Scene#startFullDrag()
以激活完全按下-拖動(dòng)-釋放手勢(shì)。然后,您的用戶(hù)界面中的每個(gè)”正方形”都需要偵聽(tīng)MOUSE_DRAG_ENTERED
事件。請(qǐng)注意,事件類(lèi)型為MOUSE_DRAG_ENTERED
和非MOUSE_ENTERED
。
舉個(gè)例子:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
root.setPadding(new Insets(2));
root.setVgap(2);
root.setHgap(2);
// start full press-drag-release gesture
root.setOnDragDetected(
event -> {
if (event.getButton() == MouseButton.PRIMARY) {
event.consume();
root.startFullDrag();
}
});
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 12; j++) {
Rectangle rect = new Rectangle(50, 50, Color.WHITE);
rect.setStroke(Color.BLACK);
root.add(rect, i, j);
// detect MOUSE_DRAG_ENTERED events
rect.setOnMouseDragEntered(
event -> {
event.consume();
rect.setFill(Color.BLACK);
});
}
}
primaryStage.setTitle("MouseDragEvent Example");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
上述通過(guò)在根GridPane
上設(shè)置Node#onDragDetected
屬性來(lái)偵聽(tīng)DRAG_DETECTED
事件。請(qǐng)注意,如果您開(kāi)始在其中一個(gè)Rectangle
上拖動(dòng),則事件將向上冒泡到根,并由前面提到的處理程序處理。此外,由于您明確提到了左鼠標(biāo)按鍵,因此我添加了鼠標(biāo)按鍵是否為主按鍵的檢查。
然后,每個(gè)Rectangle
通過(guò)設(shè)置其Node#onMouseDragEntered
屬性來(lái)偵聽(tīng)MOUSE_DRAG_ENTERED
事件。僅當(dāng)完全按下-拖動(dòng)-釋放手勢(shì)生效時(shí),才會(huì)傳遞這些事件。
這篇關(guān)于在按住按鈕JavaFX的同時(shí)對(duì)多個(gè)節(jié)點(diǎn)進(jìn)行鼠標(biāo)拖動(dòng)檢測(cè)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,