質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

2669閲覧

JavaFXで、Button#setTextをまとめて行う

CreeperSaviour

総合スコア129

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/09/15 08:25

前提・実現したいこと

私は今、オセロを作っているのですが、下記に示したコードのように、

button_00.setText(String.valueOf(Data.field.getSquare(0, 0))); button_01.setText(String.valueOf(Data.field.getSquare(0, 1))); button_02.setText(String.valueOf(Data.field.getSquare(0, 2))); button_03.setText(String.valueOf(Data.field.getSquare(0, 3))); button_04.setText(String.valueOf(Data.field.getSquare(0, 4))); button_05.setText(String.valueOf(Data.field.getSquare(0, 5))); button_06.setText(String.valueOf(Data.field.getSquare(0, 6))); button_07.setText(String.valueOf(Data.field.getSquare(0, 7))); button_08.setText(String.valueOf(Data.field.getSquare(0, 8))); button_09.setText(String.valueOf(Data.field.getSquare(0, 9))); button_10.setText(String.valueOf(Data.field.getSquare(1, 0))); button_11.setText(String.valueOf(Data.field.getSquare(1, 1))); ・・・~~~・・・ button_99.setText(String.valueOf(Data.field.getSquare(9, 9)));

となっており、同じような文字列を何度も打ち込むのは、コードが汚くなると思い、これらをまとめる方法を知りたい所存です。

詳細なソースコード

Othello.java

Java

