Ich habe 100 Textfelder erstellt und in ein GridPane eingefügt. Der Benutzer hat die Möglichkeit, den Wert in einem Textfeld zu ändern. Ich muss in der Lage sein, diesen geänderten Wert zu registrieren, so dass meine Schaltfläche, um das Sub-Quadrat der maximalen Größe zu finden, ordnungsgemäß funktioniert. Da die Textfelder in einer Schleife erstellt wurden, muss ich darauf achten, wie man in einem einzelnen Textfeld auf Änderungen achtet.Wie erstelle ich einen ChangeListener für 100 Textfelder, die in einer Schleife erstellt wurden?
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import static java.lang.Math.rint;
public class Exercise22_19 extends Application {
//declare a gridpane here so that methods have easy access
GridPane gp1;
int[][] valList;
@Override
public void start(Stage primaryStage) {
//stack pane to hold the gridpane; makes it easy to keep the grid
//centered in the stage
StackPane root = new StackPane();
///gridpane to hold the 10x10 matrix of textfields
gp1 = new GridPane();
gp1.setPadding(new Insets(5, 5, 5, 5));
//center the gridpane in the stackpane
gp1.setAlignment(Pos.CENTER);
root.getChildren().add(gp1);
setNumbers();
//refresh button: refills matrix with new values
Button refreshBt = new Button("Refresh");
//call the function to reset the values in the matrix when the refresh
//button is clicked
refreshBt.setOnAction(e -> setNumbers());
//findLargestBlock button finds the largest square block of 1's in the
//matrix
Button lrgBlkBt = new Button("Find Largest Button");
//call the function to find the largest square block of 1's when the
//find button is clicked
lrgBlkBt.setOnAction(e -> findBigBlock());
//makes a space between the last row of numbers and the buttons. Even
//though it is onle set on one button, it affects the entire row
GridPane.setMargin(refreshBt, new Insets(5, 5, 5, 5));
//add buttons to gridpane
//refresh spans 3 columns
gp1.add(refreshBt, 1, 10, 3, 1);
//find spans 6 columns
gp1.add(lrgBlkBt, 4, 10, 6, 1);
Scene scene = new Scene(root);
primaryStage.setTitle("Exercise 22_19 (Dynamic)");
primaryStage.setScene(scene);
primaryStage.show();
}
//set all textfield values in the matrix to 0 or 1
public void setNumbers() {
//gridpane does not have a method to access the value of a node in the
//gridpane, so I will store the values in an array.
valList = new int[10][10];
for (int i = 0; i < 10; i++) {
for (int k = 0; k < 10; k++) {
TextField tf = new TextField();
tf.setPrefWidth(25);
//set the value of the text field to 0 or 1
//create a random 0 or 1 integer
int val = (int)(rint(Math.random()));
//fill the array with the values
valList[i][k] = val;
String valStr = String.valueOf(val);
tf.setText(valStr);
//add text fields to gridpane
GridPane.setConstraints(tf, k, i);
gp1.getChildren().add(tf);
}
}
}
//find the largest square block of 1's in the matrix
public void findBigBlock() {
//size of square matrix
int n = 10;
//max tells the size of the largest square sub-maxtrix, e.g. if max==3,
//the largest sub-matrix is a 3x3 matrix
int max = 0;
int maxRow = 0;
int maxCol = 0;
//color for the textbox; red
Paint tfColor = Paint.valueOf("FF0000");
int[][] arr = new int[10][10];
//copy first row to new array
System.arraycopy(valList[0], 0, arr[0], 0, 10);
//copy first col to new array
for (int i = 0; i < n; i++) {
arr[i][0] = valList[i][0];
}
//determines the size and location of the maximum sub-square
for (int row = 1; row < n; row++) {
for (int col = 1; col < n; col++) {
if (valList[row][col] == 1) {
arr[row][col] =((Math.min(valList[row][col-1],
(Math.min(valList[row-1][col], valList[row-1][col-1])))) + 1);
if (arr[row][col] >= max) {
max = arr[row][col];
maxRow = row;
maxCol = col;
}
}
else
arr[row][col] = 0;
}
}
//replaces the normal textfields with red textfields for the maximum
//sub-square
for (int i = max; i > 0; i--) {
for (int j = maxRow; j > maxRow - max; j--) {
for (int k = maxCol; k > maxCol - max; k--) {
//create a nex textfield
TextField tf = new TextField();
tf.setPrefWidth(25);
//set color to red
tf.setStyle("-fx-control-inner-background: #"+tfColor.toString().substring(2));
tf.setText(String.valueOf(valList[j][k]));
//put the red textfield into the gridpane
GridPane.setConstraints(tf, k, j);
gp1.getChildren().add(tf);
}
}
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
Dank hinzufügen. Es muss etwas mit einem meiner Algorithmen nicht stimmen. Das Programm hebt nur eine 2x2 Box hervor. Selbst wenn ich die Werte in den Textfeldern ändere, um einen größeren Block zu erzeugen, wird nur gelegentlich ein Rechteck und kein Quadrat erkannt. – so8857
Ich bin mir nicht sicher, ob ich verstehe, was der richtige Algorithmus ist, aber soweit ich das beurteilen kann, wird die Zeile 'max = arr [row] [col];' falsch berechnet – Enigo