Mémo lors du tâtonnement et du développement à l'aide de JavaFX

Préface

C'est juste un mémo, donc c'est une question d'essais et d'erreurs et de choses sales. Même ainsi, si je pense à "mandokuse", je cherche un moyen qui semble plus facile à faire.

C'est pourquoi, fondamentalement, il ne s'agit pas de ce qui est écrit ici est correct ou incorrect, et l'ordre n'est pas en ordre. Ceci est ma commande d'essai. Vous ne devriez pas essayer d'obtenir quoi que ce soit d'ici parce que c'est foiré. Si vous cherchez toujours quelque chose, il vaut probablement mieux le chercher dans le tableau. (Puis-je rechercher dans la page?)

Je n'y regarde pas beaucoup parce que c'est une pause dans le travail, mais quand je reçois des conseils, je suis heureux en pleurant.

Étant donné que le contenu de l'article est erroné, il peut s'agir d'un article distinct pour chaque élément lorsqu'il est terminé (indécis)

Ce que vous essayez de faire

Des choses qui peuvent être résolues par vous-même. À l'école affectation gratuite. Placez des carrés et divers boutons sur l'écran dessiné par FX. Il est actionné par entrée manuelle et opération de bouton par l'utilisateur.

Je suis un nouveau venu, donc je n'affiche pas de fenêtre d'erreur. Laisser vomir sout ou serr.

Environnement et autres

Java (8) ... a été appris dans une certaine mesure (inexpérimenté) Essayez d'utiliser JavaFX (8), FXML. En tant qu'IDE, intelli JIDEA (ver.3.2) de l'instructeur Onunume semble avoir un peu changé l'interface utilisateur avec l'ajout récent d'Appde. La fonction de refactoring était si puissante qu'elle me démangeait dans de nombreux endroits lorsque j'utilisais eclipse.

Murs, couronnement, recherche

Je suis tombé sur un JavaFX inconnu.

À propos d'une simple correspondance

for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) {
  int idev3= i/3 , jdev3= j/3 ;

  int x= idev3 * 3 + jdev3 ,
      y= i % 3 * 3 + j % 3 ;

  subRegion[x][y] = cell[i][j]
//Puisque la fonction inverse devient une expression similaire (j'ai oublié le nom),[i][j]Quand[x][y]Même s'il est inversé, cela sert le but.
//  subRegion[i][j] = cell[x][y];
}

--À propos de la longueur du tableau à deux dimensions x = nouvel objet [i] [j]. --x.length est ʻi --x [0] .length est j. Cependant, si ʻi == 0, il lance ʻArrayIndexOutOfBoundsException.

Je souhaite afficher une entrée 9x9 dans JavaFX

Ceci est indispensable car il s'agit de résoudre le nombre.

Quand j'étais au collège, j'étudiais de manière expérientielle à l'école avec le nom provisoire de BASIC décimal, et quand j'ai essayé de le résoudre en jouant, j'ai entré 9 nombres (0 blanc) et 9 lignes en standard (? ), Mais je suis mort à cause de la saisie manuelle gênante. Puisqu'il s'agit d'un tableau, il n'y a pas de .contains (objet). J'avais l'habitude de dire "Arcana" pour.

Je prévois de n'entrer qu'ici et de le résoudre dans une autre classe, donc en codant autour de FX, il est normal d'utiliser un tableau.

Cependant, en premier lieu, je me demandais si un tableau pouvait être utilisé pour l'entrée FX. (Surtout lors de l'utilisation de FXML. En parlant d'échange de données compliqué ...)

Extraire les données du tableau dans FXML telles quelles

create array of Label using FXML in JavaFX - StackOverflaw

Si vous préparez une ArrayList avec fx: id =" myfxid " dans FXML, insérez-y les données de l'élément et appelez-la comme @FXML ArrayList myfxid; du côté du contrôleur, le contenu sera également inclus. Il peut être lu.

Mais si vous voulez créer 81 TextFields, vous devez préparer 81 à la main (copie et modification fine) sur FXML ou dupliquer sur sceneBuilder. C'est ennuyant.

Incorporer TextField dans TableView

(YouTube) JavaFX TableView | Adding TextField in tableView Cell

Utilisation des composants d'interface utilisateur JavaFX officiels d'Oracle TextView est intégré dans le cas de. Il semble qu'il soit nécessaire de mettre un setter ou un getter dans une classe qui fait une ligne pour chaque nom de TableColumn, donc je ne peux pas penser à une manière simplifiée d'écrire, donc le chemin

Ajouté depuis Controller, etc. à la mise en page FXML existante (primaryStage?)

C'était difficile à trouver de cette façon. Ou plutôt, il est sorti quand j'ai cherché un autre sujet.

Au début, j'ai pensé: "Vous devriez l'écrire au début comme avant", donc Parent root = FXMLLoader.load (getClass (). GetResource (" Example.fxml ")); Après cela, j'ai essayé de jouer avec depuis root.getChildren (). (Je ne savais pas si je pouvais jouer avec comme ça)

