在 JavaFX 中隐藏表格

Posted

技术标签:

【中文标题】在 JavaFX 中隐藏表格【英文标题】:Hiding a table in JavaFX 【发布时间】:2017-05-20 11:24:33 【问题描述】:

我在 JavaFX 中有一个这样声明的表:

@FXML private TableView tableEF;

我怎样才能,例如当我按下一个按钮或更改 ComboBox 中的值时,将其从 GUI 中完全隐藏,然后在我按下另一个按钮或再次更改 ComboBox 中的值后,使其再次可见?

编辑:

public class AllController 

private RaportPDF wrpdf;
@FXML private Pagination pagination1;
@FXML private Pagination pagination2;
@FXML private Pagination pagination3;

public void updateSarcina(Observable<Sarcina> observable) 

    SarcinaService service = (SarcinaService)observable;
    smodel.setAll(service.getAllSarcinas());

public void updatePost(Observable<Post> observable) 

    PostService service = (PostService)observable;
    pmodel.setAll(service.getAllPosts());

public void updateFisa(Observable<Elementfisa> observable) 

    FisaService service = (FisaService)observable;
    fmodel.setAll(service.getAllFisa());


public Observer<Sarcina> getSarcinaObserver() 

    return new Observer<Sarcina>() 
    
        @Override
        public void update(Observable<Sarcina> observable) 
        
            updateSarcina(observable);
        
    ;

public Observer<Post> getPostObserver() 

    return new Observer<Post>() 
    
        @Override
        public void update(Observable<Post> observable) 
        
            updatePost(observable);
        
    ;

public Observer<Elementfisa> getFisaObserver() 

    return new Observer<Elementfisa>() 
    
        @Override
        public void update(Observable<Elementfisa> observable) 
        
            updateFisa(observable);
        
    ;



@SuppressWarnings("rawtypes")
@FXML private TableView allTable;

@FXML private TableView<Post> tableP;
@FXML private TableView<Sarcina> tableS;
@FXML private TableView<Elementfisa> tableEF;

@FXML private TableColumn<Sarcina, String> sFirstColumn;
@FXML private TableColumn<Sarcina, String> sSecondColumn;
@FXML private TableColumn<Post, String> pFirstColumn;
@FXML private TableColumn<Post, String> pSecondColumn;
@FXML private TableColumn<Elementfisa, String> fFirstColumn;
@FXML  private TableColumn<Elementfisa, String> fSecondColumn;

@FXML private ComboBox<String> ComboObject;

@FXML private Label firstLabel;
@FXML private Label secondLabel;
@FXML private Label thirdLabel;

@FXML private TextField firstTextField;
@FXML private TextField secondTextField;
@FXML private TextField thirdTextField;
@FXML private TextField filterTextField;

@FXML private RadioButton radioButtonFirst;
@FXML private RadioButton radioButtonSecond;
@FXML private Button addButton;
@FXML private Button updateButton;
@FXML private Button deleteButton;
@FXML private Button clearFieldsButton;
@FXML private Button raportButton;
@FXML private Pagination pagination ;
SarcinaService sservice;
PostService pservice;
FisaService fservice;

ObservableList<Sarcina> smodel;
ObservableList<Post> pmodel;
ObservableList<Elementfisa> fmodel;

private String currentComboBoxString;

private Boolean isSelectedFC;
private Boolean isSelectedSC;

ToggleGroup toggleRadioGroup = new ToggleGroup();

public AllController() 



private int intValidate(String e) 

    for(int i = 0; i < e.length(); i++) 
    
        if(i == 0 && e.charAt(i) == '-') 
        
            if(e.length() == 1) 
            
                showErrorMessage("Numar invalid !");
                return -1;
            
            else continue;
        
        if(Character.digit(e.charAt(i), 10) < 0) 
        
            showErrorMessage("Numar invalid !");
            return -1;
        
    
    return Integer.parseInt(e);

