2017-02-20 5 views
0

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); 
    } 
} 

Antwort

1

So etwas wäre in Ihrem Fall:

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); 

      tf.textProperty().addListener((observable, oldValue, newValue) -> { 
       valList[GridPane.getRowIndex(tf)][GridPane.getColumnIndex(tf)] = Integer.parseInt(newValue); 
      }); 
     } 

    } 
} 

Beachten Sie, dass Sie sollten Typprüfung für Felder wie so

+0

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

+0

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

Verwandte Themen