JavaFX - 如何让ListView自动更新?

时间:2016-04-07 22:31:49

标签: java listview

我正在尝试让我的ListView自动更新,这通常不会成为问题,但更新是从不同控制器中的方法调用的。这是我的困境。

MainSceneController.java

package appController;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

import appData.Admin;
import appData.Album;
import appData.User;
import appDesign.PhotoAlbum;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class MainSceneController implements Initializable {

    @FXML
    ListView<Album> listViewofAlbums = new ListView<Album>();
    @FXML
    TextField albumField;
    @FXML
    TextField numField;
    @FXML 
    TextField lastPhotoField;
    @FXML
    TextField photoRangeField;

    public static Album selectedAlbum;

    public void logout(ActionEvent event) throws Exception {
        PhotoAlbum.primaryStage.show();
        ((Node) (event.getSource())).getScene().getWindow().hide();
    }

    public void addAlbum(ActionEvent event) throws Exception {

        createStage(event, "PhotoExpress - Create New Album", "/appDesign/CreateAlbumDialog.fxml", 526, 249);

    }

    public void rename(ActionEvent event) throws Exception {

        createStage(event, "PhotoExpress - Rename Album", "/appDesign/RenameDialog.fxml", 526, 249);

    }

    public void deleteAlbum(ActionEvent event) throws Exception {

        createStage(event, "PhotoExpress - Confirm Delete", "/appDesign/DeleteAlbumDialog.fxml", 503, 141);

    }

    public void openSearchStage(ActionEvent event) throws Exception {

        createStage(event, "PhotoExpress - Search", "/appDesign/SearchScene.fxml", 868, 534);

    }

    public void createStage(ActionEvent event, String windowTitle, String fxmlLocation, int x, int y) throws Exception {
        Parent root;
        Stage stage;
        try {
            root = FXMLLoader.load(getClass().getResource(fxmlLocation));
            stage = new Stage();
            stage.setTitle(windowTitle);
            stage.setScene(new Scene(root, x, y));
            stage.initModality(Modality.WINDOW_MODAL);
            stage.initOwner(((Node) event.getSource()).getScene().getWindow());
            stage.getIcons().add(new Image("/appDesign/icon.png"));
            stage.show();

            // ((Node)(event.getSource())).getScene().getWindow().hide();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        User temp = LoginSceneController.getLoggedInUser();
        listViewofAlbums.setItems(FXCollections.observableList(User.getUserAlbums(temp)));
        listViewofAlbums.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }

            albumField.setDisable(true);
            numField.setDisable(true);
            lastPhotoField.setDisable(true);
            photoRangeField.setDisable(true);

            albumField.setText(newValue.getName());
            numField.setText(newValue.getSize());
            selectedAlbum = newValue;



        }
        );

        listViewofAlbums.getSelectionModel().select(0);
    }

}

现在,在这个MainScene上有一个&#34;重命名&#34;按钮将弹出一个对话框,您可以在其中输入相关专辑的新名称。此弹出对话框由下面的RenameDialog.java控制。我希望在重命名后自动更新列表视图。

RenameDialogController.java

package appController;

import appData.Admin;
import appData.User;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.Node;

public class RenameAlbumController {

    @FXML
    TextField newAlbumName;

    public void renameAlbum(ActionEvent event){

        Admin.renameAlbum(MainSceneController.selectedAlbum.getName(), newAlbumName.getText());
        ((Node)(event.getSource())).getScene().getWindow().hide();

    }

}

我目前无法从MainSceneController以外的任何地方访问或刷新listViewofAlbums变量。我尝试了很多工作但没有任何工作。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

从“不同的控制器”触发ListView更新的一种方法是发送广播消息,并在主Activity中“捕获”它。

两步:
1)在“不同的控制器”中触发一条消息,指示列表视图现在需要更新。

2)在包含ListAdapter的相关Activity中,创建一个“捕获”消息的侦听器,并触发更新...

(1)发送广播消息:

Intent intent = new Intent(msgUpdateListView);
LocalBroadcastManager.getInstance(getApplicationContext().sendBroadcast(intent);

(2)捕获广播消息(在活动中):

public class MyActivity extends Activity{
  private BroadcastReceiver mBroadcastReceiver;
  private ListAdapter listadapter;

  @Override
  public void onStart(){
    super.onStart();
    //initialise listadapter here...
    mBroadcastReceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
            //we got a message, so update our listview...
            listadapter.notifyDataSetChanged();
        }
    };
  }

  @Override
  public void onResume(){
    super.onResume();
    IntentFilter filter = new IntentFilter(msgUpdateListView);
    LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, filter);
  }

  @Override
  public void onPause(){
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
  }

消息传递常量(过滤器)对两者都可见
final String msgUpdateListView= "MY_LIST_VIEW_NEEDS_UPDATING";