L'IDE m'a dit que ce n'était pas bon. Ne dit-il pas que vous ne pouvez pas le changer à partir du nom tel que "root.getChildrenUnmodifiable ()"? Comme ça. À partir de Oracle Sensei API Reference, il est en lecture seule. Il renvoie des données.

Cependant, il y avait le salut.

J'ai vu la méthode @Override initialize (/ * abréviation * /) dans la seconde moitié de la vidéo "Embedding TextField in TableView" un niveau ci-dessus. Parce que.

Si vous héritez de public class Controller implements Initializable {}, vous pouvez hériter de la méthode ʻinitialize` et y initialiser l'affichage FX (?).

C'est un peu vieux À propos du format du contrôleur JavaFX Diary de Tatsuno Otoshigo Il y a aussi une description dans.

Dans la vidéo ci-dessus, le processus de description de fx écrit dans ʻApplicationClass.start` dans le cas officiel a été écrit dans la méthode initialize.

Est-il possible de réécrire le contenu en manipulant la chose avec fx: id défini dans FXML avec Controller?

À propos de l'ordre d'exécution

Lorsque cela se produit, c'est l'ordre d'exécution qui est préoccupant. Quelque chose appelé "initialiseur" peut suivre un ordre d'exécution étrange, alors vérifiez-le avec la portée. Alors j'ai préparé ↓

TestApp.java


/*festival d'importation*/
public class TestApp extends Application {
  public static void main(String[] args) { launch(args); }

  @Override
  public void start(Stage primaryStage) throws IOException {
    System.out.println("set fxml 2 Parent root");
    Parent root = FXMLLoader.load(getClass().getResource("Test.fxml"));

    System.out.println("set root 2 scene");
    Scene scene =new Scene(root);

    System.out.println("set scene 2 primaryStage");
    primaryStage.setScene(scene);

    System.out.println("primaryStage.show");
    primaryStage.show();
  }
}

Test.fxml


<?xml version="1.0" encoding="UTF-8"?>
<!--?import tempête-->
<AnchorPane prefHeight="100.0" prefWidth="100.0" xmlns="http://javafx.com/javafx/8.0.172-ea" 
xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
   <children> <!--Tempête pour enfants--> </children>
</AnchorPane>

Controller.java


/*importation complète*/
public class Controller implements Initializable {
  @Override
  public void initialize(URL location, ResourceBundle resources) {
    System.out.println("initializerCalled");
  }
}

Je ne sais pas si c'est correct de lancer ʻIOE`, mais ça ressemble à ça. La sortie standard du résultat de l'exécution est ↓

set fxml 2 Parent root
initializerCalled
set root 2 scene
set scene 2 primaryStage
primaryStage.show

Process finished with exit code 0

En bref Commencez par Test.main et commencez par le lancement (la compréhension de ce domaine est ambiguë) Au fait, lisez fxml en disant FXMLLoader.load (fxml file), et lisez "(load)". Lorsque fxml est lu, le Controler.java spécifié par fx: controller est lu et" (fxml) " ʻLa méthode d'initialisation` est exécutée "(/ fxml)" (/ load) Et c'est tout! (Qu'est-ce que ça veut dire)

Il n'est pas possible d'écrire directement dans la racine Parent extraite par FXMLLoader.load écrite dans la partie supérieure (le début de la section FXML ~~ existante), mais elle est initialisée à partir du contrôleur spécifié dans le fichier fxml lors de son chargement. Si vous pouvez le faire, cela ressemble à ceci. J'ai réalisé ce que je voulais faire, alors je suis désolé.

Je me demande si la spécification de @ FXML est" Donnez-moi des informations s'il y a quelque chose avec un tel ID "à fxml qui essaie de se lire (Controller) quand il est lu.

J'ai écrit le code php avec echo dans l'instruction for de php et l'ai fait comme un tableau (\ $ _ val.1, \ $ _ val2 ... "\ $ _ val". \ $ _ I), mais celui-ci Je l'aime car il peut être décrit plus intuitivement.

Enfin (champ de saisie 9x9)

Préparez un GridPane avec ID en tant que conteneur côté FXML, Dans Controller.initialize, je définirai le TextField (tableau) qui correspond à l'intérieur.

En tant qu'idée, elle a été posée comme une question à teratail [Java FX] Comment organiser les images dans une grille [GUI] Le code du questionneur a été très utile. (En passant, la réponse qui vient avec peut être que la manière de penser les objets est maladroite. C'est une autre histoire si vous pouvez faire quelque chose comme imageView.clone (), mais il n'y a pas une telle méthode ... Eh bien, c'est un article assez ancien, et la description FXML et les spécifications internes peuvent être différentes. )

Code ci-dessous

En classe Controller



//Préparé à l'avance avec FXML. Les coordonnées XY à placer et la ligne de grille visible sont spécifiées côté FXML.
  @FXML GridPane inputGrid;