private void fillItemsOnTable(boolean justColumns) 


    ObservableList<Sarcina> localModel1 = null;
    ObservableList<Post> localModel2 = null;
    ObservableList<Elementfisa> localModel3 = null;

    if (currentComboBoxString.equals("Sarcina")) 
    
        tableP.setVisible(false);
        tableEF.setVisible(false);
        tableS.setVisible(true);
        tableS.getColumns().clear();
        tableS.getColumns().add(sFirstColumn);
        tableS.getColumns().add(sSecondColumn);
        localModel1 = this.smodel;
    
    else if (currentComboBoxString.equals("Post")) 
    
        tableP.setVisible(true);
        tableEF.setVisible(false);
        tableS.setVisible(false);
        tableP.getColumns().clear();
        tableP.getColumns().add(pFirstColumn);
        tableP.getColumns().add(pSecondColumn);
        localModel2 = this.pmodel;
    
    else if (currentComboBoxString.equals("Fisa")) 
    
        tableP.setVisible(false);
        tableEF.setVisible(true);
        tableS.setVisible(false);
        tableEF.getColumns().clear();
        tableEF.getColumns().add(fFirstColumn);
        tableEF.getColumns().add(fSecondColumn);
        localModel3 = this.fmodel;
    
    if (!justColumns)
    
        if (localModel1!=null)
        
            tableS.setItems(localModel1);
            tableP.setVisible(false);
            tableEF.setVisible(false);
            tableS.setVisible(true);
        
        else
            if (localModel2!=null)
            
                tableP.setItems(localModel2);
                tableP.setVisible(true);
                tableEF.setVisible(false);
                tableS.setVisible(false);
            
            else
            
                tableEF.setItems(localModel3);
                tableP.setVisible(false);
                tableEF.setVisible(true);
                tableS.setVisible(false);
            
    


@FXML public void handleRaport()

    if (isSelectedFC) 
    
        ObservableList<Sarcina> model = FXCollections.observableArrayList(fservice.filterRapoarte());
        ComboObject.setValue("Sarcina");
        this.fillItemsOnTable(true);
        tableS.setItems(model);
        wrpdf.addPdf(model);
    



public void setService(SarcinaService sservice, PostService pservice, FisaService fservice) 

    this.sservice = sservice;
    this.pservice = pservice;
    this.fservice = fservice;

    this.smodel = FXCollections.observableArrayList(sservice.getAllSarcinas());
    this.pmodel = FXCollections.observableArrayList(pservice.getAllPosts());
    this.fmodel = FXCollections.observableArrayList(fservice.getAllFisa());

    this.fillItemsOnTable(false);

@FXML private void onActionComboBox(ActionEvent event) 

    String current = ComboObject.getSelectionModel().getSelectedItem();
    if (current.compareTo(currentComboBoxString) != 0) 
    
        currentComboBoxString = current;
        if (current.equals("Sarcina")) 
        
            secondLabel.setText("Desc: ");
            radioButtonSecond.setText("By Desc");
            thirdLabel.setVisible(false);
            radioButtonFirst.setVisible(false);
            thirdTextField.setVisible(false);
        
        else if (current.equals("Post")) 
        
            secondLabel.setText("Name: ");
            thirdLabel.setText("Type: ");
            radioButtonFirst.setText("By Name");
            radioButtonSecond.setText("By Type");
            thirdLabel.setVisible(true);
            radioButtonFirst.setVisible(true);
            thirdTextField.setVisible(true);
        
        else if (current.equals("Fisa")) 
        
            secondLabel.setText("Sarcina ID: ");
            thirdLabel.setText("Post ID: ");
            radioButtonFirst.setText("By Sarcina");
            radioButtonSecond.setText("By Post");
            thirdLabel.setVisible(true);
            radioButtonFirst.setVisible(true);
            thirdTextField.setVisible(true);
        
        this.fillItemsOnTable(false);
    


