Java 如何将按钮添加到单列表视图中的单行?

Java 如何将按钮添加到单列表视图中的单行?,java,button,javafx,tableview,Java,Button,Javafx,Tableview,我有一个只有一列的TableView,我想在该TableView/列的最后一行有一个按钮。应禁用该按钮,直到选中一行,然后再启用该按钮。我对此做了很多搜索,但我发现的一切似乎都是在多列表中的每一行添加一个按钮。有没有快速的方法可以做到这一点 以下是一些示例图像: TableButtonView.fxml: package tablebutton; import java.net.URL; import java.util.ResourceBundle; import javafx.beans

我有一个只有一列的TableView,我想在该TableView/列的最后一行有一个按钮。应禁用该按钮,直到选中一行,然后再启用该按钮。我对此做了很多搜索,但我发现的一切似乎都是在多列表中的每一行添加一个按钮。有没有快速的方法可以做到这一点

以下是一些示例图像:

TableButtonView.fxml:

package tablebutton;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class TableButtonController implements Initializable {

    private WebView helpWebView;
    @FXML
    private TextField agencyTextField;
    @FXML
    private Button addButton;
    @FXML
    private TableView<String> agencyTableView;
    @FXML
    private TableColumn<String, String> agencyColumn;
    @FXML
    private Button okAgencyButton;
    @FXML
    private Button cancelAgencyButton;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        agencyColumn.setCellValueFactory(cellData -> 
                new ReadOnlyStringWrapper(cellData.getValue())
        );
        agencyColumn.setStyle( "-fx-alignment: CENTER;");

        ObservableList<String> agencies = FXCollections.observableArrayList(
                    "AA","DL","LH");
        agencyTableView.getItems().addAll(agencies);
    }    

    @FXML
    private void onAdd(ActionEvent event) {
    }


    @FXML
    private void onOK(ActionEvent event) {
        // Just exit for now
        Stage stage = (Stage) okAgencyButton.getScene().getWindow();
        stage.close();
    }

    @FXML
    private void onCancel(ActionEvent event) {
        // Just exit for now
        Stage stage = (Stage) cancelAgencyButton.getScene().getWindow();
        stage.close();
    }

}
package tablebutton;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class TableButton extends Application {

    @Override
    public void start(Stage primaryStage) {
        try
        {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("TableButtonView.fxml"));
            Scene scene = new Scene((Parent) loader.load());
            primaryStage.setScene(scene);
            primaryStage.setTitle("TableView Button Test");
            primaryStage.show();
        }
        catch (IOException ignored)
        {
        }
    }

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

TableButtonController.java:

package tablebutton;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class TableButtonController implements Initializable {

    private WebView helpWebView;
    @FXML
    private TextField agencyTextField;
    @FXML
    private Button addButton;
    @FXML
    private TableView<String> agencyTableView;
    @FXML
    private TableColumn<String, String> agencyColumn;
    @FXML
    private Button okAgencyButton;
    @FXML
    private Button cancelAgencyButton;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        agencyColumn.setCellValueFactory(cellData -> 
                new ReadOnlyStringWrapper(cellData.getValue())
        );
        agencyColumn.setStyle( "-fx-alignment: CENTER;");

        ObservableList<String> agencies = FXCollections.observableArrayList(
                    "AA","DL","LH");
        agencyTableView.getItems().addAll(agencies);
    }    

    @FXML
    private void onAdd(ActionEvent event) {
    }


    @FXML
    private void onOK(ActionEvent event) {
        // Just exit for now
        Stage stage = (Stage) okAgencyButton.getScene().getWindow();
        stage.close();
    }

    @FXML
    private void onCancel(ActionEvent event) {
        // Just exit for now
        Stage stage = (Stage) cancelAgencyButton.getScene().getWindow();
        stage.close();
    }

}
package tablebutton;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class TableButton extends Application {

    @Override
    public void start(Stage primaryStage) {
        try
        {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("TableButtonView.fxml"));
            Scene scene = new Scene((Parent) loader.load());
            primaryStage.setScene(scene);
            primaryStage.setTitle("TableView Button Test");
            primaryStage.show();
        }
        catch (IOException ignored)
        {
        }
    }

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

尝试将按钮实际放在TableView中是有问题的,不建议这样做。让按钮在TableView的最后一行中呈现存在技术上的困难(这不是小事),而且还存在潜在的可用性问题(如果表中有很多行,并且需要滚动该表,那么删除按钮是否只是从视图中滚动出来?如果是,那么如果用户想要删除某些内容,用户将如何找到它)