//Je voudrais faire une ligne lignée épaisse plus tard, alors rendez-le facile à changer.
  Double cellSize=30.0;

  @Override
  public void initialize(URL location, ResourceBundle resources) {

  //Nombre de colonnes dans le tableau
    int hnum = 9;    int vnum = 9;

  //La partie qui nécessite une entrée
    TextField[][] cellValues = new TextField[vnum][hnum];
        //Je donnerai chacun à nouveau plus tard, mais mémoire (pointeur(Ah)) N'est pas donné ou il crache visqueux.

    for (int i = 0; i < hnum; i++) {
      for (int j = 0; j < vnum; j++) {

        cellValues[i][j] = new TextField("");
        //Si vous n'appelez pas le constructeur et ne passez pas l'objet d'instance, après tout il crachera

    //PrefW côté TextView/Si vous spécifiez H, GridPane le redimensionnera en conséquence.
    //W côté Grid Pane/UTILISER H_COMPUTED_Définissons-le sur SIZE.
        cellValues[i][j].setPrefWidth(cellSize);
        cellValues[i][j].setPrefHeight(cellSize);
//Postscript:J'ai trouvé une méthode setPrefSize qui peut définir la largeur et la hauteur en même temps.
//Le bas fonctionne comme la même fonction que les deux lignes du haut
//      cellValues[i][j].setPrefSize(cellSize,cellSize);


    //Placez les valeurs de coordonnées sur le GridPane dans les options TextView
        GridPane.setConstraints(cellValues[i][j], i, j);
    //Spécifiez en tant qu'enfant
        inputGrid.getChildren().add(cellValues[j][i]);
//Postscript:Les deux lignes ci-dessus ont trouvé la méthode add exécutée en interne.
//Est-ce dû à la différence de version? Ci-dessous un exemple de description
//      inputGrid.add(cellValues[clmIndx][rowIndx],clmIndx,rowIndx);


      }//for j/
    }//for i/
  }// initialize/

Dans la mesure où l'opération de recherche est effectuée, il semble qu'il soit nécessaire de définir les différentes propriétés (positionnement) etc. avec la méthode "setProperty" une à une afin d'améliorer l'apparence sans utiliser FXML. Si vous décrivez un tel paramètre lié à l'apparence, la méthode de démarrage de ʻApplication.java` qui décrit start semble être longue.

En d'autres termes Laissez FXML (ou sceneBuilder) s'occuper de l'apparence. Lorsque l'ID est généré de manière exhaustive ou lorsque l'ordinateur est capable de répéter la description, réglez le contrôleur sur ʻInitializable et décrivez-le dans la méthode ʻinitialize.

Non limité à ce cas, lors de la création d'une application GUI avec JavaFX à l'aide d'une base de données ou d'un fichier qui gère des ressources préparées dans un format prédéterminé, je me demande si une telle méthode doit être prise. Ou.

Affichage de la bordure

La bordure est "GridLineVisible" dans les propriétés de GridPane, mais répondant Somewhere stackOverflow le souligne. Selon ce que je disais, "[Il est écrit pour le débogage dans le document api](https://docs.oracle.com/javase/jp/8/javafx/api/javafx/scene/layout/GridPane.html# gridLinesVisibleProperty) Ne l'utilisez pas. "

Au lieu de cela, la méthode css a été introduite, mais je veux rendre le groupe 3x3 plus facile à voir, donc un peu ... Si tel est le cas, il se peut que vous puissiez créer GridPane avec 3x3 et imbriquer GridPane (3x3), mais c'est également gênant.

En fin de compte, bien que j'aie défini et utilisé une constante appelée CELL_SIZE, elle est devenue assez sale.

Controller


  private void showRuler(Group group) {
    for (int i = 0; i <= 3; i++) {
      Line hline=new Line(CELL_SIZE*3*i,0,CELL_SIZE*3*i,CELL_SIZE*9);
      Line vline=new Line(0,CELL_SIZE*3*i,CELL_SIZE*9,CELL_SIZE*3*i);
      hline.setStrokeWidth(1.5);
      vline.setStrokeWidth(1.5);

      group.getChildren().addAll(hline,vline);
    }
  }

L'argument group spécifie le groupe qui inclut le GridPane qui dessine la bordure. Si vous spécifiez la position des coordonnées du groupe appelant dans FXML, vous n'avez pas besoin de spécifier layoutX ou layoutY de ce côté.

Dessiner avec Line lui-même semble sale et je n'ai pas l'intention de répondre à la mise à l'échelle. Créez quelque chose comme SimpleTableView. (Si vous voulez le faire, vous pouvez le faire.)

Ajouter des contraintes d'entrée

C'est un problème si la valeur d'entrée est une valeur entière, surtout si ce n'est pas un seul chiffre. Je veux autoriser seulement 0 à être entré comme 1 à 9 et le traiter comme vide.

Il semble qu'il existe différentes manières de procéder. Il semble qu'il vaut mieux l'utiliser correctement selon le but. [input] Quelle est la méthode recommandée pour créer un TextField numérique dans JavaFX? Blog de Yutchi - J'ai essayé de saisir uniquement des nombres de 0 à 9 dans TextField

Cela a également été utile lors du traitement d'expressions régulières telles que Formatter et Pattern. [Qiita - Bases des expressions régulières @sea_ship](https://qiita.com/sea_ship/items/7c8811b5cf37d700adc4#1-%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F% BE% E3% 81% AE% E5% 9F% BA% E6% 9C% AC% E3% 81% AB% E3% 81% A4% E3% 81% 84% E3% 81% A6)

