Memo beim Tappen und Entwickeln mit JavaFX

Vorwort

Es ist nur ein Memo, also ist es eine Frage von Versuch und Irrtum und schmutzigen Dingen. Trotzdem suche ich, wenn ich an "Mandokuse" denke, nach einem Weg, der einfacher zu sein scheint.

Deshalb geht es im Grunde nicht darum, ob das, was hier geschrieben ist, richtig oder falsch ist und die Reihenfolge nicht in Ordnung ist. Dies ist meine Probebestellung. Sie sollten nicht versuchen, etwas von hier zu bekommen, weil es durcheinander ist. Wenn Sie immer noch nach etwas suchen, ist es wahrscheinlich besser, es in der Tabelle zu suchen. (Kann ich innerhalb der Seite suchen?)

Ich schaue es nicht sehr genau an, weil es eine Pause von einer Hand der Arbeit ist, aber wenn ich Ratschläge oder etwas bekomme, bin ich glücklich beim Weinen.

Da der Inhalt des Artikels verirrt ist, kann es sich bei jedem Artikel um einen separaten Artikel handeln, wenn er beendet ist (unentschlossen).

Was du versuchst zu machen

Dinge, die Sie selbst lösen können. In der Schule freie Aufgabe. Platzieren Sie Quadrate und verschiedene Schaltflächen auf dem von FX gezeichneten Bildschirm. Die Bedienung erfolgt durch manuelle Eingabe und Tastenbedienung durch den Benutzer.

Ich bin ein Neuling, daher zeige ich kein Fehlerfenster an. Lassen Sie Sout oder Serr sich übergeben.

Umwelt und andere

Java (8) ... wurde bis zu einem gewissen Grad gelernt (unerfahren) Versuchen Sie es mit JavaFX (8), FXML. Als IDE scheint Intelli JIDEA (Version 3.2) des Lehrers Onunume die Benutzeroberfläche mit der kürzlich hinzugefügten Appde ein wenig verändert zu haben. Die Refactoring-Funktion war so stark, dass es an vielen Stellen juckte, als ich Eclipse verwendete.

Wände, Bewältigung, Forschung

Ich bin auf ein unbekanntes JavaFX gestoßen.

Über eine einfache Korrespondenz

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]
//Da die Umkehrfunktion zu einem ähnlichen Ausdruck wird (ich habe den Namen vergessen),[i][j]Wann[x][y]Auch wenn es umgekehrt ist, erfüllt es den Zweck.
//  subRegion[i][j] = cell[x][y];
}

Ich möchte 9x9-Eingaben in JavaFX anzeigen

Dies ist unabdingbar, um die Zahl zu lösen.

Als ich in der Junior High School war, habe ich in der Schule experimentell mit dem vorläufigen Namen Dezimal BASIC gelernt, und als ich versuchte, es durch Spielen zu lösen, gab ich 9 Zahlen (Leerzeichen sind 0) und 9 Zeilen als Standard (?) Ein. ), Aber ich bin wegen der mühsamen manuellen Eingabe gestorben. Da es sich um ein Array handelt, gibt es keine .contains (Objekt). Ich habe immer "Arcana" für gesagt.

Ich habe vor, nur hier einzugeben und es in einer anderen Klasse zu lösen. Beim Codieren um FX ist es also in Ordnung, ein Array zu verwenden.

Zunächst habe ich mich jedoch gefragt, ob ein Array für die FX-Eingabe verwendet werden kann. (Besonders bei Verwendung von FXML. Apropos komplizierter Datenaustausch ...)

Extrahieren Sie Array-Daten in FXML so wie sie sind

create array of Label using FXML in JavaFX - StackOverflaw

Wenn Sie eine ArrayList mit fx: id =" myfxid " in FXML vorbereiten, fügen Sie die Elementdaten ein und nennen Sie sie wie @FXML ArrayList myfxid; auf der Controllerseite. Der Inhalt wird ebenfalls eingeschlossen. Es kann gelesen werden.

Wenn Sie jedoch 81 TextFields erstellen möchten, müssen Sie 81 manuell in FXML vorbereiten (kopieren und fein modifizieren) oder in sceneBuilder duplizieren. Es ist nervig.

Betten Sie TextField in TableView ein

(YouTube) JavaFX TableView | Adding TextField in tableView Cell

Arbeiten mit offiziellen JavaFX-UI-Komponenten von Oracle TextView ist im Fall von eingebettet. Es scheint notwendig zu sein, einen Setter oder Getter in eine Klasse einzufügen, die für jeden TableColumn-Namen eine Zeile erstellt, daher kann ich mir keine vereinfachte Schreibweise vorstellen, also den Pfad

Vom Controller usw. zum vorhandenen FXML-Layout hinzugefügt (primaryStage?)

Es war schwer, diesen Weg zu finden. Oder besser gesagt, es kam heraus, als ich nach einer anderen Sache suchte.

Zuerst dachte ich: "Sie sollten es wie zuvor in start schreiben", also "Parent root = FXMLLoader.load (getClass (). GetResource (" Example.fxml "));" Danach habe ich versucht, damit von root.getChildren () zu spielen. (Ich wusste nicht, ob ich so damit spielen könnte)