1package jp.starfree.cpsv; 2 3import java.net.URL; 4import java.util.ResourceBundle; 5 6import javafx.event.ActionEvent; 7import javafx.fxml.FXML; 8import javafx.fxml.Initializable; 9import javafx.scene.control.Button; 10import javafx.scene.control.Menu; 11import javafx.scene.control.MenuItem; 12import javafx.scene.control.TextField; 13 14public class Othello implements Initializable{ 15 16 @FXML 17 Button button_00; 18 @FXML 19 Button button_01, button_02, button_03, button_04, button_05, button_06, button_07, button_08, button_09, button_10, button_11, button_12, button_13, button_14, button_15, button_16, button_17, button_18, button_19, button_20, button_21, button_22, button_23, button_24, button_25, button_26, button_27, button_28, button_29, button_30, button_31, button_32, button_33, button_34, button_35, button_36, button_37, button_38, button_39, button_40, button_41, button_42, button_43, button_44, button_45, button_46, button_47, button_48, button_49, button_50, button_51, button_52, button_53, button_54, button_55, button_56, button_57, button_58, button_59, button_60, button_61, button_62, button_63, button_64, button_65, button_66, button_67, button_68, button_69, button_70, button_71, button_72, button_73, button_74, button_75, button_76, button_77, button_78, button_79, button_80, button_81, button_82, button_83, button_84, button_85, button_86, button_87, button_88, button_89, button_90, button_91, button_92, button_93, button_94, button_95, button_96, button_97, button_98, button_99, button_Black, button_White, button_Move; 20 @FXML 21 TextField textField_Black, textField_White, textField_Move; 22 @FXML 23 Menu menu_File; 24 @FXML 25 MenuItem menuItem_NewGame; 26 @FXML 27 public void mouse_onClick_MenuItem_NewGame(ActionEvent e) { 28 button_00.setText(String.valueOf(Data.field.getSquare(0, 0))); 29 button_01.setText(String.valueOf(Data.field.getSquare(0, 1))); 30 button_02.setText(String.valueOf(Data.field.getSquare(0, 2))); 31 button_03.setText(String.valueOf(Data.field.getSquare(0, 3))); 32 button_04.setText(String.valueOf(Data.field.getSquare(0, 4))); 33 button_05.setText(String.valueOf(Data.field.getSquare(0, 5))); 34 button_06.setText(String.valueOf(Data.field.getSquare(0, 6))); 35 button_07.setText(String.valueOf(Data.field.getSquare(0, 7))); 36 button_08.setText(String.valueOf(Data.field.getSquare(0, 8))); 37 button_09.setText(String.valueOf(Data.field.getSquare(0, 9))); 38 button_10.setText(String.valueOf(Data.field.getSquare(1, 0))); 39 button_11.setText(String.valueOf(Data.field.getSquare(1, 1))); 40 button_12.setText(String.valueOf(Data.field.getSquare(1, 2))); 41 button_13.setText(String.valueOf(Data.field.getSquare(1, 3))); 42 button_14.setText(String.valueOf(Data.field.getSquare(1, 4))); 43 button_15.setText(String.valueOf(Data.field.getSquare(1, 5))); 44 button_16.setText(String.valueOf(Data.field.getSquare(1, 6))); 45 button_17.setText(String.valueOf(Data.field.getSquare(1, 7))); 46 button_18.setText(String.valueOf(Data.field.getSquare(1, 8))); 47 button_19.setText(String.valueOf(Data.field.getSquare(1, 9))); 48 button_20.setText(String.valueOf(Data.field.getSquare(2, 0))); 49 button_21.setText(String.valueOf(Data.field.getSquare(2, 1))); 50 button_22.setText(String.valueOf(Data.field.getSquare(2, 2))); 51 button_23.setText(String.valueOf(Data.field.getSquare(2, 3))); 52 button_24.setText(String.valueOf(Data.field.getSquare(2, 4))); 53 button_25.setText(String.valueOf(Data.field.getSquare(2, 5))); 54 button_26.setText(String.valueOf(Data.field.getSquare(2, 6))); 55 button_27.setText(String.valueOf(Data.field.getSquare(2, 7))); 56 button_28.setText(String.valueOf(Data.field.getSquare(2, 8))); 57 button_29.setText(String.valueOf(Data.field.getSquare(2, 9))); 58 button_30.setText(String.valueOf(Data.field.getSquare(3, 0))); 59 button_31.setText(String.valueOf(Data.field.getSquare(3, 1))); 60 button_32.setText(String.valueOf(Data.field.getSquare(3, 2))); 61 button_33.setText(String.valueOf(Data.field.getSquare(3, 3))); 62 button_34.setText(String.valueOf(Data.field.getSquare(3, 4))); 63 button_35.setText(String.valueOf(Data.field.getSquare(3, 5))); 64 button_36.setText(String.valueOf(Data.field.getSquare(3, 6))); 65 button_37.setText(String.valueOf(Data.field.getSquare(3, 7))); 66 button_38.setText(String.valueOf(Data.field.getSquare(3, 8))); 67 button_39.setText(String.valueOf(Data.field.getSquare(3, 9))); 68 button_40.setText(String.valueOf(Data.field.getSquare(4, 0))); 69 button_41.setText(String.valueOf(Data.field.getSquare(4, 1))); 70 button_42.setText(String.valueOf(Data.field.getSquare(4, 2))); 71 button_43.setText(String.valueOf(Data.field.getSquare(4, 3))); 72 button_44.setText(String.valueOf(Data.field.getSquare(4, 4))); 73 button_45.setText(String.valueOf(Data.field.getSquare(4, 5))); 74 button_46.setText(String.valueOf(Data.field.getSquare(4, 6))); 75 button_47.setText(String.valueOf(Data.field.getSquare(4, 7))); 76 button_48.setText(String.valueOf(Data.field.getSquare(4, 8))); 77 button_49.setText(String.valueOf(Data.field.getSquare(4, 9))); 78 button_50.setText(String.valueOf(Data.field.getSquare(5, 0))); 79 button_51.setText(String.valueOf(Data.field.getSquare(5, 1))); 80 button_52.setText(String.valueOf(Data.field.getSquare(5, 2))); 81 button_53.setText(String.valueOf(Data.field.getSquare(5, 3))); 82 button_54.setText(String.valueOf(Data.field.getSquare(5, 4))); 83 button_55.setText(String.valueOf(Data.field.getSquare(5, 5)));; 84 button_56.setText(String.valueOf(Data.field.getSquare(5, 6))); 85 button_57.setText(String.valueOf(Data.field.getSquare(5, 7))); 86 button_58.setText(String.valueOf(Data.field.getSquare(5, 8))); 87 button_59.setText(String.valueOf(Data.field.getSquare(5, 9))); 88 button_60.setText(String.valueOf(Data.field.getSquare(6, 0))); 89 button_61.setText(String.valueOf(Data.field.getSquare(6, 1))); 90 button_62.setText(String.valueOf(Data.field.getSquare(6, 2))); 91 button_63.setText(String.valueOf(Data.field.getSquare(6, 3))); 92 button_64.setText(String.valueOf(Data.field.getSquare(6, 4))); 93 button_65.setText(String.valueOf(Data.field.getSquare(6, 5))); 94 button_66.setText(String.valueOf(Data.field.getSquare(6, 6))); 95 button_67.setText(String.valueOf(Data.field.getSquare(6, 7))); 96 button_68.setText(String.valueOf(Data.field.getSquare(6, 8))); 97 button_69.setText(String.valueOf(Data.field.getSquare(6, 9))); 98 button_70.setText(String.valueOf(Data.field.getSquare(7, 0))); 99 button_71.setText(String.valueOf(Data.field.getSquare(7, 1))); 100 button_72.setText(String.valueOf(Data.field.getSquare(7, 2))); 101 button_73.setText(String.valueOf(Data.field.getSquare(7, 3))); 102 button_74.setText(String.valueOf(Data.field.getSquare(7, 4))); 103 button_75.setText(String.valueOf(Data.field.getSquare(7, 5))); 104 button_76.setText(String.valueOf(Data.field.getSquare(7, 6))); 105 button_77.setText(String.valueOf(Data.field.getSquare(7, 7))); 106 button_78.setText(String.valueOf(Data.field.getSquare(7, 8))); 107 button_79.setText(String.valueOf(Data.field.getSquare(7, 9))); 108 button_80.setText(String.valueOf(Data.field.getSquare(8, 0))); 109 button_81.setText(String.valueOf(Data.field.getSquare(8, 1))); 110 button_82.setText(String.valueOf(Data.field.getSquare(8, 2))); 111 button_83.setText(String.valueOf(Data.field.getSquare(8, 3))); 112 button_84.setText(String.valueOf(Data.field.getSquare(8, 4))); 113 button_85.setText(String.valueOf(Data.field.getSquare(8, 5))); 114 button_86.setText(String.valueOf(Data.field.getSquare(8, 6))); 115 button_87.setText(String.valueOf(Data.field.getSquare(8, 7))); 116 button_88.setText(String.valueOf(Data.field.getSquare(8, 8))); 117 button_89.setText(String.valueOf(Data.field.getSquare(8, 9))); 118 button_90.setText(String.valueOf(Data.field.getSquare(9, 0))); 119 button_91.setText(String.valueOf(Data.field.getSquare(9, 1))); 120 button_92.setText(String.valueOf(Data.field.getSquare(9, 2))); 121 button_93.setText(String.valueOf(Data.field.getSquare(9, 3))); 122 button_94.setText(String.valueOf(Data.field.getSquare(9, 4))); 123 button_95.setText(String.valueOf(Data.field.getSquare(9, 5))); 124 button_96.setText(String.valueOf(Data.field.getSquare(9, 6))); 125 button_97.setText(String.valueOf(Data.field.getSquare(9, 7))); 126 button_98.setText(String.valueOf(Data.field.getSquare(9, 8))); 127 button_99.setText(String.valueOf(Data.field.getSquare(9, 9))); 128 textField_Black.setText(Data.field.getValueOfBlack() + " 個"); 129 textField_White.setText(Data.field.getValueOfWhite() + " 個"); 130 textField_Move.setText("黒"); 131 } 132 133 @Override 134 public void initialize(URL location, ResourceBundle resources) { 135 136 } 137 138 139 140} 141

