###前提・実現したいこと
java でこういうプログラムを作りたいです
複数選べる選択肢のボックスaがある。
その選択によって結果を返す。
例えば
ボックスaには("下痢","嘔吐","宿便","d","e","f".....""""""""""""""&quo
"""")
って選択肢があって
結果には
心臓病("下痢","嘔吐")
腎臓病("嘔吐","宿便")
が格納してあります。
ボックスaで"下痢"を選択した場合、
その選択肢を含む心臓病が帰ってくる。
ボックスaで"嘔吐"を選択した場合、
その選択肢を含む心臓病、腎臓病が返ってくる。
ボックスaで"宿便"を選択した場合、
その選択肢を含む腎臓病が返ってくる。
ボックスaで"下痢""嘔吐"を選択した場合、
その選択肢を含む心臓病、腎臓病が返ってくる。
ボックスaで"下痢""宿便"を選択した場合、
その選択肢を含む心臓病、腎臓病が返ってくる。
ボックスaで"宿便""嘔吐"を選択した場合、
その選択肢を含む心臓病、腎臓病が返ってくる。
ボックスaで"下痢""宿便""嘔吐"を選択した場合、
その選択肢を含む心臓病、腎臓病が返ってくる。
こういうものを書くときに必要な知識って何ですか?
基本的なものを除いて
コンボボックスとかラジオボタンを使うのかなと思ったのですが手詰まりです。
//追記分
積集合で病名を取り出す方法を考えてみました。
全パターンを網羅したわけではないですが、一応下のコードではdiarrheaとvomitの積集合でibdをピックアップすることができました
```java
Set<String> diarrhea = new HashSet<String>();
diarrhea.add("ibd");
Set<String> vomit = new HashSet<String>(); vomit.add("ckd"); vomit.add("ibd"); Set<String> constipation = new HashSet<String>(); constipation.add("akd"); Set<String> dehydration = new HashSet<String>(); dehydration.add("akd"); dehydration.add("ibd"); Set<String> intersection = new HashSet<String>(diarrhea); intersection.retainAll(vomit); for(String s: intersection) {System.out.println(s);}
//ただ今回のピックアップのイメージは和集合なので、diarrheaとvomitの和集合ibdとckdをピックアップしました。 ```java Set<String> union = new HashSet<String>(diarrhea); union.addAll(vomit); for(String u: union) {System.out.println(u);}
/*ただこれをGUIに組み込もうとしたときに手詰まりになってしまいます。 今まで考えた方法はチェックボックスやラジオボタンのON状態をisSelected()で取得してif文でtrueならラベルを setTextで変更するというものです。
例えばこういう感じです(上記の和集合コードは組み込めてません、以前に考えてみたものです)
```java
RadioButton btn1 = new RadioButton("下痢");
RadioButton btn2 = new RadioButton("嘔吐");
RadioButton btn3 = new RadioButton("宿便");
RadioButton btn4 = new RadioButton("脱水");
if(btn1.isSelected()) {label.setText("akd,ckd"); } if(btn2.isSelected()) {label.setText("ibd,ckd"); } if(btn3.isSelected()) {label.setText("ibd"); } if(btn4.isSelected()) {label.setText("akd"); } if(btn1.isSelected()&&btn2.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn1.isSelected()&&btn3.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn1.isSelected()&&btn4.isSelected()) {label.setText("ckd,akd"); } if(btn2.isSelected()&&btn3.isSelected()) {label.setText("ibd,ckd"); } if(btn2.isSelected()&&btn4.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn3.isSelected()&&btn4.isSelected()) {label.setText("ibd,akd"); } if(btn1.isSelected()&&btn2.isSelected()&&btn3.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn1.isSelected()&&btn2.isSelected()&&btn4.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn1.isSelected()&&btn3.isSelected()&&btn4.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn2.isSelected()&&btn3.isSelected()&&btn4.isSelected()) {label.setText("ibd,ckd,akd"); } if(btn1.isSelected()&&btn2.isSelected()&&bt34.isSelected()&&btn4.isSelected()) {label.setText("ibd,ckd,akd"); }
ただこの方法だと最初のラベル表示から変更されません。そもそも和集合のコードを組み込めてませんし、冗長です。 ```java RadioButton btn1 = new RadioButton("下痢"); btn1.setOnAction( (ActionEvent)-> {label.setText("ckd")});
のようなコードだとラベルを変更できるのですが、複数選択の和集合を想定しているので一つのボタンにたいして 一つの答えみたいになるのはイメージとは異なります。
###発生している問題・エラーメッセージ
追記
疑問
Java
1public class Main extends Application { 2 Label label; 3 RadioButton[] symptomButtons; 4 5 @Override 6 void start(Stage stage) { 7 ... 8 RadioButton btn1 = new RadioButton("下痢"); 9 RadioButton btn2 = new RadioButton("嘔吐"); 10 11 symptomButtons = new RadioButton[] { btn1, btn2, ... }; 12
symptomButtons = new RadioButton[] { btn1, btn2, ... }; ラジオボタンのイベントをsymptomButtonsにまとめているのか? ```java
BooleanProperty[] selectedProperties = Arrays.stream(symptomButtons)
.map(b -> b.selectedProperty())
.toArray(size -> new BooleanProperty[size]);
左辺 配列BooleanProperty[] 変数名selectedPropertiesという変数に各ラジオボタンのチェック状態を格納している? ただ型がBooleanで配列になるのかが分かりません。 配列はintとかStringとかが入ると思っていました。 右辺 配列symptomButtonsのstreamを取得して、マップ関数でsymptomButtonsの中でチェックされたボタンの情報のみ取得している。 それを配列BooleanProperty[]に再変換(再配列)している。 // 各症状のいずれかのボタンの選択状態が変化したときに病名を再計算してlabelへ反映させる ```Java label.textProperty().bind( Bindings.createStringBinding( () -> diagnose(makeSelectedSymptomSet()), selectedProperties));
... labelとBindings.createStringBinding(() -> diagnose(makeSelectedSymptomSet())とselectedPropertiesをbindしている Bindings.createStringBinding(() -> diagnose(makeSelectedSymptomSet())は調べたけど全然わかりませんでした。
Java
1flow.getChildren().addAll(symptomButtons); 2 ... 3 stage.show(); 4}
// 選択状態の症状のみの集合を生成する
Java
1 Set<String> makeSelectedSymptomSet() { 2 return Arrays.stream(symptomButtons) 3 .filter(b -> b.isSelected()) 4 .collect(Collectors.toSet()); 5 } 6
コレクションフレームワークの Setで知っていた文法は
Set<型> 変数名 = new Set()のような形で変数名.add()で要素を入れていく
というものなんですが
上記のような
Set<型> 変数名 {配列を集めるための処理}?みたいな文法は見たことありませんでした。この解釈で合っている分かりませんが
Set<型> 変数名 {配列を集めるための処理}だとすると
配列symptomButtonsをstreamを取得して、マップ関数でsymptomButtonsの中でチェックされたボタンの情報のみ取得している。
その結果をSetで取得してString diagnose(Set<String> symptomSet)に返している。
Java
1// 選択された症状の集合を受け取り、該当する複数の病名を連結した文字列を返す 2 String diagnose(Set<String> symptomSet) { 3 // 実装については質問者さんご自身で進めておられるようなので省略 4 String diagnosis = ...; 5 return diagnosis; 6 } 7}
###該当のソースコード
###試したこと
追記
ほかの方法のアプローチもないかと作ってみましたがうまくいきません
Java
1 2import java.util.HashSet; 3import java.util.Set; 4 5import javafx.application.Application; 6import javafx.scene.Scene; 7import javafx.scene.control.Button; 8import javafx.scene.control.Label; 9import javafx.scene.control.RadioButton; 10import javafx.scene.layout.BorderPane; 11import javafx.scene.layout.FlowPane; 12import javafx.stage.Stage; 13 14public class testd extends Application { 15 Label label; 16 RadioButton[] symptomButtons; 17 18 public static void main(String[] args) { 19 launch(args); 20 } 21 22 @Override 23 public void start(Stage stage) throws Exception { 24 label = new Label(); 25 26 RadioButton btn1 = new RadioButton("下痢"); 27 RadioButton btn2 = new RadioButton("嘔吐"); 28 RadioButton btn3 = new RadioButton("宿便"); 29 RadioButton btn4 = new RadioButton("脱水"); 30 31 Button bt1 = new Button("cal"); 32 Button bt2 = new Button("dignosis"); 33 34 35 Set<String> dignosis = new HashSet<String>(); 36 37 Set<String> diarrhea = new HashSet<String>(); 38 diarrhea.add("ibd"); 39 40 Set<String> vomit = new HashSet<String>(); 41 vomit.add("ckd"); 42 vomit.add("ibd"); 43 44 Set<String> constipation = new HashSet<String>(); 45 constipation.add("akd"); 46 47 Set<String> dehydration = new HashSet<String>(); 48 dehydration.add("akd"); 49 dehydration.add("ibd"); 50 51 btn1.setOnAction(event ->dignosis.addAll(diarrhea)); 52 53 btn2.setOnAction(event ->dignosis.addAll(vomit)); 54 55 btn3.setOnAction(event ->dignosis.addAll(constipation)); 56 57 btn4.setOnAction(event ->dignosis.addAll(dehydration)); 58 59 60 61 62 bt1.setOnAction(event -> {for(String s: dignosis) {label.setText(s);}}); 63 64 65 66 67 /* 68 この方法だとSystem.out.println(s)でイメージ通りの出力ができるのですが、label.setText(s)だと 69 一疾患しかピックアップしてくれませんでした。おそらくラベルの宣言が配列として行われていないから 70 適当な一疾患だけピックアップされているのかなと思いましたが、配列として宣言した場合、配列数を先に 71 決めとかなければならないと書いてあったため、追加されていくこのdignosisには当てはまらないなと思いました。 72 こういうときにラベルをSet<String>のように宣言出来たらいいなと思ったんですが、調べたけど分かりませんでした。 73 */ 74 75 76 77 78 79 80 81 BorderPane pane = new BorderPane(); 82 pane.setTop(label); 83 FlowPane flow = new FlowPane(); 84 flow.getChildren().add(btn1); 85 flow.getChildren().add(btn2); 86 flow.getChildren().add(btn3); 87 flow.getChildren().add(btn4); 88 flow.getChildren().add(bt1); 89 pane.setCenter(flow); 90 Scene scene = new Scene(pane, 320, 120); 91 stage.setScene(scene); 92 stage.show(); 93}
###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報