2017-09-19 147 views
0

そうです、私はユーザーがSpace Marine(Warhammer 40k)軍隊を構築し、私が苦労しているプログラム。この部分では、ユーザーがComboBoxから 'Unit Type'を選択できるようになり、下の別のComboBoxには、最初のComboBoxで選択した 'Unit Type'のすべての単位が入力されます。JavaFX - ComboBoxでChangeListenerを使用して複数のArrayListを持つ2番目のComboBoxを設定する

たとえば、最初のComboBoxでElite 'Unit Type'を選択した場合、2番目のComboBoxには、「Dreadnought」、「Ironclad Dreadnought」などのElite 'Unit Type'のすべてのユニットが入力されます。 「センチュリオン・アサルト」、「司令」、「名誉守護隊」、「スターンガード・ベテラン」、「ターミネーター」、「ヴァンガード退役軍人」などがあります。それぞれに独自のユニットを持つ8つの「ユニットタイプ」があります。

これを達成するための現在の設定は次のとおりです。私はunitTypeListと呼ばれる 'Unit Types'のリストを持っています。このリストは8つの「ユニットタイプ」をすべて保持します。私はまた、8つの別々のリスト(それぞれが「ユニットタイプ」を表す)を持っています。このリストは、その「ユニットタイプ」に対して複数のユニットを保持しています。それから私は前に述べたように8つのセパレートリストのそれぞれを保持するもう一つのリストを持っています。だからそれはリストです。thatsは8つの他のリストを保持しています。

最初のComboBoxに 'Unit Types'を入力するために、unitTypeListをunitTypeOlistというObservableListに配置しました。私は、そのObservableList unitTypeOListを最初のComboBoxに設定しました。これは正常に動作します。

ここで、2番目のComboBoxに正しい単位を設定するため、最初のComboBoxにChangeListenerを追加することにしました。最初のComboBoxの入力を受け取り、2番目のComboBoxに、最初のComboBoxの 'Unit Type'の選択。

しかし、ここで問題が発生します。私はChangeListenerに別のObservableListを作成し、 'Unit Type'の各ユニットを含む8つの別々のリストを保持するListを配置します。しかし、プログラムを実行し、最初のComboBoxから 'Unit Type'を選択しようとすると、プログラムは巨大なエラーで終了します。スレッド "JavaFX Application Thread"の例外java.lang.ClassCastException:gui.model.Unit_Typeをjava.lang.Integerにキャストできません。

intへのキャストとは明らかに関係しています。しかし、私はChangeListenerを他の方法で使用したいものをどのように達成するのかは分かりません。私は最初の段落の要件を満たすためにいくつかの助けが必要です。

私は既にこれを探してみましたが、this questionは既に非常に役に立ちました。 (私の設定はこの質問に大きく基づいています)しかし、私は自分の要求が少し複雑であると思います。ここで

は私のプログラムのAddUnitPaneクラスのコードは、(私はそれを私ができる最善をコメントしようとしました)です:

package gui.view; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import elites.terminator.Terminator; 
import gui.model.Unit; 
import gui.model.Unit_Type; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.HPos; 
import javafx.geometry.Pos; 
import javafx.scene.control.Button; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.ColumnConstraints; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.HBox; 
import troops.scout.Scout; 

public class AddUnitPane extends GridPane 
{ 
    private List<Unit_Type> unitTypeList; //Declare the unitTypeList, which holds a list of unit types 
    private List<String> elitesList, fastAtkList, heavySptList, hqList, lordsowList, specialCList, transportList, troopsList; //Declare the sublists that hold all the units for the type of unit 
    private List<List<String>> unitList; //Declare the unitList that holds all the sublists units 
    private Label unitTypeLbl, unitLbl, squadNameLbl, squadSizeLbl; 
    private ComboBox<Unit_Type> unitTypeCombo; 
    private ComboBox<String> unitCombo; 
    private ComboBox<Integer> squadSizeCombo; 
    private TextField squadNameTf; 
    private Button addSquadBtn; 

