如何在 JavaFX 的 GridPane 中删除“幽灵线”?

Posted

技术标签:

【中文标题】如何在 JavaFX 的 GridPane 中删除“幽灵线”?【英文标题】:How to remove a "ghost line" in a GridPane in JavaFX? 【发布时间】:2021-08-03 13:01:10 【问题描述】:

我创建了一个包含 48 个单元格(8 列 x 6 行)的 GridPane,但我不知道为什么,但有一种我无法删除的“幽灵线”。你能帮帮我吗?

查看带和不带填充的图像以更好地理解我的意思。

GridPane 如何以 10 像素的内边距显示:

GridPane 如何在没有填充的情况下出现,但带有这条“幽灵线”:

这是我正在使用的图像,但你可以使用任何你想要的图像:image.jpg

这是一个可重现的最小示例:

scene.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.*?>

<AnchorPane fx:id="backgroundPane" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
    <children>
    
    <Button fx:id="gridButton" text="Grid" onAction="#Grid" prefWidth="150.0"> </Button>
    <GridPane fx:id="wellsGridPane" AnchorPane.leftAnchor="100.0" AnchorPane.topAnchor="100.0"></GridPane>
    
    </children>
</AnchorPane>

主要

package application;

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 Main extends Application 
    
    public static void main(String[] args) 
        launch(args);
    
    
    @Override
    public void start(Stage mainStage) 

        //load the fxml and css files
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/resources/scene.fxml"));
        
        Parent root = null;
        try 
            root = loader.load();
         
        catch (IOException e) 
            e.printStackTrace();
        
        Scene scene = new Scene(root, 1000, 750);
        
        Controller c = loader.getController();
        c.setStage(mainStage); 
                
        mainStage.setTitle("Software");
        mainStage.setScene(scene);
        
        mainStage.show();
        root.requestFocus(); 
    


控制器

package application;

import java.io.File;
import java.net.MalformedURLException;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Controller 

    @FXML
    private GridPane wellsGridPane;

    @FXML
    private void Grid (ActionEvent event) 
        
        System.out.println("Grid pressed");
         wellsGridPane.getChildren().clear();
         wellsGridPane.getColumnConstraints().clear();
         wellsGridPane.getRowConstraints().clear();
            
         for (int i = 0; i < 8; i++)  //8 cols
             ColumnConstraints colConst = new ColumnConstraints();
             colConst.setPercentWidth(100.0 / 8);
             wellsGridPane.getColumnConstraints().add(colConst);
         
         for (int i = 0; i < 6; i++)  //6 rows
             RowConstraints rowConst = new RowConstraints();
             rowConst.setPercentHeight(100.0 / 6);
             wellsGridPane.getRowConstraints().add(rowConst);    
         
        
         wellsGridPane.setHgap(0); //10 for the first image, 0 for the second image I uploaded
         wellsGridPane.setVgap(0); //10 for the first image, 0 for the second image I uploaded
        
         System.out.println("Grid is " + wellsGridPane.getRowCount() + " x " + wellsGridPane.getColumnCount());
            
         Image img = null;
         try 
            img = new Image(new File("src\\resources\\image.jpg").toURI().toURL().toExternalForm(), 100, 100, true, false);
          
         catch (MalformedURLException e) 
            e.printStackTrace();
         
         
         int i = 0;
         int j = 0;
         
         for (int n=0; n<48; n++)   
             
             ImageView image = new ImageView(img);
        
             StackPane pane = new StackPane();
             pane.getChildren().add(image);
        
             wellsGridPane.getChildren().add(pane);
             
             GridPane.setRowIndex(pane, i);
             GridPane.setColumnIndex(pane, j);
             j++;
        
             if (j == wellsGridPane.getColumnCount())  
                    i++;
                    j=0;
             
         
    
    
    public void setStage(Stage stage)  
        
        stage.setMinHeight(789);
        stage.setMinWidth(1016);
        
        stage.setMaxHeight(789);
        stage.setMaxWidth(1016);
        
        stage.setHeight(789);
        stage.setWidth(1016);
    


【问题讨论】:

请发帖minimal reproducible example @c0der 完成,我更新了代码。请告诉我如何解决这个问题! 要使其成为 mre,您需要使图像可用。最好使用公开可用的图像,例如 http://www.i2symbol.com/images/symbols/rectangle/black_large_square_u2B1B_icon_128x128.png。还要在网格中居中图像do not need a stackpane this controller 是否产生所需的输出? 接受(和赞成)答案优于编辑问题以在问题中放置答案并在标题中添加 [SOLVED](您都不应该这样做)。如果您的解决方案与现有解决方案存在显着差异,您可以发布一个额外的答案(自我回答)并接受它(当您有足够的声誉时)。 【参考方案1】:

没有真正需要设置行和列的宽度和高度。 尝试使用您发布的图像的以下控制器:

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
 
public class Controller 
 
    private static final String B_AND_W_SQUARES_800X800 =   "https://i...content-available-to-author-only...r.com/SfZWK6g.jpg";
 
    private static final int ROWS = 6, COLS = 8;
    @FXML
    private GridPane wellsGridPane;
 
    @FXML
    private void Grid (ActionEvent event) 
      
        Image img =  new Image(B_AND_W_SQUARES_800X800,100,100,false,true,true);
 
         int i = 0, j = 0;
 
         for (int n=0; n< ROWS*COLS; n++) 
 
             ImageView image = new ImageView(img);
             StackPane pane = new StackPane(image);
             GridPane.setRowIndex(pane, i);
             GridPane.setColumnIndex(pane, j);
             wellsGridPane.getChildren().add(pane);
             //wellsGridPane.setHgap(10);   wellsGridPane.setVgap(10);
 
             j++;
 
             if (j == COLS) 
                    i++;
                    j=0;
             
         
    
 
    public void setStage(Stage stage) 
 
        stage.setMinHeight(789);
        stage.setMinWidth(1016);
        stage.setMaxHeight(789);
        stage.setMaxWidth(1016);
        stage.setHeight(789);
        stage.setWidth(1016);
    

【讨论】:

以上是关于如何在 JavaFX 的 GridPane 中删除“幽灵线”?的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX中GridPane的行居中对齐

如何在 JavaFX GridPane 的列之间设置填充?

在GridPane JAVAFX中水平居中一行

JavaFX:如何从 GridPane 中动态创建的文本字段的值计算平均值?

如何使用 GridPane JavaFX 使按钮跨越多个列/行?

Javafx 中 GridPane 中的 HBox