Die IDE sagte mir, dass es nicht gut sei. Sagt es nicht, dass Sie den Namen wie "root.getChildrenUnmodizable ()" nicht ändern können? So wie das. In der Oracle Sensei API-Referenz ist es nur schreibgeschützt. Es gibt Daten zurück.

Es gab jedoch Erlösung.

Ich habe die Methode "@Override initialize (/ * Abkürzung * /)" in der zweiten Hälfte des Videos "Einbetten von TextField in TableView" eine Ebene höher gesehen. Weil.

Wenn Sie "public class Controller" implementieren, implementiert Initializable {} ", können Sie die" initialize "-Methode erben und die FX-Anzeige darin initialisieren (?).

Es ist ein bisschen alt Über das Format von Tatsuno Otoshigos Tagebuch JavaFX Controller Es gibt auch eine Beschreibung in.

Im obigen Video wurde der Beschreibungsprozess von fx, der im offiziellen Fall in "ApplicationClass.start" geschrieben wurde, in der Initialisierungsmethode geschrieben.

Ist es möglich, den Inhalt neu zu schreiben, indem Sie das Ding mit fx: id bearbeiten, das in FXML mit Controller festgelegt wurde?

Informationen zur Ausführungsreihenfolge

In diesem Fall ist die Reihenfolge der Ausführung von Bedeutung. Was als "Initialisierer" bezeichnet wird, kann einer seltsamen Ausführungsreihenfolge folgen. Überprüfen Sie dies daher anhand des Bereichs. Also habe ich ↓ vorbereitet

TestApp.java


/*Import Festival*/
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"?>
<!--?Sturm importieren-->
<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> <!--Kindersturm--> </children>
</AnchorPane>

Controller.java


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

Ich weiß nicht, ob es in Ordnung ist, das "IOE" herumzuwerfen, aber es sieht so aus. Die Standardausgabe des Ausführungsergebnisses ist ↓

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

Process finished with exit code 0

Zusamenfassend Beginnen Sie mit Test.main und starten Sie mit dem Start (das Verständnis dieses Bereichs ist nicht eindeutig). Lesen Sie übrigens fxml, indem Sie "FXMLLoader.load (fxml-Datei)" sagen, und lesen Sie "(load)". Wenn fxml gelesen wird, wird die durch "fx: controller" angegebene "Controler.java" gelesen und "(fxml)" Die "Initialisierungsmethode" wird "(/ fxml)" (/ load) ausgeführt. Und das ist es! (Was heißt das)

Es ist nicht möglich, direkt in das übergeordnete Stammverzeichnis zu schreiben, das von FXMLLoader.load im oberen Teil (dem Anfang des vorhandenen Abschnitts FXML ~~) entfernt wurde. Es wird jedoch beim Laden über den in der fxml-Datei angegebenen Controller initialisiert. Wenn Sie es schaffen, sieht es so aus. Ich habe realisiert, was ich tun möchte, also tut es mir leid.

Ich frage mich, ob die Spezifikation von "@ FXML" darin besteht, "mir Informationen zu geben, wenn es etwas mit einer solchen ID gibt" für fxml, das versucht, sich selbst zu lesen (Controller), wenn es gelesen wird.

Ich schrieb den PHP-Code mit Echo in die for-Anweisung von PHP und machte ihn wie ein Array (\ $ _ val.1, \ $ _ val2 ... "\ $ _ val". \ $ _ I), aber dieses Ich mag es, weil es intuitiver beschrieben werden kann.

Schließlich (9x9 Eingabefeld)

Bereiten Sie ein GridPane mit ID als Container auf der FXML-Seite vor. In Controller.initialize definiere ich das TextField (Array), das hineinpasst.

Als Idee wurde es als eine Frage an Teratail aufgeworfen [Java FX] So ordnen Sie Bilder in einem Raster an [GUI] Der Code des Fragestellers war sehr hilfreich. (Abgesehen davon könnte die Antwort sein, dass die Art und Weise, über Objekte nachzudenken, unangenehm ist. Es ist eine andere Geschichte, wenn Sie so etwas wie imageView.clone () machen können, aber es gibt keine solche Methode ... Nun, es ist ein ziemlich alter Artikel, und die FXML-Beschreibung und die internen Spezifikationen können unterschiedlich sein. )

Code unten

In der Controller-Klasse



//Vorab mit FXML vorbereitet. Die zu platzierenden XY-Koordinaten und die sichtbare Gitterlinie werden auf der FXML-Seite angegeben.
  @FXML GridPane inputGrid;

//Ich möchte später eine dicke Linie machen, damit es einfach ist, sie zu ändern.
  Double cellSize=30.0;

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

  //Anzahl der Spalten in der Tabelle
    int hnum = 9;    int vnum = 9;

  //Der Teil, der eine Eingabe erfordert
    TextField[][] cellValues = new TextField[vnum][hnum];
        //Ich werde jedes später neu geben, aber Speicher (Zeiger(Ah)) Wird nicht gegeben oder es spuckt schleimig.

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

        cellValues[i][j] = new TextField("");
        //Wenn Sie den Konstruktor nicht aufrufen und das Instanzobjekt übergeben, spuckt es schließlich

    //PrefW auf der TextView-Seite/Wenn Sie H angeben, ändert GridPane die Größe entsprechend.
    //W auf der Seite des Gitterfensters/BENUTZEN SIE H._COMPUTED_Stellen wir es auf GRÖSSE ein.
        cellValues[i][j].setPrefWidth(cellSize);
        cellValues[i][j].setPrefHeight(cellSize);