    public AddUnitPane() 
    { 
     this.setVgap(15); 
     this.setHgap(20); 
     this.setAlignment(Pos.CENTER); 

     ColumnConstraints col1 = new ColumnConstraints(); 
     col1.setHalignment(HPos.RIGHT); 

     this.getColumnConstraints().add(col1); 

     //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

     unitTypeList = new ArrayList<>(); //Initialise the unitTypeList 
     Collections.addAll(unitTypeList, new Unit_Type("Elites"), new Unit_Type("Fast Attack"), new Unit_Type("Heavy Support"), new Unit_Type("HQ"), new Unit_Type("Lords Of War"), 
       new Unit_Type("Special Characters"), new Unit_Type("Transport"), new Unit_Type("Troops")); //Populate the unitTypeList 

     ObservableList unitTypeOList = FXCollections.observableArrayList(unitTypeList); //Add the UnitTypeList to an observableArrayList 

     //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

     elitesList = new ArrayList<>(); //Initialise and populate all the of the sublists that hold each unit for that type 
     Collections.addAll(elitesList, "Dreadnought", "Ironclad Dreadnought", "Venerable Dreadnought", "Assault Terminator", "Centurion Assault", "Command", "Honour Guard", 
       "Sternguard Veteran", "Terminator", "Vanguard Veterans"); 

     fastAtkList = new ArrayList<>(); 
     Collections.addAll(fastAtkList, "Attack Bike", "Stormhawk Interceptor", "Stormtalon Gunship", "Assault", "Bike", "Land Speeder", "Scout Bike"); 

     heavySptList = new ArrayList<>(); 
     Collections.addAll(heavySptList, "Hunter", "Land Raider Crusader", "Land Raider Redeemer", "Land Raider", "Predator", "Stalker", "Stormraaven Gunship", "Vindicator", 
       "Whirlwind", "Centurion Devastator", "Devastator", "Thunderfire Cannon"); 

     hqList = new ArrayList<>(); 
     Collections.addAll(hqList, "Captain", "Chaplain", "Librarian", "Techmarine"); 

     lordsowList = new ArrayList<>(); 
     Collections.addAll(lordsowList, "Marneus Calger", "Roboute Guilliman"); 

     specialCList = new ArrayList<>(); 
     Collections.addAll(specialCList, "Antaro Chronus", "Cato Sicarius", "Ortan Cassius", "Torias Telion", "Varro Tigurius"); 

     transportList = new ArrayList<>(); 
     Collections.addAll(transportList, "Drop Pod", "Land Speeder Storm", "Razorback", "Rhino"); 

     troopsList = new ArrayList<>(); 
     Collections.addAll(troopsList, "Scout", "Tactical"); 

     //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

     unitList = new ArrayList<>(); //Initialise and populate the List thats holds other Lists that hold the different units 
     Collections.addAll(unitList, elitesList, fastAtkList, heavySptList, hqList, lordsowList, specialCList, transportList, troopsList); 

     //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 


     unitTypeLbl = new Label("Select The Unit Class: "); //Initialise all of the labels 
     unitLbl = new Label("Select The Unit: "); 
     squadNameLbl = new Label("Squad Name: "); 
     squadSizeLbl = new Label("Squad Size"); 

     //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

     unitTypeCombo = new ComboBox<Unit_Type>(); //Initialise the unitTypeCombo 
     unitTypeCombo.setItems(unitTypeOList); //Populate the unitTypeCombo with the UnitTypeOList (observable list) from line 56 
     unitTypeCombo.getSelectionModel().selectFirst(); //Set the unitTypeCombo to show the first item 

     unitCombo = new ComboBox<>(); //Initialise the unitCombo 

     unitTypeCombo.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() //add a change listener to the unitTypeCombo 
     { 
      @Override 
      public void changed(ObservableValue arg0, Object arg1, Object arg2) 
      { 
       ObservableList unitOList = FXCollections.observableArrayList(unitList.get((int) arg2)); //add the unitList from line 88 to an observable list and cast arg2 to an int 
       unitCombo.setItems(unitOList); //set the unitCombo items with the observable list from above 

      }   
     }); 

     unitCombo = new ComboBox<>(); 

     squadNameTf = new TextField(); 

