从GridPane中删除一行 [英] Remove a row from a GridPane

查看:240
本文介绍了从GridPane中删除一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 GridPane 来存储有关城市的信息(在游戏中),但有时我想删除一些行。这是我用于 GridPane的类

  import java。 util.ArrayList; 
import java.util.Arrays;
import java.util.List;

import com.franckyi.kingsim.city.City;

import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;

公共类CityGrid扩展了GridPane {

private List< City>城市;

public CityGrid(){
super();
cities = new ArrayList< City>();
}

public List< City> getCities(){
返回城市;
}

public void deleteCity(int row){
cities.remove(row - 1);
removeNodes(getNodesFromRow(row));
int i = row;
while(!getNodesFromRow(i + 1).isEmpty()){
moveNodes(i + 1,getNodesFromRow(i + 1));
removeNodes(getNodesFromRow(i + 1));
i ++;
}
}

public void addCity(城市){
cities.add(city);
int col = 0;
列表<节点> rowNodes = new ArrayList< Node>();
Button mod = new Button(修改);
mod.setOnAction(event - > {

});
Button del = new Button(删除);
del.setOnAction(event - > {
deleteCity(getRowIndex(del));
});
rowNodes.addAll(Arrays.asList(new CheckBox(),new Text(city.getName()),new Text(city.getStatus()。getText()),
new Text(city。 getTrade()+),新文本(city.getCost()+),新文本(city.getTroops()+),mod,
del));
for(节点n:rowNodes){
n.setId(cities.size()+);
this.add(n,col,cities.size());
col ++;
}
}

private List< Node> getNodesFromRow(int i){
List< Node> list = new ArrayList< Node>();
for(Node n:getChildren()){
if(getRowIndex(n).equals(i)){
list.add(n);
}
}
System.out.println(list.size());
返回清单;
}

private void removeNodes(List< Node> list){
for(Node node:list){
this.getChildren()。remove(getIndex( getColumnIndex(node),getRowIndex(node)));
}
}

private void moveNodes(int row,List< Node> nodes){
int i = 0;
for(节点node:getNodesFromRow(row)){
this.getChildren()。set(getIndex(getColumnIndex(node),getRowIndex(node)),
nodes.get(i) );
i ++;
}
}

private int getIndex(int col,int row){
int i = 0;
for(节点node:getChildren()){
if(getColumnIndex(node)== col&& getRowIndex(node)== row)
return i;
i ++;
}
返回0;
}

}






addCity 功能完美无缺。当我删除添加的最后一个城市时, deleteCity 功能也有效。但是当我删除一个城市时,它会自动删除我删除后添加的所有城市,我不希望这样。



你应该注意到每次执行 getNodesFromRow(int i)方法,它会打印所选行中的节点数。当我添加两个城市并删除第一个城市时,这就是我在控制台中获得的内容:8,0,8,8,8,8,8,0。



<有人能帮助我吗? (如果你想要在家里复制所需的所有代码,请告诉我)

解决方案

  private void moveNodes(int row,List< Node> nodes){
int i = 0;
for(节点node:getNodesFromRow(row)){
this.getChildren()。set(getIndex(getColumnIndex(node),getRowIndex(node)),
nodes.get(i) );
i ++;
}
}

这不起作用。子列表中的索引在 GridPane 中没有任何意义,除了它们的绘制顺序。行/列索引保存到每个孩子的属性地图。要修改这些,您需要使用 static GridPane.setRowIndex 方法



示例

  @Override 
public void start(Stage primaryStage){
按钮btn =新按钮(删除);
TextField tf = new TextField();

TextFormatter<整数> formatter = new TextFormatter<>(new IntegerStringConverter());
formatter.setValue(0);
tf.setTextFormatter(formatter);
btn.disableProperty()。bind(IntegerExpression.integerExpression(formatter.valueProperty())。lessThan(0));

GridPane grid = new GridPane();
grid.setHgap(5);
grid.setVgap(5);

btn.setOnAction((ActionEvent event) - > {
deleteRow(grid,formatter.getValue());
});

for(int r = 0; r< 5; r ++){
for(int c = 0; c< 3; c ++){
grid.add(新文本(r +_+ c),c,r);
}
}

场景场景=新场景(新的VBox(新的HBox(tf,btn),网格));

primaryStage.setScene(scene);
primaryStage.show();
}

static void deleteRow(GridPane grid,final int row){
Set< Node> deleteNodes = new HashSet<>();
for(节点子节点:grid.getChildren()){
//从子节点获取索引
整数rowIndex = GridPane.getRowIndex(child);

//处理索引的空值= 0
int r = rowIndex == null? 0:rowIndex;

if(r> row){
//在删除的行后减去行的行
GridPane.setRowIndex(child,r-1);
} else if(r == row){
//收集匹配行以进行删除
deleteNodes.add(child);
}
}

//从行中删除节点
grid.getChildren()。removeAll(deleteNodes);
}