相反,不要将按钮放在TableView中:

  • 使用包含TableView和按钮的VBox
  • 设置适当的约束,使按钮在TableView的正下方对接,并根据TableView的宽度调整大小
  • 将按钮的“禁用”属性绑定到空的选定项集
  • 示例代码:

    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
    public class Remover extends Application {
        @Override
        public void start(Stage stage) throws Exception {
            ObservableList<NamedColor> colors = FXCollections.observableArrayList(
                    new NamedColor("red", Color.RED),
                    new NamedColor("green", Color.GREEN),
                    new NamedColor("blue", Color.BLUE),
                    new NamedColor("indigo", Color.INDIGO)
            );
    
            TableView<NamedColor> table = new TableView<>(colors);
            table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
            table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
            TableColumn<NamedColor, String> colorNames = new TableColumn<>("Colors");
            colorNames.setCellValueFactory(new PropertyValueFactory<>("name"));
            table.getColumns().add(colorNames);
    
            Button remove = new Button("Remove");
            remove.disableProperty().bind(
                    Bindings.isEmpty(
                            table.getSelectionModel().getSelectedItems()
                    )
            );
            remove.setMaxWidth(Double.MAX_VALUE);
            remove.setOnAction(event ->
                    table.getItems()
                            .removeAll(
                                    table.getSelectionModel().getSelectedItems()
                            )
            );
    
            VBox layout = new VBox(table, remove);
            layout.setPadding(new Insets(10));
    
            stage.setScene(new Scene(layout));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(Remover.class);
        }
    
        public static class NamedColor {
            private String name;
            private Color color;
    
            public NamedColor(String name, Color color) {
                this.name = name;
                this.color = color;
            }
    
            public String getName() {
                return name;
            }
    
            public Color getColor() {
                return color;
            }
        }
    }
    
    导入javafx.application.application;
    导入javafx.beans.binding.Bindings;
    导入javafx.collections.FXCollections;
    导入javafx.collections.ObservableList;
    导入javafx.geometry.Insets;
    导入javafx.scene.scene;
    导入javafx.scene.control.*;
    导入javafx.scene.control.cell.PropertyValueFactory;
    导入javafx.scene.layout.VBox;
    导入javafx.scene.paint.Color;
    导入javafx.stage.stage;
    公共类移除程序扩展应用程序{
    @凌驾
    public void start(Stage)引发异常{
    ObservableList colors=FXCollections.observableArrayList(
    新名称颜色(“红色”,颜色为红色),
    新名称颜色(“绿色”,颜色为绿色),
    新名称颜色(“蓝色”,Color.blue),
    新名称颜色(“靛蓝”,Color.indigo)
    );
    TableView表格=新的TableView(颜色);
    table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_策略);
    TableColumn colorNames=新的TableColumn(“颜色”);
    colorNames.setCellValueFactory(新属性ValueFactory(“名称”);
    table.getColumns().add(颜色名称);
    按钮移除=新按钮(“移除”);
    remove.disableProperty().bind(
    绑定是空的(
    table.getSelectionModel().getSelectedItems()
    )
    );
    移除.setMaxWidth(双倍最大值);
    remove.setOnAction(事件->
    表1.getItems()
    .removeAll(
    table.getSelectionModel().getSelectedItems()
    )
    );
    VBox布局=新的VBox(表格,删除);
    布局。设置填充(新插图(10));
    舞台场景(新场景(布局));
    stage.show();
    }
    公共静态void main(字符串[]args){
    发射(拆卸器级);
    }
    公共静态类NamedColor{
    私有字符串名称;
    私人色彩;
    公共名称颜色(字符串名称、颜色){
    this.name=名称;
    这个颜色=颜色;
    }
    公共字符串getName(){
    返回名称;
    }
    公共颜色getColor(){
    返回颜色;
    }
    }
    }
    
    在图像中,按钮不是
    表视图的一部分(至少据我所知)。此外,我还不清楚用例:允许删除元素的控件通常位于
    TableView
    本身之外,仅从单个列中删除一个值也是非常不寻常的,因为这样的删除会导致所有索引更高的元素也被修改……这让我想知道为什么“添加”会出现按钮位于
    表格视图
    之外。此外,添加到表格中的项目越多,表格的可用性就越低,因为使用滚轮或箭头键滚动到最底部的行所需的时间就越长。您可以通过插入额外的项目并在
    cellValu中对该项目进行不同的处理来获得类似的结果eFactory
    返回一个
    按钮
    包装在
    ObservableValue
    中,而不是项的属性。不用说,这需要额外的修改,因为
    TableView
    从来就不是这样使用的:(例如,选择模型、比较器。)这也使得使用默认单元格类型以外的任何单元格类型都不可能。干净的方法需要您实现自己的皮肤,可能需要您编写多个k loc。@Salome不要将按钮放在TableView中,只需使用包含TableView和按钮的VBox,并带有适当的约束,以便按钮正确对接即可在TableView下面,大小与TableView的宽度相同。将按钮的disable属性绑定到一个新的按钮。我能够实现您的建议,并且它可以根据需要工作。谢谢。您的帮助