J'ai choisi d'ajouter un écouteur modifié qui s'adapte intuitivement (?) Avec l'instruction if. Essayez de faire le son beap.

Ce qui suit est dans for (i) for (j) où TextField est placé dans GridPane dans la classe Controller

Controller.setInputGrid()


  TextField textField=new TextField("");

// add NumbersOnlyLimitation for the TextField
  textField.textProperty().addListener((observable, oldValue, newValue) -> {
    String str;
//    System.out.println(newValue);  //for debug
    if(newValue.matches("[0-9]?")){            // 0~Lorsque 9 est 1 caractère ou 0 caractère
//Accepter comme d'habitude
      str=newValue;
    }else if(newValue.matches("[0-9]{2}")) {   // 0~Quand 9 correspond à 2 caractères
//Acceptez la nouvelle entrée comme normale et rejetez l'ancienne valeur
      str=String.valueOf(newValue.charAt(1));
    }else{                                     //autre que ça
      Toolkit.getDefaultToolkit().beep();      //Péron(Son d'erreur)
//Aucun changement si la valeur précédente est normale. Autre que ça""
      str=oldValue.matches("[0-9]") ? oldValue : "" ; 
    }
    textField.setText(str); //J'ai écrit str parce que c'était difficile d'écrire celui-ci un par un
  });

  textField.setPrefSize(CELL_SIZE, CELL_SIZE);
  textField.setAlignment(Pos.CENTER);
  textField.setFont(Font.font("", FontWeight.BOLD,-1.0)); //Je voulais en faire un symbole gras, mais ça ne grossit pas...

  cellValues[clmIndx][rowIndx]=textField;
//la propriété est également incluse dans l'objet(?)Donc c'est cool.
//Ou plutôt, j'étais vraiment en colère quand j'ai essayé de créer un Listener sous forme de tableau

  inputGrid.add(cellValues[clmIndx][rowIndx], clmIndx, rowIndx);

Au début, quand ! NewValue.matches (" [^ 0-9] + "), la mémoire a commencé à remplacer par "" (ambigu)

De plus, si vous définissez «« [0-9] »« dans les correspondances, 0 caractère, c'est-à-dire «» ne sera pas accepté. La première chose qui m'est venue à l'esprit fut: "Il y avait une expression régulière dans le backspace, alors faisons-le quand elle est entrée!" Peut-être d'une manière que personne n'essaierait, une partie de la méthode d'écriture reste dans le code, mais je l'ai faite comme newValue.charAt (1) ==" \ b ", mais ce type va produire en masse Nurupo À mesure qu'il monte, la sortie standard devient rouge vif.

J'ai essayé une expérience en envoyant newValue à la sortie standard avec une colle comme "Qu'est-ce qu'il y a si ce n'est pas \ b?" (sout reste dans le commentaire) Lorsqu'il est backspaced, "" après avoir été backspaced devient une newValue, donc charAt (1) semble cracher visqueux.

Exemple d'entrée et de sortie lorsque sout est fait dans l'état ci-dessus Reproduire des lignes vides

contribution: a1b23\b8d
production:
a

1
1b
1
12
2
23
3

8
8d
8

\ b est l'espace arrière et la ligne vierge est telle que reproduite. À propos, si vous copiez et collez une chaîne de caractères arbitraire, tous les nombres à demi-largeur sauf un ou deux seront remplis et seul le dernier nombre entré sera entré. Même si vous copiez et collez la chaîne de caractères "" (rien), beap sonne un peu.

Contrainte d'entrée - est-ce correct?

Avec cette méthode, 81 objets ChangeListener sont créés, et je sens qu'il y a beaucoup de gaspillage ... Je me demande s'il peut être partagé en en faisant une méthode unique.

Donc, c'était ↓

Controller.setInputGrid()