@FXML private void initialize() 


    pagination1.setPageFactory(this::createPageP);
    pagination2.setPageFactory(this::createPageS);
    pagination3.setPageFactory(this::createPageEF);

    ComboObject.getItems().addAll
    (
            "Sarcina",
            "Post",
            "Fisa"
    );
    currentComboBoxString = "Sarcina";
    ComboObject.setValue("Sarcina");

    thirdLabel.setVisible(false);
    radioButtonFirst.setVisible(false);
    thirdTextField.setVisible(false);

    isSelectedFC = true;
    isSelectedSC = false;
    radioButtonFirst.setToggleGroup(toggleRadioGroup);
    radioButtonSecond.setToggleGroup(toggleRadioGroup);
    radioButtonFirst.setSelected(true);

    if (currentComboBoxString.equals("Post")) 
    
        tableP.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> 
            if (newSelection != null) 
            
                if (currentComboBoxString.equals("Post")) 
                
                    firstTextField.setText(((Post) newSelection).getId().toString());
                    secondTextField.setText(((Post) newSelection).getNume());
                    thirdTextField.setText(((Post) newSelection).getTip());
                
            
        );
    
    else
    if (currentComboBoxString.equals("Sarcina")) 
    
        tableS.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> 
            if (newSelection != null) 
            

                if (currentComboBoxString.equals("Sarcina")) 
                
                    firstTextField.setText(((Sarcina) newSelection).getId().toString());
                    secondTextField.setText(((Sarcina) newSelection).getDesc());
                
            
        );
    
    else
    if (currentComboBoxString.equals("Fisa")) 
    
        tableEF.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> 
            if (newSelection != null) 
            
                if (currentComboBoxString.equals("Fisa")) 
                
                    firstTextField.setText(((Elementfisa) newSelection).getId().toString());
                    secondTextField.setText(((Elementfisa) newSelection).getSarcina().getId().toString());
                    thirdTextField.setText(((Elementfisa) newSelection).getPost().getId().toString());
                
            
        );
    




public int itemsPerPage() 

    return 1;


public int rowsPerPage() 

    return 7;


@SuppressWarnings("unchecked")
public VBox createPageS(int pageIndex) 

    int lastIndex = 0;
    int displace = smodel.size() % rowsPerPage();
    if (displace > 0) 
        lastIndex = smodel.size() / rowsPerPage();
     else 
        lastIndex = smodel.size() / rowsPerPage() - 1;

    

    VBox box = new VBox(7);
    int page = pageIndex * itemsPerPage();

    for (int i = page; i < page + itemsPerPage(); i++) 
        TableView<Sarcina> tableS = new TableView<Sarcina>();
        sFirstColumn.setCellValueFactory(
                new PropertyValueFactory<Sarcina, String>("Id"));

        sFirstColumn.setMinWidth(20);

        sSecondColumn.setCellValueFactory(
                new PropertyValueFactory<Sarcina, String>("desc"));

        sSecondColumn.setMinWidth(160);

        tableS.getColumns().addAll(sFirstColumn, sSecondColumn);
        if (lastIndex == pageIndex) 
            tableS.setItems(FXCollections.observableArrayList(smodel.subList(pageIndex * rowsPerPage(), pageIndex * rowsPerPage() + displace)));
         else 
            tableS.setItems(FXCollections.observableArrayList(smodel.subList(pageIndex * rowsPerPage(), pageIndex * rowsPerPage() + rowsPerPage())));
        


        box.getChildren().add(tableS);
    


    pagination2.setPageCount(smodel.size()/7+1);


    return box;



@SuppressWarnings("unchecked")
public VBox createPageP(int pageIndex) 
 

     int lastIndex = 0;
     int displace = pmodel.size() % rowsPerPage();
     if (displace > 0) 
         lastIndex = pmodel.size() / rowsPerPage();
      else 
         lastIndex = pmodel.size() / rowsPerPage() - 1;

     

     VBox box = new VBox(7);
     int page = pageIndex * itemsPerPage();

     for (int i = page; i < page + itemsPerPage(); i++) 
         TableView<Post> tableP = new TableView<Post>();
         pFirstColumn.setCellValueFactory(
                 new PropertyValueFactory<Post, String>("nume"));

         pFirstColumn.setMinWidth(20);

         pSecondColumn.setCellValueFactory(
                 new PropertyValueFactory<Post, String>("tip"));

         pSecondColumn.setMinWidth(160);

         tableP.getColumns().addAll(pFirstColumn, pSecondColumn);
         if (lastIndex == pageIndex) 
         
            tableP.setItems(FXCollections.observableArrayList(pmodel.subList(pageIndex * rowsPerPage(), pageIndex * rowsPerPage() + displace)));
          else 
            tableP.setItems(FXCollections.observableArrayList(pmodel.subList(pageIndex * rowsPerPage(), pageIndex * rowsPerPage() + rowsPerPage())));
         

        pagination1.setPageCount(pmodel.size()/7+1);
         box.getChildren().add(tableP);
     
     return box;
 


