Maslor
Maslor

Reputation: 1910

How do I use a Map as a TableView ObservableMap object parameter?

I am currently developing an application that, internally, has an HashMap that stores created Tasks associated to a string, declared like this:

private Map<String, Task> _tabs = new HashMap<String,Task>();

It works fine in the terminal but currently I am developing a javafx GUI to said application and, at first, I thought I needed a ListView object to list the tasks and I did as follows:

    @FXML
    private ListView<Task> lstView = new ListView<Task>();
    @FXML
    private CheckBox verified;
    @FXML
    private CheckBox finished;
    @FXML
    private TextField name;
    @FXML
    private TextArea description;
    @FXML
    private Button refresh;
    @FXML 
    private TextField tf;
    @FXML
    private TextField taskName;
    @FXML
    private TextField assignee;
    @FXML
    private TextArea comment;
    @FXML
    private TableColumn taskName;
    @FXML
    private TableColumn taskAuthor;
    @FXML
    private TableColumn taskAssignee;

    
    ScreenController controller;


    @FXML
    public void refreshList() {
    
        lstView.setItems(FXCollections.observableArrayList(shl.mapToArray())); //shl is my Shell object that stores the Map and is inherited by this javaFX controller class.
        lstView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        lstView.setOnMouseClicked(new EventHandler<MouseEvent>() {
            
            @Override
            public void handle(MouseEvent event) {
                System.out.println("clicked on " + lstView.getSelectionModel().getSelectedItem());
                shl.setCurrentTab((Task) lstView.getSelectionModel().getSelectedItem());
                taskName.setText(shl.getCurrentTab().getName());
                description.setText(shl.getCurrentTaskDescription());
                name.setText(shl.getCurrentTab().getAssignee());
                comment.setText(shl.getCurrentTab().getComment());
                
            }
        });
    }

This also worked. However, notice that I use a mapToAray() method I wrote, which basically returns a Task list.

I wrote so that the ListView would display elements like this.

TaskName - AssignedUser

This was fine but now I also to display the creator of the task and I no longer see ListView as the object I need. So I am trying to switch to TableView, yet I'm not being able to get it to work, receiving the Map...

@FXML
private TableView<String,Task> taskTable = new TableView<String,Task>();