//Hachage StringProperty Bean et mappe TextField
    HashMap<Integer,TextField> hashMap=new HashMap<Integer, TextField>(81,1f);

    ChangeListener<String> cl=new ChangeListener<String>() {
      @Override
      public void changed(ObservableValue<? extends String> observable, String oV, String nV) {
        String str;
        if(nV.matches("[0-9]?")){ /*Omission*/ str=FILLED_VALUE }

//Dirty cast rarement vu ce siècle
        StringProperty sp=(StringProperty)observable;
//    System.out.println(sp.getBean());
        hashMap.get(sp.getBean().hashCode()).setText(str);
      }
    };
    
    for (int clmIndx = 0; clmIndx < columnSize; clmIndx++) {
      for (int rowIndx = 0; rowIndx < RowSize; rowIndx++) {
        TextField textField=new TextField("");
        if(hashMap.containsKey(textField.textProperty().getBean().hashCode())) {
//Désolé sortie d'erreur. Si vous n'aimez pas les collisions de hachage, vous pouvez simplement stocker le bean tel quel ()
          System.err.println("textField.textProperty().getBean() Duplicated");
        }
        hashMap.put(textField.textProperty().getBean().hashCode(), textField);

//     System.out.println(textField.textProperty().getBean());

//  add NumbersOnlyLimitation for the TextField
        textField.textProperty().addListener(cl);

Je ne suis pas sûr de celui qui utilise le mieux la mémoire que le code d'origine. Ou plutôt, c'était définitivement de la merde en termes de lisibilité.

Préparez un conteneur qui accepte les entrées

Nous définirons une classe qui traite les données d'entrée sous une forme facile à manipuler. En enrichissant ceci tel quel, je voudrais simplifier la description dans la classe qui gère les données.

Ce que je veux surtout faire, c'est Préparez une classe "lecteur" qui lit les cellules du tableau pour chaque [ligne / colonne / sous-région 3x3] C'est.

Si vous voulez gérer si le nombre existe déjà ou non dans chaque groupe, préparez une chose pour lire 27 groupes de 9 colonnes, 9 lignes et 9 carrés (ci-après dénommés «région») à partir du tableau. Je devrais le donner.

De plus, lors de la résolution, par exemple, de "s'il y a n nombres qui ne peuvent tenir que dans les mêmes n endroits dans cette région, ces nombres ne rentreront pas dans d'autres endroits", soi-disant "pierre standard" Je veux aussi l'intégrer. (Bien que je pense que cela sera implémenté dans la méthode du côté de la résolution.)

Je voudrais subdiviser et préparer une liste de «nombres qui peuvent être entrés dans chaque» et «nombres qui ne peuvent pas être entrés» dans chaque cellule.

Je l'ai défini avec désinvolture, mais à partir de maintenant

"Cellule" est chaque cellule qui doit contenir une lettre pour résoudre le nombre «Région» est un groupe de nombres dans une cellule soumis à la restriction de duplication. Les régions sont ensuite divisées en «régions de ligne», «régions de colonne» et «sous-régions 3x3». (Le contenu du traitement est le même.) "Table" est une collection de toutes les cellules

Sera écrit. Cependant, le tableau peut être appelé «Conseil» sans préavis. C'est parce que nous l'avons appelé ainsi lorsque nous avons commencé le développement.

En manipulant des données partagées

En Java, les pointeurs en langage C sont appelés «variables de référence» ou «valeurs de référence».

Je veux que chaque région stocke la valeur de référence afin qu'elle puisse être traitée avec uniquement le groupe de données de la cellule pour une table. En d'autres termes, je souhaite modifier les données des cellules existantes dans le tableau en opérant à partir de la région.

Ce qui suit est un diagramme d'image qui ne se connecte pas

Cell Region image

Passer par valeur? Passer par référence? Stratégie d'évaluation? Qu'est-ce que c'est.

À ce stade, je me demandais, "Java peut-il traiter des données comme des pointeurs?", J'ai donc examiné diverses choses. Je ne peux plus dire qu'il est passé par référence Cet article a été très utile. J'ai même lu la dernière diapositive de "Matériaux d'hiver 2018 qui ne peuvent pas être appelés par référence". "La théorie du" passage par référence "! ?? Je pense que je pourrais comprendre (je pense (très mal à l'aise)) par l'exemple dans la section "" ou "passer par valeur" qui a été répété 5 fois sur la diapositive.

J'ai aussi lu Résumé du problème Java "passe par référence" @acevif et je l'ai résumé à ma manière.

Si tel est le cas, essayez de l'écrire comme C.

La syntaxe des couleurs est Java


private void method(ArrayList<String> **arg){
    *arg = new ArrayList<String>();
    **arg.add("PHP");
}

ArrayList<String> **list = new ArrayList<String>(); //Je me sens un peu mal à l'aise ici
**list.add("Java");
method(list);
System.out.println(**list);    // [Java]

C'est une description qui donne l'impression de se battre en deux langues, donc elle incluait un style d'écriture très désagréable, mais intuitivement, c'est le cas.

[^ 1]: Pour être honnête, le mot japonais "Je le remets" était génial. Lors de la traduction en anglais, je peux seulement dire qu'une telle traduction est correcte parce que j'utilise "par" qui ne peut être traduit qu'avec "de". Le texte original est "appeler par référence ou passer par référence". (Résumé du problème Java "passe par référence" @acevif). C'est un peu hors sujet, mais après un rapide coup d'œil à l'origine de by, hits est passé de "périphérie" à "proche", À son tour, il est appelé «côté» et «secondaire».

Une autre analogie ou information détaillée

Le professeur que j'enseignais a dit plus tôt dans la classe Java: «En Java, nous n'utilisons fondamentalement pas le mot pointeur, mais toutes les variables autres que les types primitifs, c'est-à-dire les types de référence, sont toutes. J'ai l'impression de comprendre maintenant le sens du mot «parce que c'est un pointeur».

Si vous passez l'argument réel ʻint * val à l'argument formel ʻint * arg, Dans la notation du langage C, la variable de pointeur ʻarg peut changer * valen changeant la destination* arg pointée par le pointeur. Si vous changez la destination du pointeur de ʻarg dans la fonction, Puisque ʻarg! = Valest défini,* val n'est pas changé même si * arg` est changé. Comme.

Dans tous les cas, j'ai l'impression de comprendre le sens du mot «passant par valeur» à partir de la conclusion du propriétaire de l'article «valeur» appelée «valeur de référence».

Vous devez lire correctement l'article de wikipedia sur la «stratégie d'évaluation» mentionné dans l'histoire. (C'est aussi en anglais)

D'ailleurs, avant de lire ces articles, j'ai utilisé le pointeur de ** type primitif ** int array int [] [] cell, par exemple cell [i] [j], vers rowRegion [i] .get (j). ) Est mort en essayant de s'adapter. Ou plutôt, je ne savais pas qu'il n'y avait pas du tout assez d'informations. Quand j'ai essayé d'écrire un problème sous forme d'article ici, j'ai d'abord pensé "Je veux gérer quelque chose comme un pointeur", commencé par "Qu'est-ce qu'un pointeur Java?", Et j'ai rencontré l'article ci-dessus. C'est comme ressentir ...

... Puisqu'un élément d'un tableau d'objets de type primitif est un type primitif, j'essayais de faire quelque chose de déraisonnable en Java, qui ne passe que par valeur. Eh bien, je pense que cela peut être fait en créant une classe simple qui a un type int comme membre.

L'histoire d'avant

Avant de connaître le passage des prix, ma malchance.

  1. Créez une "classe Table statique" et une "classe Region qui hérite de ArrayList " dans la classe Board et préparez un "champ de cellule de type int [] [] statique" dans la classe Table. , Essayez de créer une méthode pour retourner "un objet Region avec la cellule [i] [j]" dans la classe Board.
  2. Afin de faciliter le fonctionnement de la cellule en insérant ij comme les coordonnées (x, y), afin de faciliter le fonctionnement de la cellule, la méthode pour faire fonctionner le champ int i, j et la cellule est ajoutée à la classe ** Table. Commencez à écrire à l'intérieur. ** **
  3. Au moment d'essayer d'ajuster l'objet Table dans l'objet Region, il devient "!!?" Et crée rapidement une classe PosXY et la place dans la classe Table.
  4. Je remarque qu'une méthode avec un nombre considérable d'appels est difficile à appeler new ArrayList <> () à chaque fois qu'elle est appelée.
  5. Je me demande si je peux en quelque sorte faire en sorte que chaque élément de la cellule [] [] ressemble à un pointeur.
  6. Commencez à décrire à partir de «[#Préparer un conteneur qui accepte une entrée](#Préparer un conteneur qui accepte une entrée)» pour échapper à la réalité.
  7. Non, faites un cours. Teka int [] [] Qu'est-ce que la cellule? Créer une classe Cell ← Maintenant ici

...........^q^) alors

Je vais concevoir la classe Cell.

Préface à la description de conception de chaque classe

Je l'ai écrit au début, et si vous lisez le contenu, vous le comprendrez, et comme vous auriez dû l'écrire dans le profil, vous pouvez le comprendre,

Je suis un débutant en croquant. Peu importe ce que vous faites, je pense que ce sera un pauvre, alors pardonnez-moi s'il vous plaît. (Les commentaires tels que les critiques et les mesures d'amélioration sont les bienvenus.) Même les débutants de la même classe ne devraient pas l'utiliser comme référence. Même si vous l'utilisez comme référence, obtenons l'avis de l'éducateur.

Conception de classe de cellule

En principe, Cell est considérée comme l'une des lignes disposées comme un tableau. Par conséquent, la méthode de fabrique limite la génération d'instances en ne sortant que des tableaux à deux dimensions. L'objet de cellule de sortie et le nom en tant que masse sont ** cellule **, Plusieurs groupes de cellules (Cell [] []) ont été nommés ** ensemble de cellules **.

De plus, j'ai décidé d'exprimer l'action de mettre un nombre dans le carré, c'est-à-dire d'attribuer un nombre à la valeur et de le confirmer, comme "remplissage". En anglais, c'est Fill. Même si vous le faites de plusieurs façons, vous pouvez dire quelque chose comme "remplir 3 ici".

Vous trouverez ci-dessous un résumé le plus approximatif possible.

--Champ --Pos pos: un objet de classe Pos qui indique sa position sur l'ensemble de cellules. Pour expliquer brièvement la classe Pos, elle a des numéros de ligne et des numéros de colonne comme champs, et est responsable de la limitation de leur traitement et de leur traitement à l'aide des numéros de ligne et des numéros de colonne utilisés lors de l'utilisation d'une sous-région 3x3. --ʻInt value: Le nombre enterré dans la cellule. Le blanc est 0 --boolean [10] possible: Stocke si le numéro correspondant au numéro d'élément peut être rempli ou non dans cette cellule. Autrement dit, s'il existe une possibilité que 5 soit dans la cellule, possible [5] == true` --Constructeur

Pour l'écrire ensemble,

C'est comme ça? Au moment où j'écris ceci, je me demande s'il n'est pas nécessaire d'avoir le numéro de ligne et le numéro de colonne dans la cellule elle-même, mais pourquoi pas? En supposant qu'il soit appelé par cells [i] [j] comme élément du tableau, je me demande si c'est nécessaire. Pour moi, ce serait bien s'il y avait un HashMap qui avait deux types de clés. Si vous ne spécifiez qu'une seule clé, une «liste de lignes» itérables apparaîtra.

Post-scriptum (19/02/01) J'ai décidé de laisser la classe Table attraper l'objet au lieu du tableau. Après tout, je pensais que la relation de mémoire n'était pas bonne. Voir la classe Table pour plus de détails.

Copy constructor does not copy field boolean[]

Lorsque vous utilisez IDEA, les avertissements et les suggestions sont affichés sur la barre de défilement. Les rouges sont le genre de choses qui causent généralement des erreurs de compilation, et ils ne se compileront que si vous les corrigez. Les jaunes sont "Utiliser uniquement dans cette méthode, n'est-ce pas privé?" Ou "Je donne la valeur de ce champ, mais je ne l'utilise pas!" Ou "L'expression conditionnelle de cette instruction if est toujours vraie, mais je n'en ai pas besoin." Il y a beaucoup de choses telles que «non», mais cette fois, je vais aussi m'en soucier.

Il y avait quelque chose qui ne pouvait pas être oublié (en-tête).

La phrase réelle était "" possible "" au lieu de "boolean []". IDEA augmentera les informations en appuyant sur More, donc si vous regardez le contenu de more,

Reports copy constructors that dont copy all fields in the class. Fields with the modifier transient are considered unnecessary to copy

Hmm? e? Je sais que tu dis quelque chose de possible sans transitoires, La première ligne est "Il y a un champ qui n'a pas été copié", et la deuxième ligne est "Si vous ajoutez transitoire, il est considéré comme quelque chose qui n'a pas besoin d'être copié"? Réveillez Wakame.

Je vais vous montrer la partie où la déclaration ou l'avertissement a été émis

Cell


//Diverses omissions

private boolean[] possible = new boolean[10];

private Cell(@NotNull Pos pos, int value) {

//  initialize pos
  this.pos = pos;

//  initialize Value
  setValue(value);

//  initialize possible[]
  if (value <0 | 9< value) {
    System.err.println("Cell constructor : out of range(==[0,9]) value");
    System.err.println("                     where pos points > "+pos.getStringIJ());
  } else if (isFilled()) {
    possible[value] = true;
  } else {
    for (int i = 0; i < possible.length; i++) {
      possible[i] = true;
    }
  }
}

private Cell(@NotNull Cell cell){     // Copy constructor does not copy field "possible"
  this(cell.getPos(),cell.getValue());
}

Le texte d'avertissement était incohérent et j'étais dans un état hatena, alors j'ai expérimenté.

À l'intérieur de la classe Cell



  public static void main(String[] args) { //Écriture solide principale dans la classe

    int[][] x={{0}};                      //Créez des valeurs avec un seul élément à tester
    Cell[][] cell1= makeCellArray(x);     //Au fait, la contrainte 9x9 se fait dans la classe Board.
    cell[0][0].deny(2);                   //Cette opération est possible[2]Est devenu faux

    Cell[][] cell2=cloneCells(cell1);      //Le constructeur appelé par cloneCells est Cell(Cell cell)。...Un peu compliqué

    System.out.println("cell1");
    for (boolean t:cell1[0][0].possible){  //Demandez à foreach d'extraire tout le contenu du tableau possible.
      System.out.print(" "+( t?1:0 ));     //Un opérateur ternaire occasionnel. Rendre true false la même sortie que le langage C
    }

    System.out.println(); //nouvelle ligne

    for (boolean t:cell2[0][0].possible){  //possible est un accès privé, mais c'est cool car il est dans la même classe
      System.out.print(" "+( t?1:0 ));
    }
    System.out.println();
    System.out.println("cell2");
  }

Production


cell1
 1 1 0 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
cell2

Ahhhhhh! !! !! !! !! !! Ah ~ ===== ~ = ~ == ~ = ~ =! !! !! !!

C'est tout. La valeur booléenne qui n'a pas été initialisée est false. Là bas. Le côté constructeur fait le travail d'initialisation possible avec la valeur 0, mais les informations que "2 n'entre pas" ne sont pas transmises. (J'ai remarqué en écrivant cet article.)

J'ai scellé la méthode de clonage de la cellule, mais pas le clone du champ! C'est pourquoi j'ai décidé de passer possible.clone. ... je n'ai pas besoin d'appeler le constructeur ...

... réécrit.


Eh bien, mais l'histoire ne s'arrête pas là. C'était éphémère que je m'intéressais à passer. Nanikore

Pour le moment, quand j'ai mis possible à transitoire et exécuté le code avant modification, cell2.possible [2] est devenu faux (!!!!!!) Qu'est-ce que c'est?

Enquêter et m (je suis un peu fatigué d'écrire des articles, d'enquêter, de coder, etc., alors je vais jouer au jeu. Je ne disparaîtrai pas. Je continuerai demain)

Postscript (19/01/13) Je l'oublierai si je le jette plus tard () todo écriture

// todo: transitoire

Post-scriptum (19/02/01) Jusqu'à ce qu'il soit terminé (fusion), je l'ai pressé sans aucune sortie ici, donc ce qui suit est comme la trajectoire jusqu'à ce point.

Classe de région

Puisque j'ai ajouté diverses fonctions supplémentaires, je n'expliquerai que la méthode principale utilisée à l'état terminé (provisoire). `Avant, je disais" j'aime les tableaux ", mais finalement c'est devenu une ArrayList. ''

Region.java


public boolean valueFill(int value) {
  boolean changed = false;
  for (int i = 0; i < CellLength; i++) {
      changed |= get(i).deny(value);
    }
  }
  return changed;
}