I'm using a GridPane to stock informations about cities (in a game), but sometimes I want to delete some lines. This is the Class I use for my GridPane :

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.franckyi.kingsim.city.City;

import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;

public class CityGrid extends GridPane {

    private List<City> cities;

    public CityGrid() {
        super();
        cities = new ArrayList<City>();
    }

    public List<City> getCities() {
        return cities;
    }

    public void deleteCity(int row) {
        cities.remove(row - 1);
        removeNodes(getNodesFromRow(row));
        int i = row;
        while (!getNodesFromRow(i + 1).isEmpty()) {
            moveNodes(i + 1, getNodesFromRow(i + 1));
            removeNodes(getNodesFromRow(i + 1));
            i++;
        }
    }

    public void addCity(City city) {
        cities.add(city);
        int col = 0;
        List<Node> rowNodes = new ArrayList<Node>();
        Button mod = new Button("Modify");
        mod.setOnAction(event -> {

        });
        Button del = new Button("Delete");
        del.setOnAction(event -> {
            deleteCity(getRowIndex(del));
        });
        rowNodes.addAll(Arrays.asList(new CheckBox(), new Text(city.getName()), new Text(city.getStatus().getText()),
                new Text(city.getTrade() + ""), new Text(city.getCost() + ""), new Text(city.getTroops() + ""), mod,
                del));
        for (Node n : rowNodes) {
            n.setId(cities.size() + "");
            this.add(n, col, cities.size());
            col++;
        }
    }

    private List<Node> getNodesFromRow(int i) {
        List<Node> list = new ArrayList<Node>();
        for (Node n : getChildren()) {
            if (getRowIndex(n).equals(i)) {
                list.add(n);
            }
        }
        System.out.println(list.size());
        return list;
    }

    private void removeNodes(List<Node> list) {
        for (Node node : list) {
            this.getChildren().remove(getIndex(getColumnIndex(node), getRowIndex(node)));
        }
    }

    private void moveNodes(int row, List<Node> nodes) {
        int i = 0;
        for (Node node : getNodesFromRow(row)) {
            this.getChildren().set(getIndex(getColumnIndex(node), getRowIndex(node)),
                    nodes.get(i));
            i++;
        }
    }

    private int getIndex(int col, int row) {
        int i = 0;
        for (Node node : getChildren()) {
            if (getColumnIndex(node) == col && getRowIndex(node) == row)
                return i;
            i++;
        }
        return 0;
    }

}


The addCity function works perfectly. The deleteCity function also works when I delete the last city added. But when I delete a city, it automatically deletes ALL the cities added after the one I delete, and I don't want that.

You should also notice that everytime the getNodesFromRow(int i) method is executed, it prints the number of Nodes in the selected row. When I add two cities and I delete the first one, this is what I get in the console : 8, 0, 8, 8, 8, 8, 8, 0.

Can someone help me ? (Tell me if you want all the code needed to reproduce it at home)

解决方案

private void moveNodes(int row, List<Node> nodes) {
    int i = 0;
    for (Node node : getNodesFromRow(row)) {
        this.getChildren().set(getIndex(getColumnIndex(node), getRowIndex(node)),
                nodes.get(i));
        i++;
    }
}

This does not work. The index in the child list has no meaning in a GridPaneother then the order in which they are drawn. The row/column index is saved to the properties map of each child. To modify these, you need to use the static GridPane.setRowIndex method.

Example

@Override
public void start(Stage primaryStage) {
    Button btn = new Button("Delete");
    TextField tf = new TextField();

    TextFormatter<Integer> formatter = new TextFormatter<>(new IntegerStringConverter());
    formatter.setValue(0);
    tf.setTextFormatter(formatter);
    btn.disableProperty().bind(IntegerExpression.integerExpression(formatter.valueProperty()).lessThan(0));

    GridPane grid = new GridPane();
    grid.setHgap(5);
    grid.setVgap(5);

    btn.setOnAction((ActionEvent event) -> {
        deleteRow(grid, formatter.getValue());
    });

    for (int r = 0; r < 5; r++) {
        for (int c = 0; c < 3; c++) {
            grid.add(new Text(r+"_"+c), c, r);
        }
    }

    Scene scene = new Scene(new VBox(new HBox(tf, btn), grid));

    primaryStage.setScene(scene);
    primaryStage.show();
}

static void deleteRow(GridPane grid, final int row) {
    Set<Node> deleteNodes = new HashSet<>();
    for (Node child : grid.getChildren()) {
        // get index from child
        Integer rowIndex = GridPane.getRowIndex(child);

        // handle null values for index=0
        int r = rowIndex == null ? 0 : rowIndex;

        if (r > row) {
            // decrement rows for rows after the deleted row
            GridPane.setRowIndex(child, r-1);
        } else if (r == row) {
            // collect matching rows for deletion
            deleteNodes.add(child);
        }
    }

    // remove nodes from row
    grid.getChildren().removeAll(deleteNodes);
}

这篇关于从GridPane中删除一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