補足情報(FW/ツールのバージョンなど)

Java 10.0.2
JavaSE 10.0.2
Eclipse 4.8(Photon)
JavaFX Scene Builder 2.0

質問初心者なため、不足情報があればご指摘くださると幸いです。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

質問者さんはオセロの石を置く区画を表すButtonを全てFXML上に記述しコントローラークラスへ@FXMLアノテーション付きのフィールドへマッピングしておられます。

そのためbutton_00, button_01, ...のようなフィールドが多数できるわけですが、このことが「個々のButtonインスタンスへの処理を書く際に同じようなコードがたくさん並ぶ」原因になっています。

本来は似たような処理は繰り返し文によって簡潔に書きたいところですね。例えば次のように書ければ楽なはずです。

java

1for (int y = 0; y < 8; y++) { 2 for (int x = 0; x < 8; x++) { 3 buttons[y][x].setText(String.valueOf(Data.field.getSquare(y, x))); 4 } 5}

上のコード例のフィールドbuttonsはButtonインスタンスを保持する二次元の配列のつもりです。しかしFXML上に個別に記述したButtonをコントローラークラスの@FXMLアノテーション付きの配列フィールドのようなものに簡単にマッピングするような機能はJavaFXでは用意されてません。

一案として考えられるのは

  • FXML上に記述したButtonにfx:id属性はつけない

