2016-07-10 2 views
1

Я пытаюсь вставить HyperLink с текстом «Удалить» во всех строках столбца. Только строка TabelView будет вставлена ​​при нажатии на кнопку. Гиперссылка также вставлена, но не для всех строк. Он автоматически получает пустую ячейку для предыдущей строки, если добавляются данные следующей строки. Скриншот: enter image description hereВставка гиперссылки в JavaFx TableView

Создатель гиперссылки будет создан, чтобы удалить выбранную строку, если щелкнуть по ней.

Этот метод вызывается, когда пользователь нажимает на кнопку, здесь я создаю ссылку:

public void SalesAdd(ActionEvent actionEvent){ 


    if(quantity.getText().isEmpty()){ 
     quantity.setStyle("-fx-border-color: red"); 
     return; 
    } 
    String name = comboBox.getSelectionModel().getSelectedItem(); 
    String batch = batchno.getText(); 
    String exp = expDate.getText(); 
    int qty = Integer.parseInt(quantity.getText()); 
    Double mrp1 = Double.valueOf(mrp.getText()); 
    Double amt = Double.valueOf(amount.getText()); 
    Double mrpAmount = mrp1*qty; 

    PropertyValueFactory<TableData,String> namePro = new PropertyValueFactory<TableData,String>("name"); 
    PropertyValueFactory<TableData,Integer> qtyPro = new PropertyValueFactory<TableData,Integer>("qty"); 
    PropertyValueFactory<TableData,String> expPro = new PropertyValueFactory<TableData,String>("exp"); 
    PropertyValueFactory<TableData,String> batchPro = new PropertyValueFactory<TableData,String>("batch"); 
    PropertyValueFactory<TableData,Double> mrpPro = new PropertyValueFactory<TableData,Double>("mrp"); 
    PropertyValueFactory<TableData,Double> amtPro = new PropertyValueFactory<TableData,Double>("amt"); 
    PropertyValueFactory<TableData,Hyperlink> rmbutton = new PropertyValueFactory<TableData,Hyperlink>("rbutton"); 

    nameColumn.setCellValueFactory(namePro); 
    qtyColumn.setCellValueFactory(qtyPro); 
    expColumn.setCellValueFactory(expPro); 
    batchColumn.setCellValueFactory(batchPro); 
    mrpColumn.setCellValueFactory(mrpPro); 
    amtColumn.setCellValueFactory(amtPro); 
    removeRowColumn.setCellValueFactory(rmbutton); 



    for(TableData data:tableData){ 
     if(data.getName()==comboBox.getEditor().getText() || data.getName() == comboBox.getSelectionModel().getSelectedItem().toString()){ 
      common.dialogAlert("Already in Table!","Already in the Table!","Already Exist,Please change the quantity!"); 
      return; 
     } 

    } 

    tableData.add(new TableData(name,batch,exp,qty,mrp1,mrpAmount, rbutton)); 
    tableView.setItems(tableData); 

    clearInput(); 
    calctotal(); 


} 

TableData Класс:

public class TableData extends ActionEvent { 
private final SimpleStringProperty name; 
private final SimpleStringProperty batch; 
private final SimpleStringProperty exp; 
private final SimpleIntegerProperty qty; 
private final SimpleDoubleProperty mrp; 
private final SimpleDoubleProperty amt; 
private final Hyperlink rbutton; 

public Hyperlink getRbutton() { 
    return rbutton; 
} 

public TableData(String name, String batch, 
       String exp, int qty, Double mrp, Double amt, Hyperlink rbutton) { 
    this.name = new SimpleStringProperty(name); 
    this.batch = new SimpleStringProperty(batch); 
    this.exp = new SimpleStringProperty(exp); 
    this.qty = new SimpleIntegerProperty(qty); 
    this.mrp = new SimpleDoubleProperty(mrp); 
    this.amt = new SimpleDoubleProperty(amt); 
    this.rbutton = rbutton; 
    this.amt.bind(this.qty.multiply(this.mrp)); 


} 

public String getName() { 
    return name.get(); 
} 

public SimpleStringProperty nameProperty() { 
    return name; 
} 

public void setName(String name) { 
    this.name.set(name); 
} 

public String getBatch() { 
    return batch.get(); 
} 

public SimpleStringProperty batchProperty() { 
    return batch; 
} 

public void setBatch(String batch) { 
    this.batch.set(batch); 
} 

public String getExp() { 
    return exp.get(); 
} 

public SimpleStringProperty expProperty() { 
    return exp; 
} 

public void setExp(String exp) { 
    this.exp.set(exp); 
} 

public int getQty() { 
    return qty.get(); 
} 

public SimpleIntegerProperty qtyProperty() { 
    return qty; 
} 

public void setQty(int qty) { 
    this.qty.set(qty); 
} 

public double getMrp() { 
    return mrp.get(); 
} 

public SimpleDoubleProperty mrpProperty() { 
    return mrp; 
} 

public void setMrp(double mrp) { 
    this.mrp.set(mrp); 
} 

public double getAmt() { 
    return amt.get(); 
} 

public SimpleDoubleProperty amtProperty() { 
    return amt; 
} 

public void setAmt(double amt) { 
    this.amt.set(amt); 
} 

}

