我在一個程式中有一個包含 100 個 javafx 標簽的網格,它使用了我在 scenebuilder 中制作的 gui。我正在嘗試進行設定,因此每當您單擊標簽時,標簽都會變為綠色。
我在二維陣列串列中有標簽。我使用嵌套的 for 回圈遍歷串列,然后使用 setOnMouseClicked 函式設定滑鼠事件,而不是為所有 100 個標簽創建函式。
但是,我無法訪問 EventHandler 方法中的 for 回圈控制變數。
for (int i = 0; i < 10; i )
{
for (int j = 0; j < 10; j )
{
labels.get(i).get(j).setOnMouseClicked(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
labels.get(i).get(j).setTextFill(Color.GREEN);
}
});
}
}
Local variable i defined in an enclosing scope must be final or effectively final
該錯誤僅在 eclipse 中為“i”彈出,但我認為它會影響兩者。
解決這個問題有什么不同的方法?我不必使用回圈來設定滑鼠事件,這只是我嘗試解決設定要單擊的 100 個標簽的問題。
uj5u.com熱心網友回復:
這實際上是以下內容的副本:
import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.TilePane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.util.ArrayList; import java.util.List; import static javafx.scene.paint.Color.GREEN; public class MultiLabelApplication extends Application { private static final int N_ROWS = 5; private static final int N_COLS = 5; @Override public void start(Stage stage) { Label lastClicked = new Label("No Selection"); lastClicked.setPadding(new Insets(10)); TilePane grid = new TilePane(5, 5); grid.setPrefRows(N_ROWS); grid.setPrefColumns(N_COLS); grid.setMinSize(TilePane.USE_PREF_SIZE, TilePane.USE_PREF_SIZE); grid.setMaxSize(TilePane.USE_PREF_SIZE, TilePane.USE_PREF_SIZE); List<List<Label>> labels = new ArrayList<>(new ArrayList<>()); for (int i = 0; i < N_ROWS; i ) { final int row = i; labels.add(new ArrayList<>()); for (int j = 0; j < N_COLS; j ) { final int col = j; final Label label = new Label(row "," col); label.setPadding(new Insets(10)); label.setOnMouseClicked(event -> { label.setTextFill(GREEN); lastClicked.setText( "Last clicked row: " row ", col: " col ); }); labels.get(row).add(label); grid.getChildren().add(label); } } VBox layout = new VBox(10, lastClicked, grid); layout.setPadding(new Insets(10)); Scene scene = new Scene(layout); scene.getStylesheets().add(CSS); stage.setScene(scene); stage.setResizable(false); stage.show(); } public static void main(String[] args) { launch(); } public static final String CSS = "data:text/css," // language=CSS """ .root { -fx-font-size: 16px; -fx-background-color: cornsilk; } .label { -fx-background-color: palegreen; -fx-text-fill: darkgreen; } TilePane .label { -fx-background-color: lightblue; -fx-text-fill: navy; } """; }uj5u.com熱心網友回復:
使用@jewelsea 的回答,我想向您展示另一種不使用的方法
final. 不知道有沒有什么缺點或者坑。您可以
MouseEvent通過呼叫 來確定按下了哪個節點event.getSource()。請參閱下面的更改代碼。import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.TilePane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.util.ArrayList; import java.util.List; import static javafx.scene.paint.Color.GREEN; public class App extends Application { private static final int N_ROWS = 5; private static final int N_COLS = 5; @Override public void start(Stage stage) { Label lastClicked = new Label("No Selection"); lastClicked.setStyle("-fx-background-color: palegreen; -fx-text-fill: darkgreen; -fx-font-size: 16px;"); lastClicked.setPadding(new Insets(10)); TilePane grid = new TilePane(5, 5); grid.setPrefRows(N_ROWS); grid.setPrefColumns(N_COLS); grid.setMinSize(TilePane.USE_PREF_SIZE, TilePane.USE_PREF_SIZE); grid.setMaxSize(TilePane.USE_PREF_SIZE, TilePane.USE_PREF_SIZE); grid.setStyle("-fx-background-color: cornsilk;"); List<List<Label>> labels = new ArrayList<>(new ArrayList<>()); for (int i = 0; i < N_ROWS; i ) { final int row = i; labels.add(new ArrayList<>()); for (int col = 0; col < N_COLS; col ) { Label label = new Label(row "," col); label.setPadding(new Insets(10)); label.setStyle("-fx-background-color: lightblue; -fx-text-fill: navy; -fx-font-size: 16px;"); label.setOnMouseClicked(event -> { Label tempLabel = ((Label)event.getSource()); tempLabel.setTextFill(GREEN); lastClicked.setText("Last clicked row: " tempLabel.getText()); }); labels.get(row).add(label); grid.getChildren().add(label); } } VBox layout = new VBox(10, lastClicked, grid); layout.setPadding(new Insets(10)); stage.setScene(new Scene(layout)); stage.setResizable(false); stage.show(); } public static void main(String[] args) { launch(); } }
uj5u.com熱心網友回復:
當您實體化每個 EventHandler 類時,回圈變數
i并j存在。然而,在兩個回圈完成創建偵聽器之后,這兩個變數就消失了。您需要做的是將坐標(i 和 j)傳遞給偵聽器。
for (int i = 0; i < 10; i ) { for (int j = 0; j < 10; j ) { labels.get(i).get(j).setOnMouseClicked(new EventHandler<MouseEvent>(i, j){ private int i; private int j; public EventHandler<MouseEvent>(int iIn, int jIn ) { i = iIn; j = jIn; } @Override public void handle(MouseEvent event) { labels.get(i).get(j).setTextFill(Color.GREEN); } }); } }嗯,我實際上并沒有對此進行測驗,但我之前已經將變數傳遞給偵聽器類,盡管這些類是嵌套的而不是行內的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/467931.html