//Nachtrag:Ich habe eine setPrefSize-Methode gefunden, mit der Breite und Höhe gleichzeitig festgelegt werden können.
//Die untere Zeile hat dieselbe Funktion wie die beiden oberen Zeilen
//      cellValues[i][j].setPrefSize(cellSize,cellSize);


    //Fügen Sie die Koordinatenwerte im GridPane in die TextView-Optionen ein
        GridPane.setConstraints(cellValues[i][j], i, j);
    //Als Kind angeben
        inputGrid.getChildren().add(cellValues[j][i]);
//Nachtrag:In den beiden obigen Zeilen wurde die intern ausgeführte add-Methode gefunden.
//Liegt es an der unterschiedlichen Version? Unten finden Sie ein Beschreibungsbeispiel
//      inputGrid.add(cellValues[clmIndx][rowIndx],clmIndx,rowIndx);


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

Was die Suchoperation betrifft, scheint es notwendig zu sein, verschiedene Eigenschaften (Positionierung) usw. mit der Methode "setProperty" nacheinander festzulegen, um das Erscheinungsbild ohne Verwendung von FXML zu verbessern. Wenn Sie eine Einstellung für ein solches Erscheinungsbild schreiben, scheint die Startmethode von "Application.java", die den Start beschreibt, lang zu sein.

Mit anderen Worten Lassen Sie FXML (oder sceneBuilder) sich um das Erscheinungsbild kümmern. Wenn eine ID umfassend generiert wird oder wenn die Spezialität eines Computers wiederholt beschrieben wird, wird der Controller auf "Initialisierbar" gesetzt und in der "Initialisierungs" -Methode beschrieben.

Nicht nur in diesem Fall, wenn Sie eine GUI-Anwendung mit JavaFX unter Verwendung einer Datenbank oder Datei erstellen, die Ressourcen verwaltet, die in einem vorgegebenen Format vorbereitet wurden, frage ich mich, ob eine solche Methode angewendet werden sollte. Oder.

Randanzeige

Der Rand ist in den Eigenschaften von GridPane "GridLineVisible", aber Somewhere stackOverflow-Befragter weist darauf hin. Laut dem, was ich gesagt habe: "[Es ist zum Debuggen im API-Dokument geschrieben](https://docs.oracle.com/javase/jp/8/javafx/api/javafx/scene/layout/GridPane.html#" gridLinesVisibleProperty) Verwenden Sie es nicht. "

Stattdessen wurde die CSS-Methode eingeführt, aber ich möchte die 3x3-Gruppe besser sichtbar machen, also ein wenig ... Wenn ja, kann es eine Geschichte sein, dass Sie GridPane mit 3x3 erstellen und GridPane (3x3) verschachteln können, aber das ist auch problematisch.

Obwohl ich eine Konstante namens CELL_SIZE definiert und verwendet habe, wurde sie am Ende ziemlich schmutzig.

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

Das Gruppenargument gibt die Gruppe an, die das GridPane enthält, das den Rand zeichnet. Wenn Sie die Koordinatenposition der aufrufenden Gruppe in FXML angeben, müssen Sie auf dieser Seite weder layoutX noch layoutY angeben.

Das Zeichnen mit der Linie selbst fühlt sich schmutzig an, und ich habe nicht die Absicht, auf die Skalierung zu reagieren. Machen Sie so etwas wie SimpleTableView. (Wenn Sie es tun möchten, können Sie es tun.)

Fügen Sie Eingabeeinschränkungen hinzu

Es ist ein Problem, wenn der Eingabewert ein ganzzahliger Wert ist, insbesondere wenn es sich nicht um eine einzelne Ziffer handelt. Ich möchte zulassen, dass nur 0 als 1 bis 9 eingegeben wird, und es als leer behandeln.

Es scheint, dass es verschiedene Möglichkeiten gibt, dies zu tun. Es scheint, dass es besser ist, es entsprechend dem Zweck richtig zu verwenden. [Eingabe] Wie wird ein numerisches TextField in JavaFX empfohlen? Yutchis Blog - Ich habe versucht, nur Zahlen von 0 bis 9 in TextField einzugeben

Dies war auch hilfreich, wenn reguläre Ausdrücke wie Formatierer und Muster verwendet wurden. [Qiita - Grundlagen der regulären Ausdrücke @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)

Ich habe mich entschieden, einen geänderten Listener hinzuzufügen, der intuitiv (?) Mit der if-Anweisung optimiert. Versuchen Sie, den Beap-Sound zu erzeugen.