Как добавить этот такой же HyperLink для каждой строки в столбце?

+0

Я думаю, вы используете тот же самый объект «HyperLink» для всех строк, который не будет работать, поскольку «Node» не будет добавляться дважды к графику сцены (поэтому только последняя добавленная строка отображает гиперссылку). Для каждого объекта «TableData» вы должны иметь отдельный объект «HyperLink». Я также не понимаю, почему ваша модель данных расширяет «ActionEvent». Здесь вы можете найти хорошую статью о том, как вставить 'HyperLink' в' TableView': http://www.superglobals.net/create-hyperlink-cell-in-javafx-tableview/ – DVarga

+0

приватная гиперссылка rbutton = новая гиперссылка (); rbutton = новая гиперссылка («Удалить»); работает, но теперь слушатель не работает? Слушатель: rbutton.setOnAction (новый EventHandler () { @Override общественных аннулируются ручка (ActionEvent событие) { System.out.println ("Клики");} }); – kodr

ответ

1

Включение элементов интерфейса в класс предметов редко является хорошей идеей (также расширение ActionEvent кажется ненужным). Ссылка работает независимо от любого значения элемента, поэтому он не должен использовать его. Вместо этого используйте ячейку, которая отображает ссылку, когда она не пуста:

public class RemoveCell<T> extends TableCell<T, Void> { 

    private final Hyperlink link; 

    public RemoveCell() { 
     link = new Hyperlink("Remove"); 
     link.setOnAction(evt -> { 
      // remove row item from tableview 
      getTableView().getItems().remove(getTableRow().getIndex()); 
     }); 
    } 

    @Override 
    protected void updateItem(Void item, boolean empty) { 
     super.updateItem(item, empty); 

     setGraphic(empty ? null : link); 
    } 

} 

Эта ячейка не принимает никаких данных. Вместо этого ссылка отображается только для непустых ячеек (setGraphic(empty ? null : link);). Когда инициируется событие onActionHyperlink, данные, доступные из TableCell, используются для удаления соответствующего элемента из TableView, который содержит эту ячейку. Дополнительный код может быть добавлен в тело выражения лямбда в случае необходимости дополнительных операций при удалении элемента.


Не используйте cellValueFactory для removeRowColumn (выбирая Void как тип значения допускает только null значений), а не просто использовать cellFactory создание RemoveCell S:

removeRowColumn.setCellFactory(tc -> new RemoveCell<>()); 

BTW: Вы похоже, воссоздают cellValueFactory с кнопкой, вставляя один новый элемент. Было бы лучше сделать это только один раз для всей таблицы, а не один раз за вставленную таблицу.

+0

Я новичок в java. Не могли бы вы объяснить, как это работает? Я никогда не пишу код следующим образом :(Также у меня есть метод, который вычисляет другую строку. Как мне вызвать этот метод после удаления строки? – kodr

+0

@rpo: о чем вы спрашиваете в своем комментарии, в основном учебник. Это выходит за рамки ответа. Более конкретный вопрос, чем * «Как это работает?» * Может быть подотчетным или, по крайней мере, я мог бы разместить некоторые ссылки для дальнейшего чтения. [Раздел * Cell Factories * здесь] (https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Cell.html) может пролить свет на 'Cell' /' cellFactory концепция. – fabian