Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将对象中的Arraylist用于另一个类中的方法_Java_Object_Arraylist_Javafx_Controller - Fatal编程技术网

Java 如何将对象中的Arraylist用于另一个类中的方法

Java 如何将对象中的Arraylist用于另一个类中的方法,java,object,arraylist,javafx,controller,Java,Object,Arraylist,Javafx,Controller,我的程序应该从用户那里获取单词和定义,并像闪存卡一样显示它们。我已经把所有的单词整理成了类,现在我需要做的就是,当我的应用程序按下一个按钮时,控制器类将执行一个方法,该方法将遍历卡片类的arraylist,并显示单词和最终的定义 我的问题是我有一个reader类的对象,它包含所有卡片,我希望能够在getWordClick方法中调用一个随机卡片。我不知道如何在另一个类中使用该对象 public class Main extends Application{ @Override public v

我的程序应该从用户那里获取单词和定义,并像闪存卡一样显示它们。我已经把所有的单词整理成了类,现在我需要做的就是,当我的应用程序按下一个按钮时,控制器类将执行一个方法,该方法将遍历卡片类的arraylist,并显示单词和最终的定义

我的问题是我有一个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;
}

}
很抱歉,我知道它很长,但代码只是作为参考,我主要关心的是如何从
Reader r
获取
ArrayList
,以便在
getWordClick()
方法的控制器中使用它。从字面上说,任何帮助都是感激的,我只是需要有人把我扔到正确的方向,因为我被卡住了

更新:我现在编辑了控制器类,使其看起来像这样 公共类控制器{

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;
}
因此,控制器类声明的不同之处在于,将reader对象的引用传递给该类的引用。这是一个被称为封装的概念

编辑:

可以提供构造函数的类是功能强大的工具。多态性等是研究得很好的主题,在开发方面有很多实际应用。我还打算推荐一些链接,但我需要自己做更多的研究:p

快速谷歌一下java多态性将为您提供更多的知识

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 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类主扩展应用程序{
private ArrayList mCards=new ArrayList();
公用干管(阵列列表卡)
{
this.mCards=卡片;
//在此处或启动时,执行将卡送到控制器所需的操作
}
@凌驾
public void start(Stage primaryStage)引发异常{
父根=FXMLLoader.load(getClass().getResource(“Scene.fxml”);
初级阶段。设置标题(“抽认卡”);
场景=新场景(根,600,400,颜色.灰色);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
Reader wordReader=新读卡器();
读卡器定义读卡器=新读卡器();
readFile();
definitionReader.readFile();
/*忽略用于测试目的
//字表已打印
for(字符串i:wordList){
系统输出打印LN(i);
}
//定义列表已打印
for(字符串i:定义列表){
系统输出打印LN(i);
} */
//如果我们知道单词和定义大小相同,我们就可以制作卡片
ArrayList c=makeCards(wordReader.getReadContent(),definitionReader.getReadContent());
//循环并显示单词和defs
对于(卡i:c){
System.out.printf(“%s:%s\n”,i.dispWord(),i.dispDef());
}
干管m=新干管(c);
//显示窗口
//我不确定FXMLLoader和它是如何工作的,因为我不太喜欢java,但如果您在中传递对main的引用,那就很好了
发射(args);
}
公共ArrayList生成卡(ArrayList word,ArrayList def){
ArrayList cards=新的ArrayList();

对于(inti=0;i,在我看来,您需要更多地实践面向对象的设计概念

让我们从逻辑上来看这个问题。您有一个
控制器
类,用于控制
列表的视图。这里明显的问题是,您的
控制器
实际上缺少要控制的
列表,因此,您应该将其添加到类中

public class Controller {
    // The list of Cards that are being controlled.
    private ArrayList<Card> cards;

    ...
}
或者,您可以使用mutator方法(也称为asetter方法)使用Koalakoalifid提到的封装概念来设置卡片列表

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;
    }

    ...
}
或者,如果您更喜欢使用mutator方法,则:

Controller controller = new Controller();
controller.setCards(r.getCardList());
现在,您的
Controller
类可以在其每个方法中引用
Card
s列表,如果您有其他一些源提供
Cards
s列表,那么它可能会被重用


我强烈建议对面向对象设计(OOD)进行更多的研究.Java很大程度上依赖于这种类型的设计。您的程序中似乎有一些零散的设计,但您似乎对一些细节和可能的全局有点困惑。

我不理解这个问题。您已经有了一种方法
getCardList
来检索的卡片列表de>Reader
。难道不能用一个实例变量来存储
Reader
,然后调用
Reader.getCardList()吗
getWordClick
中,是否存在操作列表的问题?请参见一个图图:。否则,您可以像任何对象变量一样传递管理它。当FXML文件运行时,当我按下按钮时,它是否会使用我在main中创建的控制器对象来执行方法?因为我正在使用Java FX创建应用程序。如果我在在控制器类旁边,它会使用我在main中创建的对象来处理单击事件吗?我会尝试一下你的建议,看看它是如何运行的:D非常感谢。考虑到OP加载FXML的方式,你不应该调用
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());
        }
    }
}
public class Controller {
    // The list of Cards that are being controlled.
    private ArrayList<Card> cards;

    ...
}
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;
    }

    ...
}
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;
    }

    ...
}
Controller controller = new Controller(r.getCardList());
Controller controller = new Controller();
controller.setCards(r.getCardList());