実現したいこと
javafxにて、画面内の短形(以降操作キャラと呼びます)を動かし、中央にある枠に触れた時と、枠の内部に入った時にテキストが変化するコードを作成しました。
作成後、「オブジェクトコントロールを個別に設定出来たら、操作キャラは操作キャラのクラスに処理を格納でき、現在のコントロールクラスの可読性が上がるのでは?」と思いました。
そこで質問です。FXMLにおいて、コントロール設定されたFXMLの、特定のオブジェクトのコントロールを他クラスに譲渡するというのは可能なのでしょうか?
発生している問題・分からないこと
実現可能か分からない
・FXMLのオブジェクト(今回の場合は短形を)のコントロールを他のクラスに譲渡できるのか?
→Screen2に記述している、「private Rectangle shape1;//操作キャラ」に関連する移動制御の処理は個別に用意したり、中央枠等の操作キャラ以外を種類ごとに分けて機能を拡張していきたい。
該当のソースコード
java
1package application; 2 3import java.net.URL; 4import java.util.ResourceBundle; 5 6import javafx.animation.AnimationTimer; 7import javafx.beans.binding.BooleanBinding; 8import javafx.beans.property.BooleanProperty; 9import javafx.beans.property.SimpleBooleanProperty; 10import javafx.fxml.FXML; 11import javafx.fxml.Initializable; 12import javafx.geometry.Bounds; 13import javafx.scene.input.KeyCode; 14import javafx.scene.layout.AnchorPane; 15import javafx.scene.paint.Color; 16import javafx.scene.shape.Rectangle; 17import javafx.scene.text.Text; 18 19public class Screen2 implements Initializable{ 20 21 @FXML 22 private AnchorPane screen2;//画面 23 24 @FXML 25 private Rectangle boundary1;//境界(図形) 26 private Bounds boundboundary1;//境界の境界線 27 28 @FXML 29 private Rectangle shape1;//操作キャラ 30 private Bounds boundshape1;//操作キャラ境界線 31 32 boolean tutch = false; 33 boolean included= false; 34 35 36 @FXML 37 private Text text; 38 39 //キー押下変数 40 private BooleanProperty wPressed = new SimpleBooleanProperty(); 41 private BooleanProperty aPressed = new SimpleBooleanProperty(); 42 private BooleanProperty sPressed = new SimpleBooleanProperty(); 43 private BooleanProperty dPressed = new SimpleBooleanProperty(); 44 private BooleanProperty shiftPressed = new SimpleBooleanProperty(); 45 46 private BooleanBinding keyPressed = wPressed.or(aPressed).or(sPressed).or(dPressed).or(shiftPressed); 47 48 49 50 //移動速度 51 private int movementVariable = 2; 52 53 //スピードアップ 54 private int speedUp = 3; 55 56 //短形の高さ: 57 private double shape1Height; 58 59 AnimationTimer timer = new AnimationTimer() { 60 @Override 61 public void handle(long timestamp) { 62 63 boundshape1 = shape1.getBoundsInParent(); 64 boundboundary1 = boundary1.getBoundsInParent(); 65 contains(boundshape1,boundboundary1); 66 67 if(wPressed.get()) { 68 if(shiftPressed.get()) { 69 shape1.setLayoutY(shape1.getLayoutY() - (movementVariable + speedUp)); 70 71 } 72 shape1.setLayoutY(shape1.getLayoutY() - movementVariable); 73 74 } 75 76 if(sPressed.get()){ 77 if(shiftPressed.get()) { 78 shape1.setLayoutY(shape1.getLayoutY() + (movementVariable + speedUp)); 79 } 80 shape1.setLayoutY(shape1.getLayoutY() + movementVariable); 81 } 82 83 if(aPressed.get()){ 84 if(shiftPressed.get()) { 85 shape1.setLayoutX(shape1.getLayoutX() - (movementVariable + speedUp)); 86 } 87 shape1.setLayoutX(shape1.getLayoutX() - movementVariable); 88 } 89 90 if(dPressed.get()){ 91 if(shiftPressed.get()) { 92 shape1.setLayoutX(shape1.getLayoutX() + (movementVariable + speedUp)); 93 } 94 shape1.setLayoutX(shape1.getLayoutX() + movementVariable); 95 } 96 97 if(tutch == true) { 98 text.setText("当たっています。"); 99 text.setFill(Color.RED); 100 } 101 if(included == true){ 102 text.setText("内部に入っています。"); 103 text.setFill(Color.RED); 104 } 105 if(tutch != true && included != true) { 106 text.setText("何にも接触していません。"); 107 } 108 109 110 checkBorder(); 111 112 } 113 }; 114 115 116 @Override 117 public void initialize(URL url, ResourceBundle resourceBundle) { 118 //shape1X座標 119 shape1Height = shape1.getHeight(); 120 //shape1四隅 121 boundshape1 = shape1.getBoundsInParent(); 122 boundboundary1 = boundary1.getBoundsInParent(); 123 movementSetup(); 124 125 keyPressed.addListener(((observableValue, aBoolean, t1) -> { 126 if(!aBoolean){ 127 timer.start(); 128 } else { 129 timer.stop(); 130 } 131 })); 132 } 133 134 public void movementSetup(){ 135 screen2.setOnKeyPressed(e -> { 136 if(e.getCode() == KeyCode.W) { 137 wPressed.set(true); 138 } 139 140 if(e.getCode() == KeyCode.A) { 141 aPressed.set(true); 142 } 143 144 if(e.getCode() == KeyCode.S) { 145 sPressed.set(true); 146 } 147 148 if(e.getCode() == KeyCode.D) { 149 dPressed.set(true); 150 } 151 152 if(e.getCode() == KeyCode.SHIFT) { 153 shiftPressed.set(true); 154 } 155 156 }); 157 158 screen2.setOnKeyReleased(e ->{ 159 if(e.getCode() == KeyCode.W) { 160 wPressed.set(false); 161 } 162 163 if(e.getCode() == KeyCode.A) { 164 aPressed.set(false); 165 } 166 167 if(e.getCode() == KeyCode.S) { 168 sPressed.set(false); 169 } 170 171 if(e.getCode() == KeyCode.D) { 172 dPressed.set(false); 173 } 174 if(e.getCode() == KeyCode.SHIFT) { 175 shiftPressed.set(false); 176 } 177 }); 178 } 179 180 //当たり判定左がチェック対象、右があたる可能性のあるオブジェクト 181 public void contains(Bounds smallShape, Bounds largeShape) { 182 183 //接触判定 184 if ( smallShape.intersects(largeShape)) { 185 tutch = true; 186 }else { 187 tutch = false; 188 } 189 190 //内部判定 191 if(largeShape.getMinX() < smallShape.getMinX() && largeShape.getMinY() < smallShape.getMinY() && 192 largeShape.getMaxX() > smallShape.getMaxX() && largeShape.getMaxY() > smallShape.getMaxY()){ 193 included = true; 194 } 195 else { 196 included = false; 197 } 198 199 200 } 201 202 public void checkBorder() { 203 //上からwsad変数 204 double topbound = 0; 205 double bottombound = screen2.getHeight() - shape1Height; 206 double leftbound = 0; 207 double lightbound = screen2.getWidth() - shape1Height; 208 209 //w移動制御 210 if(shape1.getLayoutY() <= topbound) { 211 shape1.setLayoutY(topbound); 212 } 213 //s移動制御 214 if(shape1.getLayoutY() >= bottombound) { 215 shape1.setLayoutY(bottombound); 216 } 217 //a移動制御 218 if(shape1.getLayoutX() <= leftbound) { 219 shape1.setLayoutX(leftbound); 220 } 221 //d移動制御 222 if(shape1.getLayoutX() >= lightbound) { 223 shape1.setLayoutY(lightbound); 224 } 225 226 } 227 228 229}
FXML
1<?xml version="1.0" encoding="UTF-8"?> 2 3<?import javafx.scene.layout.AnchorPane?> 4<?import javafx.scene.shape.Rectangle?> 5<?import javafx.scene.text.Text?> 6 7<AnchorPane fx:id="screen2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/24.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Screen2"> 8 <children> 9 <Rectangle fx:id="shape1" arcHeight="5.0" arcWidth="5.0" fill="#ff8c1f" height="100.0" layoutX="450.0" layoutY="400.0" stroke="BLACK" strokeType="INSIDE" width="100.0" /> 10 <Rectangle fx:id="boundary1" arcHeight="5.0" arcWidth="5.0" fill="TRANSPARENT" height="200.0" layoutX="400.0" layoutY="150.0" stroke="BLACK" strokeType="INSIDE" width="200.0" AnchorPane.bottomAnchor="150.0" AnchorPane.leftAnchor="400.0" AnchorPane.rightAnchor="400.0" AnchorPane.topAnchor="150.0" /> 11 <Text fx:id="text" layoutX="417.0" layoutY="63.0" strokeType="OUTSIDE" strokeWidth="0.0" wrappingWidth="166.80340576171875" /> 12 </children> 13</AnchorPane> 14
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
試してみたこと。
・操作キャラを別のFXMLに作成。Screen2.FXMLで呼び出し(include)、Screen2クラスの操作キャラの初期値設定箇所に割り込ませてみた。
→対象の短形でNullpoint発生
補足
特になし

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/10/08 21:56