[英]How can I use an Arraylist in an object for a method in another class
我的程序應該從用戶那里獲取單詞和定義,並像閃存卡一樣顯示它們。 我已經把所有的詞整理成類等等,現在我需要做的就是讓它在我的應用程序按下按鈕時,控制器類將執行一個方法,該方法將通過 Card 類的數組列表並顯示單詞並最終顯示定義。
我的問題是我有一個包含所有卡片的 reader 類的對象,我希望能夠在 getWordClick 方法中調用隨機卡片。 我不知道如何在另一個類中使用該對象。
public class Main extends Application{
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Scene.fxml"));
primaryStage.setTitle("FlashCards");
Scene scene = new Scene(root, 600, 400, Color.GREY);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main (String[] args){
Reader r = new Reader();
//Initialises the Arraylist and reads the file adding them to arraylist
ArrayList<String> wordList = r.getWordList();
r.OpenFile();
r.readFile(wordList);
r.closeFile();
//Initialises the Definitions Arraylist and reads the file adding them
ArrayList<String> definitionList = r.getDefinitionsList();
r.OpenFile();
r.readFile(definitionList);
r.closeFile();
/* IGNORE IS FOR TESTING PURPOSES
//Wordlist is printed
for (String i : wordList){
System.out.println(i);
}
//Definitions list is printed
for (String i : definitionList){
System.out.println(i);
} */
//Card for each word and def is made
ArrayList<Card> c = r.getCardList();
Main m = new Main();
r.cardSetter(m.addTerms(c, wordList.size(), wordList, definitionList));
//Loops through and displays the word and defs
for (Card i : c){
System.out.printf("%s : %s\n",i.dispWord(),i.dispDef());
}
//Displays the window
launch(args);
}
public ArrayList<Card> addTerms(ArrayList<Card> c, int q, ArrayList<String> word, ArrayList<String> def){
for (int i = 0; i<q; i++){
c.add(new Card(word,def,i));
}
return c;
}
}
這是讀者類
public class Reader {
private Scanner x;
private Scanner sc;
//ArrayList to store the words
private ArrayList<String> wordList = new ArrayList<>();
//ArrayList to store the definitions
private ArrayList<String> definitionsList = new ArrayList<>();
//ArrayList to store the cards
private ArrayList<Card> cardList = new ArrayList<>();
//Simple scanner collects user input
public String getFileName(){
sc = new Scanner(System.in);
return sc.nextLine();
}
//Method to open the file and throw an exception if failed
public void OpenFile(){
try{
x = new Scanner(new File(getFileName()));
}
catch (Exception e){
System.out.println("could not find file");
}
}
//Assigns each line to a Array
public void readFile(ArrayList<String> e){
while(x.hasNext()){
e.add(x.nextLine());
}
}
//Closes file
public void closeFile(){
x.close();
}
//Returns the wordlist
public ArrayList<String> getWordList(){
return wordList;
}
//Returns Definitionlist
public ArrayList<String> getDefinitionsList(){
return definitionsList;
}
//Returns cardList
public ArrayList<Card> getCardList(){
return cardList;
}
public void cardSetter(ArrayList<Card> c){
c = cardList;
}
}
這是卡片類
public class Card {
private String word;
private String definition;
public Card(ArrayList<String> Word,ArrayList<String> Definition, int i){
word = Word.get(i);
definition = Definition.get(i);
}
public String dispWord(){
return word;
}
public String dispDef(){
return definition;
}
}
最后這里是控制器
public class Controller {
Random rand = new Random();
private int Random;
//Makes the rand instance variable int so that the def class can use it
public Button wordBox;
public Label defBox;
public void getWordClick(){
}
public void goExit(){
}
public void goRand(){
}
public void getDefClick(){
}
public void goNext(){
}
public void goPrev(){
}
}
抱歉,我知道它很長,但代碼僅供參考,我主要關心的是如何從Reader r
獲取ArrayList<Card>
以便我可以在getWordClick()
方法的控制器中使用它。 從字面上看,任何幫助都值得贊賞,我只需要有人在我陷入困境時將我推向正確的方向。
更新:我現在編輯了控制器類,所以它看起來像這個公共類 Controller {
Random rand = new Random();
private int Random;
//Makes the rand instance variable int so that the def class can use it
public Button wordBox;
public Label defBox;
private Reader mReader = null;
public Controller(Reader reader){
this.mReader = reader;
}
public Reader getReader(){
return this.mReader;
}
public void getWordClick(){
getReader();
}
public void goExit(){
}
public void goRand(){
}
public void getDefClick(){
}
public void goNext(){
}
public void goPrev(){
}
}
但現在的問題是,當 fxml 文件運行並查找控制器時,它將如何自己創建對象或使用我創建的對象,因為我創建了一個對象,在其中添加了讀取器作為構造函數。 但是我不知道 fxml 文件將如何使用它進行事件處理。
好吧,我看到了一個簡單的方法,雖然我不知道它的內存效率如何:
在您的控制器類中聲明
private Reader mReader = null;
並添加一個構造函數
public Controller(Reader reader)
{
this.mReader = reader;
}
public Reader getReader()
{
return this.mReader;
}
所以你聲明 Controller 類的不同之處在於你將讀取器對象的引用傳遞給該類的引用。 這是一個稱為封裝的概念。
編輯:
可以提供構造函數的類是強大的工具。 多態性等是深入研究的主題,在開發方面有很多實際應用。 我也打算推薦鏈接來查看,但我需要自己做更多的研究:p
一個多態性java的快速谷歌會給你足夠的surknowledge!
EDIT2 代碼重述:
讀者
public class Reader {
private Scanner x;
private Scanner sc;
//ArrayList to store the words
private ArrayList<String> readContent = new ArrayList<>();
private String filename = "";
public Reader()
{
//if every time I want a new reader, I want to read user input
//this.filename = readUserInput();
//If I want to read indefinitely which I will do for now
readIndefinitely();
}
//This will continuously read until the user enters a valid file name
public void readIndefinitely()
{
while (!OpenFile())
{
filename = readUserInput();
}
}
public Reader(String fileIWantToRead)
{
this.filename = fileIWantToRead;
}
public String readUserInput()
{
if (sc != null)
{
sc.close();
sc = null;
}
sc = new Scanner(System.in);
return sc.nextLine();
}
//Simple scanner collects user input
public String getFileName(){
return filename;
}
//Method to open the file and throw an exception if failed
public boolean OpenFile(){
try{
//assume we already know the filename
x = new Scanner(new File(filename));
}
catch (Exception e){
System.out.println("could not find file");
return false;
}
return true;
}
//Assigns each line to a Array
public ArrayList<String> readFile(){
OpenFile();
try
{
readContent.clear();
while(x.hasNext()){
readContent.add(x.nextLine());
}
}
catch(Exception e)
{
e.printStackTrace();
}
closeFile();
return readContent;
}
//Closes file
public void closeFile(){
x.close();
}
public String getReadContent()
{
return readContent;
}
public void clearReadContent()
{
readContent.clear();
}
} //end class
卡片類
public class Card {
private String word;
private String definition;
public Card(String word, String definition){
this.word = word;
this.definition = definition
}
public String getWord(){
return word;
}
public String getDefinition(){
return definition;
}
}
主類
public class Main extends Application{
private ArrayList<Card> mCards = new ArrayList<>();
public Main(ArrayList<Card> cards)
{
this.mCards = cards;
//do what is required to get the cards to the controller either here or start
}
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Scene.fxml"));
primaryStage.setTitle("FlashCards");
Scene scene = new Scene(root, 600, 400, Color.GREY);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main (String[] args){
Reader wordReader = new Reader();
Reader definitionReader = new Reader();
wordReader.readFile();
definitionReader.readFile();
/* IGNORE IS FOR TESTING PURPOSES
//Wordlist is printed
for (String i : wordList){
System.out.println(i);
}
//Definitions list is printed
for (String i : definitionList){
System.out.println(i);
} */
//if we know that both the words and definitions are the same size, we can make cards
ArrayList<Card> c = makeCards(wordReader.getReadContent(), definitionReader.getReadContent());
//Loops through and displays the word and defs
for (Card i : c){
System.out.printf("%s : %s\n",i.dispWord(),i.dispDef());
}
Main m = new Main(c);
//Displays the window
//Not sure how FXMLLoader and this functions as I don't work too much with java but if you pass a reference to main in you'd be good to go
launch(args);
}
public ArrayList<Card> makeCards(ArrayList<String> word, ArrayList<String> def){
ArrayList<Card> cards = new ArrayList<>();
for (int i = 0; i<word.size(); i++){
c.add(new Card(word.get(i),def.get(i)));
}
return c;
}
}
控制器:
public class Controller {
Random rand = new Random();
private int Random;
//Makes the rand instance variable int so that the def class can use it
private int position = 0;
public Button wordBox;
public Label defBox;
//instead of passing in an entire reader we just pass in cards (oops!)
private ArrayList<Card> mCards = new ArrayList<>();
public Controller(ArrayList<Card> cards){
this.mCards = cards;
}
public ArrayList<Card> getCards()
{
return this.mCards;
}
public void goExit(){
//Exit program
}
public void goRand(){
//nextInt in range is ((max - min) + 1) + min and we want a position that corresponds from 0 to the size of cards
position = rand.nextInt(cards.size());
wordBox.setText(cards.get(position).getWord());
defBox.setText(cards.get(position).getDefinition());
}
public void getDefClick(){
//Call to either cards.get(position).getDefinition() or defBox.getText().toString()
}
public void goNext(){
//because retrieving from cards starts at index 0 the equivalent position will require a +1 and we are looking for the next
if (cards.size() < position+2)
{
position++;
wordBox.setText(cards.get(position).getWord();
defBox.setText(cards.get(position).getDefinition();
}
}
public void goPrev(){
//same concept as above but assume that position is already an acceptable value
if (position != 0 && !cards.isEmpty())
{
position--;
wordBox.setText(cards.get(position).getWord());
defBox.setText(cards.get(position).getDefinition());
}
}
}
在我看來,您只需要對面向對象的設計概念進行更多練習即可。
讓我們從邏輯上看這個問題。 您有一個Controller
類,它用作控制Card
列表視圖的一種方式。 這里明顯的問題是您的Controller
實際上缺少要控制的Card
列表,因此,您應該將其添加到類中。
public class Controller {
// The list of Cards that are being controlled.
private ArrayList<Card> cards;
...
}
現在這只是增加了Controller
的抽象概念。 顯然,我們需要一種方法來指定Controller
應該使用哪個Card
列表。 因此,我們應該創建一個構造函數。
public class Controller {
// The list of Cards that are being controlled.
private ArrayList<Card> cards;
...
// A list of cards must be specified when creating a Controller instance.
public Controller(ArrayList<Card> cards) {
this.cards = cards;
}
...
}
另外,您也可以使用賦值函數方法(也就是一組之三法)來設置的使用被稱為半導體封裝的概念卡的列表,如KoalaKoalified提及。
public class Controller {
// The list of Cards that are being controlled.
private ArrayList<Card> cards;
...
// Specify a list of cards.
public void setCards(ArrayList<Card> cards) {
this.cards = cards;
}
...
}
所以現在,在 Main 中,或者在任何您創建Controller
實例的地方,您可以這樣做:
Controller controller = new Controller(r.getCardList());
或者,如果您更喜歡使用 mutator 方法,請執行以下操作:
Controller controller = new Controller();
controller.setCards(r.getCardList());
現在,你的Controller
類可以參考清單Card
S IN每個方法,如果你有一些其他來源它可能重新使用該設備的清單Cards
秒。
我強烈建議對面向對象設計 (OOD) 進行更多研究。 Java 在很大程度上依賴於這種類型的設計。 您的程序中似乎有一些零碎的東西,但您似乎對某些細節以及可能的大局感到有些困惑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.