@FXML
    public void refreshList() {
    
        taskTable.setItems((FXCollections.observableMap(shl.getTabs())); //I know that setItems() requires a ListView object, I just don't  see how to do this without it
        taskTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        taskTable.setOnMouseClicked(new EventHandler<MouseEvent>() {
            
            @Override
            public void handle(MouseEvent event) {
                System.out.println("clicked on " + taskTable.getSelectionModel().getSelectedItem());
                shl.setCurrentTab((Task) taskTable.getSelectionModel().getSelectedItem());
                taskName.setText(shl.getCurrentTab().getName());
                description.setText(shl.getCurrentTaskDescription());
                name.setText(shl.getCurrentTab().getAssignee());
                comment.setText(shl.getCurrentTab().getComment());
                
            }
        });
    }

Note: The three table columns are c1,c2and c3

I need my table to display something like this:

Task Name | Task Author | Task Assignee

Rock Climbing | Dwayne JOHNSON | Hulk HOGAN

EDIT

I forgot to paste my Task class, here it is:

 package main.entities;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.naming.NoPermissionException;

public class Task implements Serializable{   
    /**
     * 
     */
    private static final long serialVersionUID = -5416272475989116821L;
    private List<File> _files = new ArrayList<File>();
    private User _assignee;
    private boolean _status = false;
    private Shell _shl;
    private String _name;
    private String _description;
    private String _lastEditDate;
    private User _lastEditor;
    private String comment;
    private String author;
    
    /**
     * @param shl
     * @param name
     * @param description
     * @param assignee
     */
    public Task(Shell shl, String name, String description, String assignee){
        this._shl = shl;
        this._name = name;
        this._description = description;
        this._assignee = shl.findUser(assignee);
        this.author = shl.getCurrentUser().getName();
        shl.addTask(this);
    }
    
    /**
     * (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    public String toString(){
        return _name+" - "+_assignee;
    }
    
    /**
     * @return description string
     */
    public String getDescription(){
        return this._description;
    }
    
    /**
     * @param description
     */
    public void setDescription(String description){
        this._description = description;
    }
    
    /**
     * @param String fileName: name of the file that will be created with the tab saved object locally
     */
    public void save(String fileName){
        try{
            ObjectOutputStream stream =
                new ObjectOutputStream(
                new BufferedOutputStream(
                new FileOutputStream(fileName)));
            
            
            this.setTabName(fileName);
            stream.writeObject(this);
            stream.flush();
            stream.close();
        }catch(IOException ioe){
            ioe.printStackTrace();
        }
    }
    
    /**
     * @param name
     */
    private void setTabName(String name) {
        this.setName(name);
    }

    /**
     * @param file name: String
     * @param userID: String
     */
    public void deleteFile(String fileName, String uID){
        _shl.removeFile(_shl.getFile(fileName));
    }
        
    /**
     * @param fileName
     * @return null
     * @throws IOException
     */
    public File downloadFile(String fileName) throws IOException{
        return null;
        //TODO
        //This method is probably deprecated by javaFX fileChooser
    }   
    
    /**
     * @param trabalhador
     * @throws NoPermissionException
     */
    public void setAssignee(User trabalhador) {
        this._assignee = trabalhador;
    }
    
    /**
     * @param Verification
     * @return boolean status
     */
    public boolean checkStatus(){
        return _status;
    }
    
    /**
     * changes status to opposite
     * @throws NoPermissionException
     */
    public void changeStatus() throws NoPermissionException{
        if (_shl.getCurrentUser() instanceof Manager){
            if (this._status == true)
                this._status = false;
            else this._status = true;
        }
        else throw new NoPermissionException("You need Manager rights to change Status");   
    }
    
    /**
     * @return void;
     */
    public String getAssignee(){
        return this._assignee.getID();
    }
    
    /**
     * @return task name
     */
    public String getName() {
        return _name;
    }
    
    /**
     * @param _name
     */
    public void setName(String _name) {
        this._name = _name;
    }
    
    /**
     * @param f
     */
    public void addFile(File f) {
        this._files.add(f);
    } 
    
    /**
     * @return date of last edition
     */
    public String getLastEditDate() {
        return _lastEditDate;
    }
    
    /**
     * @param _lastEditDate
     */
    public void setLastEditDate(String _lastEditDate) {
        this._lastEditDate = _lastEditDate;
    }
    
    /**
     * @return last editor
     */
    public User getLastEditor() {
        return _lastEditor;
    }
    
    /**
     * @param _lastEditor
     */
    public void setLastEditor(User _lastEditor) {
        this._lastEditor = _lastEditor;
    }

    public File getFile() {
        //TODO
        return null;
        
    }

    public void setComment(String text) {
        this.comment = text;
    }

    public String getComment() {
        return this.comment;
    }
}

Upvotes: 0

Views: 2101

Answers (1)

Coder55
Coder55

Reputation: 559

You can use the map as a table view this way:

Please mention that I used Strings as sample data here, not Tasks.

public class MapTableView extends Application {

@Override
public void start(Stage stage) {

    // sample data
    Map<String, String> map = new HashMap<>();
    map.put("one", "One");
    map.put("two", "Two");
    map.put("three", "Three");


    // use fully detailed type for Map.Entry<String, String> 
    TableColumn<Map.Entry<String, String>, String> column1 = new TableColumn<>("Key");
    column1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() {

        @Override
        public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, String> p) {
            // this callback returns property for just one cell, you can't use a loop here
            // for first column we use key
            return new SimpleStringProperty(p.getValue().getKey());
        }
    });

    TableColumn<Map.Entry<String, String>, String> column2 = new TableColumn<>("Value");
    column2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() {

        @Override
        public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, String> p) {
            // for second column we use value
            return new SimpleStringProperty(p.getValue().getValue());
        }
    });

    ObservableList<Map.Entry<String, String>> items = FXCollections.observableArrayList(map.entrySet());
    final TableView<Map.Entry<String,String>> table = new TableView<>(items);

    table.getColumns().setAll(column1, column2);

    Scene scene = new Scene(table, 400, 400);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch();
}
}

Upvotes: 1

Related Questions