Das Folgende gilt für (i) für (j), wobei TextField in GridPane in der Controller-Klasse platziert wird

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~Wenn 9 1 Zeichen oder 0 Zeichen ist
//Akzeptiere wie gewohnt
      str=newValue;
    }else if(newValue.matches("[0-9]{2}")) {   // 0~Wenn 9 2 Zeichen ist
//Akzeptieren Sie die neue Eingabe als normal und verwerfen Sie den alten Wert
      str=String.valueOf(newValue.charAt(1));
    }else{                                     //anders als das
      Toolkit.getDefaultToolkit().beep();      //Peron(Fehlerton)
//Keine Änderung, wenn der vorherige Wert normal ist. Davon abgesehen""
      str=oldValue.matches("[0-9]") ? oldValue : "" ; 
    }
    textField.setText(str); //Es war mühsam, dies eins nach dem anderen zu schreiben, also schrieb ich str
  });

  textField.setPrefSize(CELL_SIZE, CELL_SIZE);
  textField.setAlignment(Pos.CENTER);
  textField.setFont(Font.font("", FontWeight.BOLD,-1.0)); //Ich wollte es zu einem kühnen Symbol machen, aber es wird nicht viel Fett...

  cellValues[clmIndx][rowIndx]=textField;
//Eigenschaft ist auch im Objekt enthalten(?)Das ist also cool.
//Oder besser gesagt, ich war wirklich wütend, als ich versuchte, einen Listener als Array zu erstellen

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

Als ! NewValue.matches (" [^ 0-9] + ") wurde der Speicher zunächst durch "" ersetzt (mehrdeutig)

Wenn Sie in Übereinstimmungen "[0-9]" "festlegen, werden 0 Zeichen, dh" ", nicht akzeptiert. Das erste, was mir in den Sinn kam, war: "Es gab einen regulären Ausdruck im hinteren Bereich, also lass es uns tun, wenn es betreten wird!" Vielleicht auf eine Weise, die niemand versuchen würde, wurde ein Teil des Schreibens im Code belassen, aber ich habe es wie "newValue.charAt (1) ==" \ b "" gemacht, aber dieser Typ produziert Nurupo in Massenproduktion. Wenn es steigt, wird die Standardausgabe hellrot.

Ich habe ein Experiment versucht, indem ich newValue mit einem Kleber wie "Was ist drin, wenn es nicht \ b ist?" In die Standardausgabe ausgegeben habe. (Sout bleibt im Kommentar) Im Hintergrund wird "" nach dem Zurücksetzen zu einem neuen Wert, sodass charAt (1) schleimig auszuspucken scheint.

Beispiel für Eingabe und Ausgabe, wenn Sout im obigen Zustand ausgeführt wird Leere Zeilen reproduzieren

Eingang: a1b23\b8d
Ausgabe:
a

1
1b
1
12
2
23
3

8
8d
8

\ b ist das hintere Leerzeichen und die leere Zeile ist wie reproduziert. Übrigens, wenn Sie eine beliebige Zeichenfolge kopieren und einfügen, werden alle Zahlen bis auf eine oder zwei mit halber Breite geschlagen und nur die zuletzt eingegebene Zahl eingegeben. Selbst wenn Sie die Zeichenfolge "" (nichts) kopieren und einfügen, klingt Beap ein wenig.

Eingabebeschränkung - ist das in Ordnung?

Mit dieser Methode werden 81 ChangeListener-Objekte erstellt, und ich habe das Gefühl, dass viel Abfall anfällt ... Ich frage mich, ob es geteilt werden kann, indem man es zu einer einzigen Methode macht.

Also war es ↓

Controller.setInputGrid()



//StringProperty Bean-Hash und TextField Map
    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]?")){ /*Unterlassung*/ str=FILLED_VALUE }

//Schmutzige Besetzung, die in diesem Jahrhundert selten zu sehen war
        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())) {
//Entschuldigung Fehlerausgabe. Wenn Sie keine Hash-Kollisionen mögen, können Sie die Bean einfach so speichern, wie sie ist ()
          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);

Ich bin nicht sicher, welches eine bessere Speichernutzung als der ursprüngliche Code hat. Oder besser gesagt, es war definitiv Scheiße in Bezug auf die Lesbarkeit.

Bereiten Sie einen Container vor, der Eingaben akzeptiert

Wir werden eine Klasse definieren, die die Eingabedaten in ein Formular verarbeitet, das einfach zu handhaben ist. Durch die Anreicherung möchte ich die Beschreibung in der Klasse, die die Daten verarbeitet, vereinfachen.

Was ich besonders machen möchte, ist Bereiten Sie eine "Leser" -Klasse vor, die Zellen in der Tabelle für jede [Zeile / Spalte / 3x3-Unterregion] liest. Das ist.

Wenn Sie verwalten möchten, ob die Nummer bereits in jeder Gruppe vorhanden ist, bereiten Sie eine Aktion zum Lesen von 27 Gruppen mit 9 Spalten, 9 Zeilen und 9 Quadraten (im Folgenden als "Region" bezeichnet) aus der Tabelle vor. Ich sollte es geben.

Wenn Sie beispielsweise tatsächlich lösen: "Wenn es n Zahlen gibt, die nur an die gleichen n Stellen in dieser Region passen, passen diese Zahlen nicht an andere Stellen", so genannter "Standardstein". Ich möchte es auch einbauen. (Obwohl ich denke, dass dies in der Methode auf der Lösungsseite implementiert wird.)

