2015-04-06 3 views
2

Как создать новую вкладку с помощью JavaFX/FXML? Я создал tabpane в своем FXML, но я хочу нажать кнопку, которая приведет к появлению новой вкладки.Как динамически создавать вкладки в JavaFX с помощью FXML?

Вот мой FXML:

<?import javafx.scene.effect.*?> 
<?import javafx.scene.text.*?> 
<?import javafx.scene.layout.*?> 
<?import java.lang.*?> 
<?import javafx.scene.control.*?> 


<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller"> 
<top> 
     <MenuBar BorderPane.alignment="CENTER"> 
     <menus> 
      <Menu mnemonicParsing="false" text="File"> 
      <items> 
      <MenuItem mnemonicParsing="false" text="New..." onAction="#btnNew"/> 
      <MenuItem mnemonicParsing="false" text="Save..." /> 
      <MenuItem mnemonicParsing="false" text="Save As..." /> 
      <MenuItem mnemonicParsing="false" text="Open..." /> 
      <MenuItem mnemonicParsing="false" text="Close" /> 

     </items> 
     </Menu> 
     <Menu mnemonicParsing="false" text="Help"> 
     <items> 
      <MenuItem mnemonicParsing="false" text="About Blank" onAction="#btnAbout"/> 
     </items> 
     </Menu> 
    </menus> 
    </MenuBar> 
</top> 
<center> 
    <TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER" fx:id="tabPane"> 
    <tabs> 
     <Tab text="Untitled Tab 1"> 
      <content> 
       <AnchorPane> 
       <children> 
        <TextFlow maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" /> 
       </children> 
       </AnchorPane> 
      </content> 
     </Tab> 
    </tabs> 
    </TabPane> 

Вот мой код, который я пытаюсь сейчас в моем контроллере:

package sample; 

import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.*; 
import java.net.URL; 
import java.util.ResourceBundle; 


public class Controller implements Initializable { 
@FXML 
private Button btnAbout; 
@FXML 
private Button btnNew; 
@FXML 
private TabPane tabPane; 

//tab array 
int intTabs = 0; 
Tab[] openTabs; 

@FXML 
private void btnNew(ActionEvent event){ 
    try{ 
     intTabs++; 
     openTabs = new Tab[intTabs]; 
     //System.out.println(openTabs.length); 
     tabAdder(intTabs, openTabs); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 

} 

private TabPane tabAdder(int tabNum, Tab[] tabs){ 
    //System.out.println(tabNum); 
    tabPane.getTabs().add(tabs[tabNum]); 
    return tabPane; 
} 

@FXML 
private void btnAbout(ActionEvent event){ 
    Alert alert = new Alert(Alert.AlertType.INFORMATION); 
    alert.setTitle("Blank: Information"); 
    alert.setHeaderText(null); 
    alert.setContentText("This is Blank, a simple and soon to be elegant cross platform text editor."); 
    alert.showAndWait(); 
} 


public void initialize(URL url, ResourceBundle rb){ 
    //tabPane.getTabs().add 

} 

}

I «Не совсем уверен, в чем проблема: я шел глупо h куча ресурсов, и я знаю, как добавить регулярную вкладку.

Я знаю, что если я сделать закладку, как это:

Tab fapTab = new Tab(); 

Я могу добавить это следующим образом:

tabPane.getTabs().add(fapTab); 

Но я хочу, чтобы создавать их динамически, потому что я не знаю, как многие вкладки, которые мой пользователь захочет. Поэтому мой подход заключался в создании массива вкладок, который увеличивается, когда пользователь нажимает «новый», а затем имеет функцию, которая добавляет эту новую вкладку в gui. Он работает не так, и я пробовал несколько разных подходов, адаптируя код людей к своему.

Так что мой вопрос: кто-нибудь знает, что я делаю неправильно?

Вот некоторые из этих источников: javafx open a new fxml file in new tab dynamically http://javafx-albert-af77.blogspot.com/2012/06/tabs-fxml.html https://www.youtube.com/watch?v=NhoiSMk3f5U

+1

Что случилось с другим решением вы предложили, то есть 'Tab newTab = новая вкладка()' 'tabPane.getTabs() добавить (newTab);'.? Просто запустите этот код в обработчике событий. Вам не нужно сохранять дополнительный список (или массив) вкладок, вы всегда можете получить текущий список с помощью 'tabPane.getTabs()'. –

+0

Потому что он создает одну вкладку и только добавит одну вкладку для каждого создаваемого объекта табуляции. Мне нужно, чтобы он был динамичным, поэтому, если у моего пользователя есть безумные количества RAM и он хочет открыть 200 вкладок, они могут сделать это без меня, чтобы их жестко закодировать. – user3505901

+1

Что такое пользовательский интерфейс для добавления большого количества вкладок?Они вводят номер, который они хотят добавить в текстовое поле, а затем нажмите кнопку? Я не уверен, что понимаю, чего вы пытаетесь достичь. –

ответ

2

Вы уже дали ответ: просто создать новую вкладку и добавить его в закладки панели:

Tab tab = new Tab(); 
tabPane.getTabs().add(tab); 

Полный пример :

AddTabsExample.fxml:

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

<?import javafx.scene.layout.BorderPane?> 
<?import javafx.scene.control.TabPane?> 
<?import javafx.scene.layout.HBox?> 
<?import javafx.scene.control.Button?> 

<BorderPane xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="AddTabsController"> 
    <center> 
     <TabPane fx:id="tabPane" /> 
    </center> 
    <bottom> 
     <HBox alignment="center"> 
      <Button text="Add tab" onAction="#addTab" /> 
      <Button text="List tabs" onAction="#listTabs" /> 
     </HBox> 
    </bottom> 
</BorderPane> 

AddTabsController.java:

import javafx.fxml.FXML; 
import javafx.scene.control.Tab; 
import javafx.scene.control.TabPane; 

public class AddTabsController { 

    @FXML 
    private TabPane tabPane ; 

    public void initialize() { 
     tabPane.getTabs().add(new Tab("Tab 1")); 
    } 

    @FXML 
    private void addTab() { 
     int numTabs = tabPane.getTabs().size(); 
     Tab tab = new Tab("Tab "+(numTabs+1)); 
     tabPane.getTabs().add(tab); 
    } 

    @FXML 
    private void listTabs() { 
     tabPane.getTabs().forEach(tab -> System.out.println(tab.getText())); 
     System.out.println(); 
    } 
} 

Применение (AddTabsExample.java):

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

public class AddTabsExample extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     BorderPane root = FXMLLoader.load(getClass().getResource("AddTabsExample.fxml")); 
     primaryStage.setScene(new Scene(root, 800, 600)); 
     primaryStage.show(); 
    } 

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

Да! Отлично спасибо! Я не уверен, почему то, что я сделал, сначала не работало, так как я уверен, что пробовал что-то очень похожее на это. Но я не уверен, почему это не сработало. В любом случае, спасибо! Я бы отметил это как решение, но я не думаю, что у меня достаточно репутации для этого. – user3505901

0

Используйте это вместо этого. Вы должны @Override инициализировать метод:

@Override 
    public void initialize(URL location, ResourceBundle resources) { 
     tabPane.getTabs().add(new Tab("Tab 1")); 
     } 

    //Not this: 
    public void initialize() { 
      tabPane.getTabs().add(new Tab("Tab 1")); 
     }