当然ながらコントローラークラス上に@FXMLアノテーション付きのbutton_xxといったフィールドは定義しません。

  • コントローラーの初期化時に動的に必要なButtonインスタンスの参照を二次元配列フィールドへ格納するようなコードを記述する

これを行うためにはButtonを配置している親ノードのメソッドを介して行えばよいでしょう。例えばButtonをGridLayout上に配置した場合、次のようにすればButtonの行・列の位置がインデックスとなるようにbuttonsフィールドを初期化できます。

リスト1

java

1public class Controller { 2 @FXML 3 GridPane gridPane; // Buttonを配置しているGridPane 4 ... 5 Button[][] buttons = new Button[8][8]; 6 7 @FXML 8 void initialize() { 9 for (Node child: gridPane.getChildren()) { 10 int rowIndex = GridPane.getRowIndex(child); 11 int columnIndex = GridPane.getColumnIndex(child); 12 buttons[rowIndex][columnIndex] = (Button)child; 13 } 14 ... 15 } 16}

こうしておくと最初のコードに書いたような繰り返し文が書けるようになります。


補足:
コメントいただくまで、実際にやってみてなかったのですが、やってみると(多分SceneBuilderにクセがあるため)ひっかかりそうな点がありそうなので補足します。

SceneBuilderをつかってGridPaneにButtonなどを配置するとちょっと都合の悪いFXMLが出来上がります。多分以下のようなFXMLになってしまうことでしょう。(関係ないプロパティーは省略してます)

XML

1<GridPane fx:id="gridPane" ...省略...> 2 ...省略... 3 <children> 4 <Button text="0_0" /> 5 <Button text="0_1" GridPane.columnIndex="1" /> 6 <Button text="1_0" GridPane.rowIndex="1" /> 7 <Button text="1_1" GridPane.columnIndex="1" GridPane.rowIndex="1" /> 8 </children> 9</GridPane>

どうもrowIndexやcolumnIndexが0だとその値がデフォルト値という意味でSceneBuilderはFXMLプロパティ(GridPane.columnIndex および GridPane.rowIndex)を生成してくれないようです。
単に画面を表示するだけなら問題ないのですが、上のリスト1にあるようにgetRowIndex, getColumnIndexを取り出すと結果がnullとなりNPE(Null Pointer Exception)が発生してしまいます。

FXML上に手書きでcolumnIndex, rowIndexとして"0"というプロパティー値を明記すればリスト1のコードのままでも動作するのですが、そんなことをしても再度SceneBuilderで編集するとまたプロパティー値が消されてしまうため、よい対処とは言えません。

ということで、リスト1に対してgetRowIndex, getColumnIndexを取得した結果がnullの場合は0を仮定するという対処をすれば動くと思います。いちいちこんな配慮をするのは業腹な気がしますが・・・

リスト1(NPE対策版)

java

1... 2import java.util.Optional; 3 4public class Controller { 5 @FXML 6 GridPane gridPane; // Buttonを配置しているGridPane 7 ... 8 Button[][] buttons = new Button[8][8]; 9 10 @FXML 11 void initialize() { 12 for (Node child: gridPane.getChildren()) { 13 int rowIndex = Optional.ofNullable(GridPane.getRowIndex(child)).orElse(0); 14 int columnIndex = Optional.ofNullable(GridPane.getColumnIndex(child)).orElse(0); 15 buttons[rowIndex][columnIndex] = (Button)child; 16 } 17 ... 18 } 19}

さらに蛇足:
NPE対策コードではnullチェックを多少なりとも簡潔に書こうと思ったのでOptionalを使っています。これはおおむね次のようなコードと同義です。

java

1Integer _rowIndex = GridPane.getRowIndex(child); 2int rowIndex = _rowIndex == null ? 0 : _rowIndex; 3...

本件に関係ないのですが「SceneBuilderのいけてない」感を多少なりとも緩和したいなぁとなんとなく思ったのでこういうコードにしてみました。緩和できてないかもしれませんが・・・

投稿2018/09/15 09:03

編集2018/09/15 13:48
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CreeperSaviour

2018/09/15 10:07

回答有り難うございます。 ``` package jp.starfree.cpsv; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; public class Othello implements Initializable{ Button[][] buttons = new Button[8][8]; @FXML GridPane gridPane; @FXML TextField textField_Black, textField_White, textField_Move; @FXML Menu menu_File; @FXML MenuItem menuItem_NewGame; @FXML public void mouse_onClick_MenuItem_NewGame(ActionEvent e) { textField_Black.setText(Data.field.getValueOfBlack() + " 個"); textField_White.setText(Data.field.getValueOfWhite() + " 個"); textField_Move.setText("黒"); } @Override public void initialize(URL location, ResourceBundle resources) { for (Node child : gridPane.getChildren()) { int rowIndex = gridPane.getRowIndex(child); int columnIndex = gridPane.getColumnIndex(child); buttons[rowIndex][columnIndex] = (Button)child; } for (var i = 0; i < Data.field.getWidth(); i += 1) { for (var j = 0; j < Data.field.getHeight(); j += 1) { buttons[i][j].setText(String.valueOf(Data.field.getSquare(i, j))); } } } } ``` としましたが、 ``` for (Node child: gridPane.getChildren()) { ``` でNullPointerExceptionが発生します。 以下エラー文 ``` javafx.fxml.LoadException: /C:/Users/creep/Desktop/Work/Java/Othello/bin/jp/starfree/cpsv/Othello.fxml at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625) at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603) at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466) at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435) at jp.starfree.cpsv.OthelloCore.start(OthelloCore.java:32) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418) at java.base/java.security.AccessController.doPrivileged(Native Method) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175) at java.base/java.lang.Thread.run(Thread.java:844) Caused by: java.lang.NullPointerException at jp.starfree.cpsv.Othello.initialize(Othello.java:39) at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573) ... 12 more ``` もう一つ、 ``` int rowIndex = gridPane.getRowIndex(child); int columnIndex = gridPane.getColumnIndex(child); ``` で「型 GridPane からの static メソッド getRowIndex(Node) には static にアクセスする必要があります」と言われたのですが、これは ``` int rowIndex = GridPane.getRowIndex(child); int columnIndex = GridPane.getColumnIndex(child); ``` にしても良いのでしょうか。
KSwordOfHaste

2018/09/15 12:43

> 「型 GridPane からの static メソッド getRowIndex(Node) には static にアクセスする必要が...」 失礼しました。コンパイラーのいうとおりです! おっしゃるとおりのコードに変更すべきですね。回答を訂正しておきます。NPEの方は少し調べてみます。
CreeperSaviour

2018/09/15 13:08

> NPE... よろしくお願いします。
KSwordOfHaste

2018/09/15 13:53

NPEのありえる原因について回答に追記しました。ただしこれが質問者さんの環境で実際に起こっているかどうかはわかりません。完全なFXMLファイルの内容とソースコードがあれば再現できますが、ないのでわからないのです。またスタックトレースはありますが、それを解析するには「ソースプログラムの行番号がすぐにわかる」ことが必要です。提示しておられるソースをコピペすれば行番号までわかるのかも知れませんが、そこまではやってません。スタックトレースについては単に張り付けるだけでなくできるだけ自分自身で意味を解釈できるようにしてください。そうできれば「例外が発生しているソースの行はここです」といった情報とともに質問できるので回答がつけやすいと思います。
CreeperSaviour

2018/09/15 15:14 編集

NullPointerExceptionの方、解決いたしましたが、Othello.java:42でClassCastExceptionが発生しました。 スタックトレース https://pastebin.com/mQWYKfek Othello.java:42 buttons[rowIndex][columnIndex] = (Button)child; となり、if(child instanceof Button) を前に付け加えると解消されましたが、Button以外に何があったのでしょうか。良ければ調べる方法も含め、教えていただきたいです。 ~付け加える前~ OthelloCore.java https://pastebin.com/Y4sbyz7Z Data.java https://pastebin.com/NLiVgCu4 Field.java https://pastebin.com/C1Va4ZbL Othello.java https://pastebin.com/z5HtZZjt Othello.fxml https://pastebin.com/6yaWMa4y
KSwordOfHaste

2018/09/15 18:21

これはしたり・・・ 自分が試したのは2x2の小さなGridPane上にButtonを4つ配置したのですが、その際には子供ノードにはButton以外はありませんでした。実際に質問者さんのアプリを実行してみるとunmagedなGroupノードがGridPaneの子ノードとしてできていました。FXML上には記述していないので、おそらくはGridPaneが機能的な都合でひそかに生成しているのではないかと推測します。とりあえずは質問者さんがやっておられる対処どおり「Buttonのインスタンスについてのみ配列へ設定」としておけばいいのではないかと思います。しかしこういう「よくわからないノードが子供ノードにぶらさがっていることがある」という事実があると自分が提案した方法は少々気持ち悪いかも知れません。 いっそのことButtonをFXML上には定義せず、GripPaneのみ記述しておいて、Buttonは動的に生成してGridPaneへ自前で配置したほうが堅いかもです。gridPaneのリファレンスに動的に子どもノードをGridPaneへ配置する例が書かれていますのでそれを見ればそう面倒なことでもありません。
CreeperSaviour

2018/09/16 11:38

>> いっそのこと~~~ 試してみましたが、Othello.java:50 ~ :55の buttons[i][j].setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { System.out.println("Clicked"); } }); ですが、53行目でSystem.out.println(/*今クリックした座標(i, j)*/);とするにはどうすればいいでしょうか。System.out.println(i + " " + j);としてみましたが、「Local variable j defined in an enclosing scope must be final or effectively 」となり、私が求めている結果は得られませんでした。 下記ソースコード OthelloCore.java https://pastebin.com/cLHr98KJ Data.java https://pastebin.com/wXcHzt2c Field.java https://pastebin.com/qL9TZQZK OthelloField.java https://pastebin.com/uT47e0iD Othello.java https://pastebin.com/Qz4x9K2e Othello.fxml https://pastebin.com/P8yGhsjg
KSwordOfHaste