Ich möchte eine Liste von "Nummern, die in jede Zelle eingegeben werden können" und "Nummern, die nicht eingegeben werden können" in jeder Zelle weiter unterteilen und vorbereiten.

Ich habe es beiläufig definiert, aber von nun an,

"Zelle" ist jede Zelle, die einen Buchstaben enthalten sollte, um die Zahl zu lösen "Region" ist eine Gruppe von Zahlen in einer Zelle, die der Einschränkung der Duplizierung unterliegen. Regionen sind weiter unterteilt in "Zeilenregionen", "Spaltenregionen" und "3x3-Unterregionen". (Der Verarbeitungsinhalt ist der gleiche.) "Tabelle" ist eine Sammlung aller Zellen

Wird geschrieben. Die Tabelle kann jedoch ohne vorherige Ankündigung als "Board" bezeichnet werden. Das liegt daran, dass wir es so genannt haben, als wir mit der Entwicklung begonnen haben.

Bei der Bearbeitung gemeinsam genutzter Daten

In Java werden Zeiger in der Sprache C als "Referenzvariablen" oder "Referenzwerte" bezeichnet.

Ich möchte, dass jede Region den Referenzwert speichert, damit er nur mit der Datengruppe der Zelle für eine Tabelle verarbeitet werden kann. Mit anderen Worten, ich möchte die Daten der in der Tabelle vorhandenen Zellen ändern, indem ich von der Region aus operiere.

Das Folgende ist ein Bilddiagramm, das keine Verbindung herstellt

Cell Region image

Nach Wert? Als Referenz übergeben? Bewertungsstrategie? was ist das.

Zu diesem Zeitpunkt fragte ich mich: "Kann Java Daten wie Zeiger verarbeiten?". Also habe ich mir verschiedene Dinge angesehen. Ich kann nicht mehr sagen, dass es als Referenz übergeben wurde Dieser Artikel war sehr hilfreich. Ich habe sogar die letzte Folie von "Wintermaterialien 2018, die nicht als Referenz bezeichnet werden können" gelesen. "Die Theorie des" Referenzierens "! ?? Ich glaube, ich konnte das Beispiel im Abschnitt "" oder "Wertübergabe" verstehen, das fünfmal auf der Folie wiederholt wurde (ich denke (sehr unruhig)).

Ich habe auch die Problemzusammenfassung Java "Pass by Reference" @acevif gelesen und auf meine eigene Weise zusammengefasst.

Wenn ja, schreiben Sie es wie C.

Die Farbsyntax ist Java


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

ArrayList<String> **list = new ArrayList<String>(); //Ich fühle mich hier etwas unwohl
**list.add("Java");
method(list);
System.out.println(**list);    // [Java]

Es ist eine Beschreibung, die sich anfühlt, als würde man in zwei Sprachen kämpfen, daher enthielt sie einen sehr unangenehmen Schreibstil, aber intuitiv ist dies der Fall.

[^ 1]: Um ehrlich zu sein, war das japanische Wort "Ich übergebe es" fantastisch. Bei der Übersetzung von Englisch kann ich nur sagen, dass eine solche Übersetzung korrekt ist, da ich "by" verwende, das nur mit "de" übersetzt werden kann. Der Originaltext lautet "Call by Reference oder Pass by Reference". (Java "Pass by Reference" -Problemzusammenfassung @acevif). Es ist ein bisschen abseits des Themas, aber nach einem kurzen Blick auf den Ursprung von by wandelten sich Hits von "Peripherie" zu "Nah". Es heißt wiederum "Seite" und "Sekundär".

Eine weitere detaillierte Analogie oder Information

Der Lehrer, den ich unterrichtete, sagte früher in der Java-Klasse: "In Java verwenden wir grundsätzlich nicht den Wortzeiger, aber alle Variablen außer primitiven Typen, dh Referenztypen, sind alle. Ich habe das Gefühl, jetzt die Bedeutung des Wortes "weil es ein Zeiger ist" zu verstehen.

Wenn Sie das eigentliche Argument "int * val" an das formale Argument "int * arg" übergeben, In der C-Sprachnotation kann die Zeigervariable arg`` * val ändern, indem das Ziel * arg geändert wird, auf das der Zeiger zeigt. Wenn Sie das Ziel des Arg-Zeigers in der Funktion ändern, Da arg! = Val gesetzt ist, ändert das Ändern von * arg nicht * val. Mögen.

Auf jeden Fall habe ich das Gefühl, dass ich die Bedeutung des Wortes "Wertübergabe" aus der Schlussfolgerung des Artikelbesitzers "Wert", genannt "Referenzwert", verstehe.

Sie müssen den in der Geschichte erwähnten Wikipedia-Artikel über "Bewertungsstrategie" richtig lesen. (Es ist auch in Englisch)

Übrigens habe ich vor dem Lesen dieser Artikel den Zeiger des ** primitiven Typs ** int array int [] [] cell, zum Beispiel cell [i] [j], auf rowRegion [i] .get (j) verwendet. ) Starb beim Versuch zu passen. Oder besser gesagt, ich wusste nicht, dass es überhaupt nicht genug Informationen gab. Als ich versuchte, hier ein Problem als Artikel zu schreiben, dachte ich zuerst "Ich möchte so etwas wie einen Zeiger behandeln", begann mit "Was ist ein Java-Zeiger?" Und stieß auf den obigen Artikel. Es fühlt sich an wie ...

