如何创建一个嵌入在其一列中的按钮的tableview?

时间:2014-05-02 11:21:45

标签: java javafx

我想在我的tablview单元格中嵌入一个按钮。到目前为止,我已经覆盖了表格单元格,并且能够在表格视图中反映出一个按钮。但问题是我想在不同的列中使用不同的按钮名称。基本上表中的数据是动态添加的。我试图动态更改单元格工厂,但正如预期的那样,它反映了所有单元格的变化。对此的任何线索都将不胜感激。

代码:

import java.util.Random;

import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXDynTable extends Application {

    private TableView tableView = new TableView();
    private Button btnNew = new Button("New Record");

    static Random random = new Random();
     public static int i=0;
     private TableColumn col_action;

    static final String Day[] = {
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday"};

    public static class Record {
        private final SimpleIntegerProperty id;
        private final SimpleIntegerProperty value_0;
        private final SimpleIntegerProperty value_1;
        private final SimpleIntegerProperty value_2;
        private final SimpleIntegerProperty value_3;
        private final SimpleIntegerProperty value_4;

        Record(int i, int v0, int v1, int v2, int v3, 
                int v4) {
            this.id = new SimpleIntegerProperty(i);
            this.value_0 = new SimpleIntegerProperty(v0);
            this.value_1 = new SimpleIntegerProperty(v1);
            this.value_2 = new SimpleIntegerProperty(v2);
            this.value_3 = new SimpleIntegerProperty(v3);
            this.value_4 = new SimpleIntegerProperty(v4);
        }

        public int getId() {
            return id.get();
        }

        public void setId(int v) {
            id.set(v);
        }

        public int getValue_0() {
            return value_0.get();
        }

        public void setValue_0(int v) {
            value_0.set(v);
        }

        public int getValue_1() {
            return value_1.get();
        }

        public void setValue_1(int v) {
            value_1.set(v);
        }

        public int getValue_2() {
            return value_2.get();
        }

        public void setValue_2(int v) {
            value_2.set(v);
        }

        public int getValue_3() {
            return value_3.get();
        }

        public void setValue_3(int v) {
            value_3.set(v);
        }

        public int getValue_4() {
            return value_4.get();
        }

        public void setValue_4(int v) {
            value_4.set(v);
        }

    };

    ObservableList<Record> data = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("java-buddy.blogspot.com");
        tableView.setEditable(true);
        Callback<TableColumn, TableCell> cellFactory =
                new Callback<TableColumn, TableCell>() {

                    @Override
                    public TableCell call(TableColumn p) {
                        return new EditingCell();
                    }
                };

        btnNew.setOnAction(btnNewHandler);

        //init table
        //Un-editable column of "id"
        TableColumn col_id = new TableColumn("ID");
        tableView.getColumns().add(col_id);
        col_id.setCellValueFactory(
                    new PropertyValueFactory<Record, String>("id"));

        //Editable columns
        for(int i=0; i<Day.length; i++){
            TableColumn col = new TableColumn(Day[i]);
            col.setCellValueFactory(
                    new PropertyValueFactory<Record, String>(
                            "value_" + String.valueOf(i)));
            tableView.getColumns().add(col);
            col.setCellFactory(cellFactory);
        }

        //Insert Button
 col_action = new TableColumn<>("Action");
        col_action.setSortable(false);

        col_action.setCellValueFactory(
                new Callback<TableColumn.CellDataFeatures<Record, Boolean>, 
                ObservableValue<Boolean>>() {

            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Record, Boolean> p) {
                return new SimpleBooleanProperty(p.getValue() != null);
            }
        });



        col_action.setCellFactory(
                new Callback<TableColumn<Record, Boolean>, TableCell<Record, Boolean>>() {

            @Override
            public TableCell<Record, Boolean> call(TableColumn<Record, Boolean> p) {
                return new ButtonCell("JJJJJ");
            }

        });



        tableView.getColumns().add(col_action);

        tableView.setItems(data);

        Group root = new Group();
        VBox vBox = new VBox();
        vBox.setSpacing(10);
        vBox.getChildren().addAll(btnNew, tableView);
        root.getChildren().add(vBox);
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }

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

    //Define the button cell
    private class ButtonCell extends TableCell<Record, Boolean> {


        private Button cellButton;

        ButtonCell(String text){
              cellButton = new Button("Action");
             cellButton.setText(text);
            cellButton.setOnAction(new EventHandler<ActionEvent>(){

                @Override
                public void handle(ActionEvent t) {
                    // do something when button clicked
                    //...
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            super.updateItem(t, empty);
            if(!empty){
                setGraphic(cellButton);
            }
        }
    }

    EventHandler<ActionEvent> btnNewHandler = 
            new EventHandler<ActionEvent>(){

        @Override
        public void handle(ActionEvent t) {

            //generate new Record with random number
            int newId = data.size();
            if (i%2==0) {


                col_action.setCellFactory(
                        new Callback<TableColumn<Record, Boolean>, TableCell<Record, Boolean>>() {

                    @Override
                    public TableCell<Record, Boolean> call(TableColumn<Record, Boolean> p) {
                        return new ButtonCell("JJJJJ");
                    }

                });
                }
                else
                {

                    col_action.setCellFactory(
                        new Callback<TableColumn<Record, Boolean>, TableCell<Record, Boolean>>() {

                    @Override
                    public TableCell<Record, Boolean> call(TableColumn<Record, Boolean> p) {
                        return new ButtonCell("jakao");
                    }

                });



                }
                i++;
            Record newRec = new Record(
                    newId,
                    random.nextInt(100), 
                    random.nextInt(100), 
                    random.nextInt(100), 
                    random.nextInt(100), 
                    random.nextInt(100));
            data.add(newRec);

        }
    };

    class EditingCell extends TableCell<XYChart.Data, Number> {

        private TextField textField;

        public EditingCell() {}

        @Override
        public void startEdit() {

            super.startEdit();

            if (textField == null) {
                createTextField();
            }

            setGraphic(textField);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            textField.selectAll();
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();

            setText(String.valueOf(getItem()));
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }

        @Override
        public void updateItem(Number item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setGraphic(textField);
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                } else {
                    setText(getString());
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()*2);
            textField.setOnKeyPressed(new EventHandler<KeyEvent>() {

                @Override
                public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(Integer.parseInt(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }

}

1 个答案:

答案 0 :(得分:3)

ButtonCell课程中,您可以这样做:

    ButtonCell(String text){
          cellButton = new Button();
        cellButton.setOnAction(new EventHandler<ActionEvent>(){

            @Override
            public void handle(ActionEvent t) {
                // do something when button clicked
                Record record = (Record) getTableRow().getItem();
                // do something dependent on record....
            }
        });
    }
    //Display button if the row is not empty
    @Override
    protected void updateItem(Boolean t, boolean empty) {
        super.updateItem(t, empty);
        if(!empty){
            final Record record = (Record)getTableRow().getItem();
            cellButton.setText("Do something with "+record.getId());
            setGraphic(cellButton);
        } else { // you must always do the following in cell subclasses:
            setGraphic(null);
        }
    }

构建它的方式略有不同:

而不是让col_action成为TableColumn<Record, Boolean>,您可以将其设为TableColumn<Record, Record>并执行

col_action = new TableColumn<>("Action");
        col_action.setCellValueFactory(
                new Callback<TableColumn.CellDataFeatures<Record, Record>, 
                ObservableValue<Record>>() {

            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Record, Record> p) {
                return new ReadOnlyObjectWrapper<Record>(p.getValue());
            }
        });



        col_action.setCellFactory(
                new Callback<TableColumn<Record, Record>, TableCell<Record, Record>>() {

            @Override
            public TableCell<Record, Record> call(TableColumn<Record, Record> p) {
                return new ButtonCell();
            }

        });

然后ButtonCell将是

private class ButtonCell extends TableCell<Record, Record> {


    private Button cellButton;

    ButtonCell(){
          cellButton = new Button();
        cellButton.setOnAction(new EventHandler<ActionEvent>(){

            @Override
            public void handle(ActionEvent t) {
                // do something when button clicked
                Record record = getItem();
                // do something with record....
            }
        });
    }

    //Display button if the row is not empty
    @Override
    protected void updateItem(Record record, boolean empty) {
        super.updateItem(record, empty);
        if(!empty){
            cellButton.setText("Something with "+record.getId());
            setGraphic(cellButton);
        } else {
            setGraphic(null);
        }
    }
}