public VBox createPageEF(int pageIndex) 

    int lastIndex = 0;
    int displace = fmodel.size() % rowsPerPage();
    if (displace > 0) 
        lastIndex = fmodel.size() / rowsPerPage();
     else 
        lastIndex = fmodel.size() / rowsPerPage() - 1;

    

    VBox box = new VBox(7);
    int page = pageIndex * itemsPerPage();

    for (int i = page; i < page + itemsPerPage(); i++) 
    


        fFirstColumn.setCellValueFactory(new Callback<CellDataFeatures<Elementfisa, String>, ObservableValue<String>>()
        
             public ObservableValue<String> call(CellDataFeatures<Elementfisa, String> p) 
             
                 if (p.getValue() != null && p.getValue().getSarcina() != null) 
                 
                      return new SimpleStringProperty(p.getValue().getSarcina().getDesc());
                  else 
                 
                     return new SimpleStringProperty("Empty");
                 
             
          );
        fSecondColumn.setCellValueFactory(new Callback<CellDataFeatures<Elementfisa, String>, ObservableValue<String>>() 
        
             public ObservableValue<String> call(CellDataFeatures<Elementfisa, String> p) 
             
                 if (p.getValue() != null && p.getValue().getPost() != null) 
                 
                      return new SimpleStringProperty(p.getValue().getPost().getNume());
                  else 
                 
                     return new SimpleStringProperty("Empty");
                 
             
          );

        fFirstColumn.setMinWidth(20);
        fSecondColumn.setMinWidth(160);


        if (lastIndex == pageIndex) 
            tableEF.setItems(FXCollections.observableArrayList(fmodel.subList(pageIndex * rowsPerPage(), pageIndex * rowsPerPage() + displace)));
         else if (lastIndex == pageIndex && lastIndex!=0 && pageIndex!=0) 
            tableEF.setItems(FXCollections.observableArrayList(fmodel.subList(pageIndex * rowsPerPage(), pageIndex * rowsPerPage() + rowsPerPage())));
        
        pagination3.setPageCount(fmodel.size()/7+1);
        box.getChildren().add(tableEF);
    
    return box;






private void clearFields() 

    firstTextField.setText("");
    secondTextField.setText("");
    thirdTextField.setText("");