2018/09/16 12:17 編集

> 53行目でSystem.out.println(/*今クリックした座標(i, j)*/);とするにはどうすれば... 実はこれJavaの言語仕様についての「あるある質問」です。 lambda本体などで外側のスコープにあるローカル変数を参照する場合、その変数はfinalでなければならないという制約があるのです。ほかの言語(C#とか)はそういう制限がないので「Javaを使う際の注意点」といえるかもしれません。元のトピックから離れるので詳細を省き結論だけ書きますと次のように書く方法があります。 for (int ri = 0; ri < 8; ri++) { for (int ci = 0; ci < 8; ci++) { int rowIndex = ri; // (事実上)finalなローカル変数を宣言し、望む情報をいったんそれに代入 int colIndex = ci; // 同上 buttons[ri][ci].setOnAction(event -> System.out.format("row=%d col=%d%n", rowIndex, colIndex);//内側のスコープからはfinalなローカル変数の方を参照する。 } } なぜこうなるかの詳細は関連する言語仕様(final, ローカル変数のスコープ)について調べてみることをお勧めします。Javaを使いこなすなら有用な知識と思うので・・・
KSwordOfHaste

2018/09/16 16:15 編集

ちなみにfinalなローカル変数をわざわざ宣言するのは「筋が悪いコード」と感じる人が多いと思います。個人的には「finalでないローカル変数を極力使わない手法を学ぶ」とこのようなヘンテココードを書かずに済むと思います。例えばjava.util.stream.IntStreamを用いると次のように書けます。 IntStream.range(0, 8).forEach(rowIndex ->  IntStream.range(0, 8).forEach(colIndex ->   System.out.format("row=%d col=%d%n", rowIndex, colIndex)  ) ) こう書けばわざわざfinalな変数を別途書く必要がありません。java.util.streamパッケージ内の機能に親しんでいればこちらのコードの方が好まれる気がします。 --- 失礼しました。IntegerではなくIntStreamの間違いです。またパラメーターも違ってました。間違いが多くて申し訳ありません。本コメントのコードについては訂正しました。
CreeperSaviour

2018/09/16 13:46

>> for (int ri = 0; ri < 8; ri++) { >> for (int ci = 0; ci < 8; ci++) { ... の方は問題なく実行できましたが、 >> Integer.range(8).forEach(rowIndex -> >> Integer.range(8).forEach(colIndex -> の方は実行できません。 また、Integer.range(8)の部分が理解できず、教えて頂きたいと思います。 >> java.util.streamパッケージ内の機能に親しんでいれば やはり、リファレンスを読んで理解できる能力があれば、Javaのいろいろな機能を使えるようになれるのでしょうか。
KSwordOfHaste

2018/09/16 16:13

失礼しました。IntegerじゃなくてIntStreamでした orz > リファレンスを読んで理解できる能力があれば、Javaのいろいろな機能を使える それは十分条件ではないけど必要条件ではあると思います。リファレンスを読むのが難しい時期は確かにあると思うのでインターネットで検索したり自分でコードを書いてデバッグする経験を積んだり色々な手段でだんだんとスキルアップしていく必要があるだろうと思います。
CreeperSaviour

2018/09/17 09:33

トピックから離れた質問にも答えて頂き、ありがとうございました。是非参考にさせて頂きます。
guest

0

検索したら良さそうなコードあったので参考までにどうぞ。

[Android] Button 配列を設定する

// Button[] 配列の設定 for(int i=0; i< button.length ;i++) { button[i] = new Button(this); // Tag を設定する button[i].setTag(String.valueOf(i)); button[i].setText(String.format(Locale.US, "Button %d", i)); // 以下略

そもそも論で恐縮なのですがクリックした画面の座標から盤面の座標を計算すればボタン不要になりませんか?

投稿2018/09/15 08:45

編集2018/09/15 09:08
opyon

総合スコア1009

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CreeperSaviour

2018/09/15 09:00

回答有り難うございます。 確かにボタンは不要になりますが、私の質問にある「setTextをまとめて行う」ということの回答にはなっていないため、そちらの方の回答をしていただけると幸いです。
opyon

2018/09/15 09:18

余談ですが、まずは3x3の◯Xゲームなどでプロトタイプ作るとデバッグや実装が楽そうですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問