... Da ein Element eines Arrays von Dingen vom primitiven Typ ein primitiver Typ ist, habe ich versucht, in Java etwas Unvernünftiges zu tun, das nur als Wert übergeben wird. Nun, ich denke, dies kann erreicht werden, indem eine einfache Klasse erstellt wird, die als Mitglied einen int-Typ hat.

Die Geschichte davor

Meine schlechte Gnade, bevor ich wusste, dass die Preise überschritten wurden.

  1. Erstellen Sie eine "statische Tabellenklasse" und eine "Regionsklasse, die ArrayList " in der Board-Klasse erbt, und bereiten Sie ein "statisches Zellenfeld vom Typ int [] []" in der Table-Klasse vor. Versuchen Sie, eine Methode zu erstellen, um "ein Regionsobjekt mit Zelle [i] [j]" in der Board-Klasse zurückzugeben.
  2. Um die Bedienung der Zelle durch Einfügen von ij wie die Koordinaten (x, y) zu vereinfachen und die Bedienung der Zelle zu vereinfachen, wird der Klasse ** Table die Methode zur Bedienung des Felds int i, j und der Zelle hinzugefügt. Fangen Sie an, innen zu schreiben. ** ** **
  3. Wenn Sie versuchen, das Table-Objekt in das Region-Objekt einzufügen, wird es zu "!!?". Erstellen Sie in Eile eine PosXY-Klasse und fügen Sie es in die Table-Klasse ein.
  4. Ich stelle fest, dass es schwierig ist, eine Methode mit einer beträchtlichen Anzahl von Aufrufen bei jedem Aufruf als neue ArrayList <> () zu bezeichnen.
  5. Ich frage mich, ob ich jedes Element der Zelle [] [] irgendwie wie einen Zeiger aussehen lassen kann.
  6. Beginnen Sie mit der Beschreibung von "[# Bereiten Sie einen Container vor, der Eingaben akzeptiert](# Bereiten Sie einen Container vor, der Eingaben akzeptiert)", um der Realität zu entkommen.
  7. Nein, mach eine Klasse. Teka int [] [] Was ist Zelle? Erstellen Sie eine Zellenklasse ← Jetzt hier

...........^q^) damit

Ich werde die Cell-Klasse entwerfen.

Vorwort zur Entwurfsbeschreibung jeder Klasse

Ich habe es am Anfang geschrieben, und wenn Sie den Inhalt lesen, werden Sie es verstehen, und da Sie es im Profil hätten schreiben sollen, können Sie es verstehen,

Ich bin ein Anfänger von knusprig. Egal was du tust, ich denke es wird eine arme sein, also bitte vergib mir. (Kommentare wie Kritik und Verbesserungsmaßnahmen sind willkommen.) Selbst Anfänger derselben Klasse sollten dies nicht als Referenz verwenden. Auch wenn Sie es als Referenz verwenden, lassen Sie uns die Meinung des Erziehers einholen.

Zellklassendesign

Als Voraussetzung wird Cell als eine der Zeilen angesehen, die wie eine Tabelle angeordnet sind. Daher begrenzt die Factory-Methode die Erzeugung von Instanzen, indem nur zweidimensionale Arrays ausgegeben werden. Das Ausgabezellenobjekt und der Name als Masse sind ** Zelle **, Mehrere Zellcluster (Cell [] []) wurden als ** Zellen gesetzt ** bezeichnet.

Außerdem habe ich beschlossen, die Aktion auszudrücken, eine Nummer in die Zelle einzufügen, dh dem Wert eine Nummer zuzuweisen und diese als "Füllung" zu bestätigen. Auf Englisch ist es Fill. Selbst wenn Sie es tatsächlich tun, können Sie so etwas wie "3 hier ausfüllen" sagen.

Unten finden Sie eine Zusammenfassung, die so grob wie möglich ist.

--Feld --Pos pos: Ein Pos-Klassenobjekt, das seine Position auf den eingestellten Zellen angibt. Um die Pos-Klasse kurz zu erläutern, enthält sie Zeilennummern und Spaltennummern als Felder und ist dafür verantwortlich, die Verarbeitung für sie und die Verarbeitung unter Verwendung von Zeilennummern und Spaltennummern, die bei Verwendung einer 3x3-Unterregion verwendet werden, einzuschränken. --int value: Die in der Zelle vergrabene Nummer. Leer ist 0 --boolean [10] möglich: Speichert, ob die der Elementnummer entsprechende Nummer in diese Zelle eingetragen werden darf. Das heißt, wenn die Möglichkeit besteht, dass sich 5 in der Zelle befindet, ist "möglich [5] == wahr" --Konstrukteur

Um es zusammen zu schreiben,

Ist es so Während ich dies schreibe, frage ich mich, ob es nicht notwendig ist, die Zeilennummer und die Spaltennummer in der Zelle selbst zu haben, aber warum nicht? Unter der Annahme, dass es von "cells [i] [j]" als Element des Arrays aufgerufen wird, frage ich mich, ob es notwendig ist. Für mich wäre es schön, wenn es eine HashMap mit zwei Schlüsseltypen gäbe. Wenn Sie nur einen Schlüssel angeben, wird eine iterierbare "Zeilenliste" angezeigt.