Lorsque region.get (index) .tryFill (value) == true (En d'autres termes: si vous réussissez à renseigner ** value ** dans ** _index _ ** th cell dans la région) Un autre cells(: = indexOf (cells [i])! =** _index _ **) ʻ dans la même région ne peut pas être rempli avec ** _value _ **, donc En appelant cette méthode dans la classe qui contiendra la région Assurons-nous que ** _ value _ ** est cell.deny (value)` dans cells autre que cell automatiquement, Méthode faite avec l'intention ** return ** Valeur booléenne que la mise à jour s'est produite à la suite de cet appel de méthode (si la valeur de retour de cell.deny est vraie)

Classe de table

Créé en héritant de java.util.HashMap. Stockez les données avec pos comme clé et cellule comme valeur. Il a une méthode getEmptyCells qui renvoie une liste de cellules avec des valeurs non remplies.

Classe de conseil

Une classe qui a un tableau et un tableau de région (9 chacun pour les lignes, colonnes et sous-marins, totalisant 27) dans le champ, et les intègre et les exploite. La taille que vous avez seulement à nouveau lors de la création d'un duplicata. Créez un doublon en passant un objet de carte au constructeur. Je l'ai écrit pour exclure le facteur d'anxiété lorsque je veux faire une copie profonde.

De plus, nous préparerons une méthode pour exécuter Cell :: tryFill et Region :: valueFill, et l'utiliserons comme une "méthode pour remplir la valeur" de la classe NPS décrite plus loin.

Classe NumberPlaceSolver

Je l'ai écrit en tant que classe qui exécute un groupe d'algorithmes pour résoudre réellement les mathématiques. En tant que champ

avoir.

J'ai écrit une classe "Algorithm" qui stocke les méthodes en tant que classe interne. WANT todo: Traitement tel que l'exécution de toutes les méthodes écrites dans un endroit comme "liste de méthodes"

Pour l'instant, seul le «stockage temporaire» est implémenté. Lors d'un placement temporaire, une nouvelle instance de NumberPlaceSolver doit être créée avec l'emplacement et la valeur de la cellule temporairement placée et le «statut actuel (this)» comme arguments.


L'histoire qui était dans le mauvais ordre

Au début, je pensais que je pensais: "Faisons-le du côté de l'utilisateur!"

Créez un écran, créez une classe NPS et ... créons une classe Cell! (←!?)

Parce que c'est devenu, c'est devenu un design avec beaucoup de méthodes inutiles et de gaspillage. En outre, c'était le but initial J'ai abandonné l'implémentation de "Placer temporairement plusieurs threads en même temps et refuser chacun d'entre eux. De plus, en refusant une table statique, plusieurs valeurs peuvent être refusées en même temps" (? ), Donc la direction était assez différente de ce à quoi je m'attendais. Il a été complété pour pouvoir être résolu, mais cela prendrait beaucoup de temps s'il n'était pas rempli à plus de la moitié, alors je voudrais l'améliorer.

Recommended Posts

Mémo lors du tâtonnement et du développement à l'aide de JavaFX
Un mémorandum lors de la tentative de création d'une interface graphique à l'aide de JavaFX
[Mémo personnel] Écriture d'un fichier à l'aide de BufferedWriter
[Rails] [Note] Quand ajouter = à <%%> et quand pas
Sortie à l'aide de méthodes et de constantes Mémo d'apprentissage
[Mémo personnel] Lecture de fichiers à l'aide de BufferedReader
Un mémo pour créer un formulaire simple en utilisant uniquement HTML et CSS dans Rails 6
Lors de l'utilisation d'une liste en Java, java.awt.List sort et une erreur se produit
Un simple jeu de ciseaux-papier-pierre avec JavaFX et SceneBuilder
Lors de l'exécution d'une jointure externe complète sans utiliser de jointure externe complète
JavaFX et HiDPI
Une note sur "Ne pas émettre une erreur de certificat avec un certificat auto-signé à l'aide de Keytool Java"
Afficher une image de chargement dans JavaFX puis afficher une autre image
Comment convertir A en A et A en A en utilisant le produit logique et la somme en Java
Un mémorandum lors de l'installation de Docker et de la construction d'un conteneur Linux
Remarques à vérifier lorsque vous essayez d'utiliser Lombok
Un mémo lors de l'obtention du numéro entrant à l'aide de Broadcast Receiver sur Android 9/10 ne fonctionne pas