     squadSizeCombo = new ComboBox<>(); 

     addSquadBtn = new Button("Add Squad"); 

     this.add(unitTypeLbl, 0, 1); 
     this.add(unitTypeCombo, 1, 1); 

     this.add(unitLbl, 0, 2); 
     this.add(unitCombo, 1, 2); 

     this.add(squadNameLbl, 0, 3); 
     this.add(squadNameTf, 1, 3); 

     this.add(squadSizeLbl, 0, 4); 
     this.add(squadSizeCombo, 1, 4); 

     this.add(new HBox(), 0, 5); 
     this.add(addSquadBtn, 1, 5);   
    } 

    public ComboBox<Unit_Type> getUnitClass() 
    { 
     return unitTypeCombo;  
    } 

    public ComboBox<String> getUnit() 
    { 
     return unitCombo; 
    } 

    public String getSquadName() 
    { 
     return squadNameTf.getText(); 
    } 

    public ComboBox<Integer> getSquadSize() 
    { 
     return squadSizeCombo; 
    } 

    public void AddUnitHandler(EventHandler<ActionEvent> handler) 
    { 
     addSquadBtn.setOnAction(handler);  
    } 
} 

答えて

1

これはあなたが生のタイプを使用しないでください理由の一つであります。

ChangeListenerは、Property<Unit_Type>の代わりにIntegerPropertyを聞いているかのように書かれています。キャストはIntegerUnit_Typeオブジェクトを形成しますが、この表現で例外を取得しては不可能である。

unitList.get((int) arg2) 

ChangeListener<Integer>が代わりに使用された場合あなたのコンパイラは、この問題について不平を言っただろう。

代わりにselectedIndexプロパティを聞くことができます(もちろん有効なインデックス - -1も可能です)。

リストをプロパティとしてUnit_Typeに簡単に追加する方が簡単です。でも、もしあれば

elitesList = Arrays.asList("Dreadnought", "Ironclad Dreadnought", "Venerable Dreadnought", "Assault Terminator", "Centurion Assault", "Command", "Honour Guard", 
          "Sternguard Veteran", "Terminator", "Vanguard Veterans"); 
... 

:ところで

unitTypeCombo.valueProperty().addListener(new ChangeListener<Unit_Type>() { 
    @Override 
    public void changed(ObservableValue<? extends Unit_Type> observable, Unit_Type oldValue, Unit_Type newValue) { 
     unitCombo.setItems(newValue == null ? FXCollections.emptyObservableList() : newValue.getUnits()); 
    } 
}); 

:あなたがリストのサイズを変更することはありませんので、それらを初期化する次のような方法がはるかに簡単になりますこれは、あなたがこのような何かを書くことができるようになります特定のリストタイプを使用したい場合は、定型コードを減らし、ヘルパーメソッドを導入することをお勧めします。

elitesList = createArrayList("Dreadnought", "Ironclad Dreadnought", "Venerable Dreadnought", "Assault Terminator", "Centurion Assault", "Command", "Honour Guard", 
          "Sternguard Veteran", "Terminator", "Vanguard Veterans"); 
... 
+0

Unit_TypeクラスでgetUnitsメソッドが必要ですか?私はその部分で少し混乱しています。 getUnitsメソッドのどちらを返すべきか正確にはわかりません。私は私のリストを返すべきですthatsは他の8つのサブリストを保持し、次にインデックスを選択しますか?私は、Unit_Typeクラスがユニットの集合であることに注意してください。ユニットはArrayListです必要に応じてUnit_Typeクラスを共有できます。 – GR412

+0

'getUnits'は与えられた型の単位を含む' ObservableList 'を返します... – fabian

+0

私はそれを理解することができたと思いますが、単位のリストを追加しようとするとうまくいかないようです。これは、各ユニットタイプにseprate文字列を追加する場合にのみ機能します。私は別の質問を掲載して、私の意味をよりよく理解しています。多分あなたは見てみるといいかもしれません:https://stackoverflow.com/questions/46342627/javafx-using-a-changelistener-on-a-combobox-to-populate-another-combobox-with – GR412

関連する問題