@FXML public void handleAdd() 

    String id = firstTextField.getText();
    String first = secondTextField.getText();
    String sec = thirdTextField.getText();
    int vid = intValidate(id);
    if (vid == -1)
        return;
    if (currentComboBoxString.equals("Sarcina")) 
    
        Sarcina s = new Sarcina(Integer.parseInt(id), first);
        try 
            if (sservice.findOne(s.getId()) == null) 
            
                sservice.save(s);
                showMessage(Alert.AlertType.INFORMATION, "Salvare cu succes", "Sarcina a fost adaugat!");
                clearFields();
            
            else
                showErrorMessage("Exista deja o sarcina cu acest id !");
        catch(ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    
    else if (currentComboBoxString.equals("Post")) 
    
        Post p = new Post(Integer.parseInt(id), first, sec);
        try 
            if (pservice.findOne(p.getId()) == null) 
            
                pservice.save(p);
                showMessage(Alert.AlertType.INFORMATION, "Salvare cu succes", "Post-ul a fost adaugat!");
                clearFields();
            
            else
                showErrorMessage("Exista deja un post cu acest id !");
        catch(ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    
    else if (currentComboBoxString.equals("Fisa")) 
    
        try 
            Sarcina s = sservice.findOne(Integer.parseInt(first));
            Post p = pservice.findOne(Integer.parseInt(sec));
            if (s == null || p == null) 
            
                showErrorMessage("Id-ul sarcinii sau postului nu exista !");
                return;
            
            Elementfisa f = new Elementfisa(Integer.parseInt(id), p, s);
            if (fservice.findOne(f.getId()) == null) 
            
                fservice.save(f);
                showMessage(Alert.AlertType.INFORMATION, "Salvare cu succes", "Fisa a fost adaugat!");
                clearFields();
            
            else
                showErrorMessage("Exista deja o fisa cu acest id !");
         catch (ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    


@FXML public void handleUpdate() 

    String id = firstTextField.getText();
    String first = secondTextField.getText();
    String sec = thirdTextField.getText();
    int vid = intValidate(id);
    if (vid == -1)
        return;
    if (currentComboBoxString.equals("Sarcina")) 
    
        Sarcina s = new Sarcina(Integer.parseInt(id), first);
        try 
            Sarcina updated = sservice.update(s);
            if (updated != null) 
            
                showMessage(Alert.AlertType.INFORMATION, "Actualizare cu succes", "Sarcina a fost actualizata!");
                clearFields();
            
            else
                showErrorMessage("Eroare la actualizare !");
         catch (ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    
    else if (currentComboBoxString.equals("Post")) 
    
        Post p = new Post(Integer.parseInt(id), first, sec);
        try 
            Post updated = pservice.update(p);
            if (updated != null) 
            
                showMessage(Alert.AlertType.INFORMATION, "Actualizare cu succes", "Postul a fost actualizat!");
                clearFields();
            
            else
                showErrorMessage("Eroare la actualizare !");
         catch (ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    
    else if (currentComboBoxString.equals("Fisa")) 
    
        try 
            Sarcina s = sservice.findOne(Integer.parseInt(first));
            Post p = pservice.findOne(Integer.parseInt(sec));
            if (s == null || p == null) 
            
                showErrorMessage("Id-ul sarcinii sau postului nu exista !");
                return;
            
            Elementfisa f = new Elementfisa(Integer.parseInt(id), p, s);
            Elementfisa updated = fservice.update(f);
            if (updated != null) 
            
                showMessage(Alert.AlertType.INFORMATION, "Actualizare cu succes", "Fisa a fost actualizata!");
                clearFields();
            
            else
                showErrorMessage("Eroare la actualizare !");
        catch (ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    

@FXML public void handleDelete() 

    if (currentComboBoxString.equals("Sarcina")) 
    
        Sarcina s = (Sarcina) tableS.getSelectionModel().getSelectedItem();
        try 
        
            sservice.delete(s);
            showMessage(Alert.AlertType.INFORMATION, "Stergere cu succes", "Sarcina a fost stersa !");
            clearFields();
         catch (ValidatorException e) 
            showErrorMessage(e.getMessage());
        
    
    else if (currentComboBoxString.equals("Post")) 
    
        Post p = (Post) tableP.getSelectionModel().getSelectedItem();
        try 
        
            pservice.delete(p);
            showMessage(Alert.AlertType.INFORMATION, "Stergere cu succes", "Postul a fost sters !");
            clearFields();
         catch (ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    
    else if (currentComboBoxString.equals("Fisa")) 
    
        Elementfisa f = (Elementfisa) tableEF.getSelectionModel().getSelectedItem();
        try 
        
            fservice.delete(f);
            showMessage(Alert.AlertType.INFORMATION, "Stergere cu succes", "Fisa a fost stersa !");
            clearFields();
         catch (ValidatorException e) 
        
            showErrorMessage(e.getMessage());
        
    

@FXML public void handleClearFields() 

    clearFields();

@FXML public void handleToggleButton() 

    isSelectedFC = radioButtonFirst.isSelected();
    isSelectedSC = radioButtonSecond.isSelected();      

@FXML public void handleFilterColumn() 

    String what = filterTextField.getText();
    try 
    
        if (currentComboBoxString.equals("Sarcina")) 
        
            if (what.equals("")) 
            
                tableS.setItems(smodel);
                return;
            
            if (isSelectedFC) 
            
                showErrorMessage("N/A for Sarcina !");
                return;
            
            else if (isSelectedSC) 
            
                ObservableList<Sarcina> model = FXCollections.observableArrayList(sservice.filterSarcinaDesc(what));
                tableS.setItems(model);
            
        
        else if (currentComboBoxString.equals("Post")) 
        
            if (what.equals("")) 
            
                tableP.setItems(pmodel);
                return;
            
            if (isSelectedFC) 
            
                ObservableList<Post> model = FXCollections.observableArrayList(pservice.filterPostNume(what));
                tableP.setItems(model);
            
            else if (isSelectedSC) 
            
                ObservableList<Post> model = FXCollections.observableArrayList(pservice.filterPostTip(what));
                tableP.setItems(model);
            
        
        else if (currentComboBoxString.equals("Fisa")) 
        
            if (what.equals("")) 
            
                ComboObject.setValue("Fisa");
                tableS.setItems(smodel);
                return;
            
            int vid = intValidate(what);
            if (vid == -1)
                return;
            if (isSelectedFC) 
            
                Sarcina s = sservice.findOne(Integer.parseInt(what));
                ObservableList<Sarcina> model = FXCollections.observableArrayList(fservice.filterElementSarcina(s));
                ComboObject.setValue("Sarcina");
                this.fillItemsOnTable(true);
                tableS.setItems(model);
            
            else if (isSelectedSC) 
            
                Post p = pservice.findOne(Integer.parseInt(what));
                ObservableList<Post> model = FXCollections.observableArrayList(fservice.filterElementPost(p));
                ComboObject.setValue("Fisa");
                this.fillItemsOnTable(true);
                tableP.setItems(model);
            
        
    
    catch(ValidatorException e) 
    
        showErrorMessage(e.getMessage());
    

static void showMessage(Alert.AlertType type, String header, String text)

    Alert message=new Alert(type);
    message.setHeaderText(header);
    message.setContentText(text);
    message.showAndWait();


static void showErrorMessage(String text)

    Alert message=new Alert(Alert.AlertType.ERROR);
    message.setTitle("Mesaj eroare");
    message.setContentText(text);
    message.showAndWait();



Edit2:“JavaFX - setVisible 不“隐藏”元素”的问题不是一个解决方案,因为对他来说 setInvisible 有效,因为它使 vBox 不可见,只是不会在它的位置移动另一个。我也已经尝试过那里提出的解决方案,但没有任何效果。

我还注意到,当我更改 ComboBox 中的值时,表 Fisa (tableEF) 会自行隐藏。

【问题讨论】:

请发布您当前的代码 JavaFX - setVisible doesnt "hide" the element的可能重复 你想隐藏它并让它占用可用空间还是隐藏它并删除它当前占用的空间? 我想在同一位置的表之间进行更改。所以当我隐藏一张桌子时,另一张桌子应该出现在它的位置。 【参考方案1】:
private final BooleanProperty tableHidden;

public AllController()

    this.tableHidden = new SimpleBooleanProperty(false);
    this.tableEF.visibleProperty().bind(this.tableHiddenProperty());
    this.tableEF.managedProperty().bind(this.tableHiddenProperty().not());

    // ...


// Standard FX property setter/getter...

public void makeTableHidden()

    this.setTableHidden(true);
    // ...

当然,你可以选择没有属性,直接设置TableViewvisiblePropertymanagedProperty,不过我觉得这样更简洁(个人意见)。

编辑

这些是 JavaFX properties 的 getter/setter 的标准命名约定(参见示例 1)。

表格的可见性也是这种属性的一个例子;它的private 属性(你看不到)被称为visible,它的public 版本(你可以看到)是visibleProperty,它的getter/setter 分别是isVisiblesetVisible

这是您需要拥有的额外代码(我假设您已经知道如何自己生成一个)。

public final BooleanProperty tableHiddenProperty()

    return this.tableHidden;

public final boolean isTableHidden()

    return this.tableHiddenProperty().get;

public final void setTableHidden(final boolean value)

    this.tableHiddenProperty().set(value);

【讨论】:

tableHiddenProperty() 是一个单独的 void 函数还是我必须从某个地方导入它? @Artyomska 更新。

以上是关于在 JavaFX 中隐藏表格的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX - 分页:如何隐藏底部(控制)面板并用页面占据其区域?

JavaFX:隐藏SplitPane的滑块/分隔线

JavaFX 如何隐藏Pagination的按钮?

隐藏零值图表项目的图例javaFX

JavaFX - 隐藏列后单元格渲染中的错误

javafx中TabPane中Tab的隐藏与添加