Nachtrag (19.02.01) Ich habe beschlossen, die Table-Klasse das Objekt anstelle des Arrays abfangen zu lassen. Immerhin dachte ich, dass die Erinnerungsbeziehung nicht gut war. Weitere Informationen finden Sie in der Tabellenklasse.

Copy constructor does not copy field boolean[]

Bei Verwendung von IDEA werden Warnungen und Vorschläge in der Bildlaufleiste angezeigt. Die roten Dinge verursachen normalerweise Kompilierungsfehler und werden erst kompiliert, wenn Sie sie beheben. Die gelben sind "Nur in dieser Methode verwenden, nicht privat?" Oder "Ich gebe diesen Feldwert an, aber ich verwende ihn nicht!" Oder "Der bedingte Ausdruck dieser if-Anweisung ist immer wahr, aber ich brauche ihn nicht." Es gibt viele Dinge wie "Nein", aber dieses Mal werde ich mich auch darum kümmern.

Es gab etwas, das nicht übersehen werden konnte (Überschrift).

Der eigentliche Satz war "" möglich "" anstelle von "boolean []". IDEA erhöht die Informationen durch Drücken von mehr. Wenn Sie sich also den Inhalt von mehr ansehen,

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

Hmm? e? Ich weiß, dass Sie etwas über möglich ohne Transienten sagen, Die erste Zeile lautet "Es gibt ein Feld, das nicht kopiert wurde", und die zweite Zeile lautet "Wenn Sie Transienten hinzufügen, wird davon ausgegangen, dass Sie nicht kopieren müssen". Wach Wakame auf.

Ich werde Ihnen den Teil zeigen, in dem die Erklärung oder Warnung abgegeben wurde

Cell


//Verschiedene Auslassungen

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

Der Warnungstext war inkonsistent und ich befand mich in einem Hatena-Zustand, also experimentierte ich.

Innerhalb der Cell-Klasse



  public static void main(String[] args) { //Haupt solide Schrift in der Klasse

    int[][] x={{0}};                      //Erstellen Sie Werte mit nur einem Element zum Testen
    Cell[][] cell1= makeCellArray(x);     //Die 9x9-Einschränkung wird übrigens in der Board-Klasse durchgeführt.
    cell[0][0].deny(2);                   //Dieser Vorgang ist möglich[2]Ist falsch geworden

    Cell[][] cell2=cloneCells(cell1);      //Der von cloneCells aufgerufene Konstruktor ist Cell(Cell cell)。...Ein bisschen kompliziert

    System.out.println("cell1");
    for (boolean t:cell1[0][0].possible){  //Bitten Sie foreach, den gesamten Inhalt des möglichen Arrays zu extrahieren.
      System.out.print(" "+( t?1:0 ));     //Ein gelegentlicher ternärer Operator. Machen Sie true false zur gleichen Ausgabe wie die C-Sprache
    }

    System.out.println(); //Neue Zeile

    for (boolean t:cell2[0][0].possible){  //möglich ist privater Zugang, aber es ist cool, weil es in der gleichen Klasse ist
      System.out.print(" "+( t?1:0 ));
    }
    System.out.println();
    System.out.println("cell2");
  }

Ausgabe


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

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

Das ist es. Ein nicht initialisierter Boolescher Wert ist falsch. Da drüben. Die Konstruktorseite erledigt die Aufgabe der möglichen Initialisierung mit dem Wert 0, aber die Information, dass "2 nicht eingibt", wird nicht übergeben. (Ich habe es beim Schreiben dieses Artikels bemerkt.)

Ich habe die Klonmethode der Zelle versiegelt, aber nicht den Klon des Feldes! Deshalb habe ich mich entschieden, möglich zu bestehen. Klon. ... Ich muss den Konstruktor nicht aufrufen ...

... umgeschrieben.


Nun, aber die Geschichte endet hier nicht. Es war vorübergehend, dass ich daran interessiert war, vorbei zu gehen. Nanikore

Vorerst wurde cell2.possible [2] falsch (!!!!!!), als ich feststellte, dass der Code vorübergehend ist und vor der Änderung ausgeführt wurde. Was ist das?

Nachforschen und m (Ich bin es ein wenig leid, Artikel zu schreiben, Nachforschungen anzustellen und zu programmieren, also werde ich das Spiel spielen. Ich werde nicht verschwinden. Ich werde morgen weitermachen.)

Nachtrag (19.01.13) Du wirst es vergessen, wenn du es später in einen Kreis wirfst () todo schreiben

// todo: vorübergehend

Nachtrag (19.02.01) Bis es fertig war (schmelzen), habe ich es hier ohne Ausgabe zusammengedrückt, so dass das Folgende wie die Flugbahn bis zu diesem Punkt ist.

Regionsklasse

Da ich verschiedene zusätzliche Funktionen hinzugefügt habe, werde ich nur die Hauptmethode erläutern, die im abgeschlossenen (vorläufigen) Zustand verwendet wird. Früher sagte ich "Ich mag Arrays", aber am Ende wurde es eine 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;
}

Wenn region.get (index) .tryFill (value) == true (Mit anderen Worten: Wenn es Ihnen gelingt, ** value ** in den ** index ** th cell in der Region zu füllen) Andere cells(: = indexOf (cells [i])! =** _index _ **) in derselben Region können also nicht mit ** _value _ ** gefüllt werden Durch Aufrufen dieser Methode in der Klasse, die die Region enthält Stellen wir sicher, dass ** _ value _ ** cell.deny (value) in cells automatisch ist, außer cell, Methode mit der Absicht gemacht ** return ** Boolescher Wert, den die Aktualisierung als Ergebnis dieses Methodenaufrufs erhalten hat (ob der Rückgabewert von cell.deny wahr ist)

Tabellenklasse

Erstellt durch Erben von java.util.HashMap. Speichern Sie Daten mit pos als Schlüssel und cell als Wert. Es verfügt über eine getEmptyCells-Methode, die eine Liste von Zellen mit nicht ausgefüllten Werten zurückgibt.

Board Klasse

Eine Klasse, die ein Tabellen- und ein Regionsarray (jeweils 9 für Zeilen, Spalten und Subs, insgesamt 27) im Feld hat und diese integriert und betreibt. Die Größe, die Sie nur neu erstellen müssen, wenn Sie ein Duplikat erstellen. Erstellen Sie ein Duplikat, indem Sie ein Board-Objekt an den Konstruktor übergeben. Ich habe es geschrieben, um den Angstfaktor auszuschließen, wenn ich eine tiefe Kopie machen möchte.

Darüber hinaus bereiten wir eine Methode zur Ausführung von Cell :: tryFill und Region :: valueFill vor und verwenden sie als "Methode zum Füllen des Werts" aus der später beschriebenen NPS-Klasse.

NumberPlaceSolver-Klasse

Ich habe es als Klasse geschrieben, die eine Gruppe von Algorithmen zum tatsächlichen Lösen von Mathematik ausführt. Als Feld

--Int Wert zur Gewährleistung der Sicherheit bei übermäßiger Wiederholung bei der Verarbeitung der "temporären Platzierung" mit rekursiver Verarbeitung ("Tiefe" der rekursiven Verarbeitung)

haben.

Ich habe eine "Algorithmus" -Klasse geschrieben, in der Methoden als innere Klasse gespeichert werden. WANT todo: Verarbeitung wie das Ausführen aller Methoden, die an einer Stelle wie "Methodenliste" geschrieben wurden

Derzeit ist nur "temporärer Speicher" implementiert. Beim temporären Platzieren soll eine neue Instanz von NumberPlaceSolver mit dem Speicherort und Wert der temporär platzierten Zelle und dem "aktuellen Status (this)" als Argument erstellt werden.


Die Geschichte, die nicht in Ordnung war

Zuerst dachte ich, ich dachte: "Machen wir es von der Benutzerseite aus!"

Erstellen Sie eine Bildschirmanzeige, erstellen Sie eine NPS-Klasse und ... erstellen Sie eine Cell-Klasse! (← !?)

Weil es wurde, wurde es ein Design mit vielen unnötigen Methoden und Verschwendung. Es war auch der ursprüngliche Zweck Ich habe die Implementierung von "Mehrere Threads gleichzeitig gleichzeitig platzieren und jeden ablehnen. Durch Verweigern einer statischen Tabelle können mehrere Werte gleichzeitig verweigert werden" (? ), Die Richtung war also ganz anders als ich erwartet hatte. Es wurde fertiggestellt, damit es gelöst werden konnte, aber es würde lange dauern, wenn es nicht mehr als die Hälfte gefüllt wäre, also würde ich es gerne verbessern.

Recommended Posts

Memo beim Tappen und Entwickeln mit JavaFX
Ein Memorandum beim Versuch, eine GUI mit JavaFX zu erstellen
[Persönliches Memo] Schreiben einer Datei mit BufferedWriter
[Rails] [Hinweis] Wann = zu <%%> hinzugefügt werden soll und wann nicht
Ausgabe mit Methoden und Konstanten Lernnotiz
[Persönliches Memo] Lesen von Dateien mit BufferedReader
Ein Memo zum Erstellen eines einfachen Formulars, das nur HTML und CSS in Rails 6 verwendet
Bei Verwendung einer Liste in Java wird java.awt.List ausgegeben und ein Fehler tritt auf
Ein einfaches Stein-Papier-Scheren-Spiel mit JavaFX und SceneBuilder
Wenn Sie eine vollständige äußere Verknüpfung ausführen, ohne die vollständige äußere Verknüpfung zu verwenden
JavaFX und HiDPI
Ein Hinweis zu "Stellen Sie mit einem selbstsignierten Zertifikat mit Javas Keytool keinen Zertifikatfehler aus"
Zeigen Sie ein Ladebild in JavaFX an und zeigen Sie dann ein anderes Bild an
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
Ein Memorandum bei der Installation von Docker und der Erstellung eines Linux-Containers
Hinweise zur Überprüfung bei der Verwendung von Lombok
Ein Memo beim Abrufen der eingehenden Nummer mit Broadcast Receiver unter Android 9/10 funktioniert nicht