JavaFX 8:更改主要阶段的标题

时间:2014-10-21 19:36:20

标签: java javafx javafx-8

当窗口已经显示时,如何更改主要舞台的标题?

Stage#setTitle(String)显然不是诀窍。

3 个答案:

答案 0 :(得分:6)

setTitle(...)似乎在这里工作正常:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class UpdateStageTitle extends Application {

    @Override
    public void start(Stage primaryStage) {
        TextField titleField = new TextField();
        titleField.textProperty().addListener((obs, oldText, newText) -> 
            primaryStage.setTitle(newText));
        HBox root = new HBox(5, new Label("Window title: "), titleField);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, 350, 75);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

更新以下评论。

对于一个更复杂的例子,如果你需要在控制器的初始化方法中设置它,你需要安排控制器在FXMLLoader'之前引用一个阶段。调用s load()方法。您可以通过在加载程序上调用setController或通过调用setControllerFactory来执行此操作。我通常更喜欢设置控制器工厂,因为它允许在FXML中使用fx:controller属性(设置控制器直接禁止这个)。

所以:

PrimaryStageAware.java:

package application;

import javafx.stage.Stage;

public interface PrimaryStageAware {
    public void setPrimaryStage(Stage primaryStage);
}

Main.java:

package application;

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


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("TitleSetter.fxml"));
            loader.setControllerFactory((Class<?> type) -> {
                try {
                    Object controller = type.newInstance();
                    if (controller instanceof PrimaryStageAware) {
                        ((PrimaryStageAware) controller).setPrimaryStage(primaryStage);
                    }
                    return controller ;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
            HBox root = loader.load();
            Scene scene = new Scene(root,400,400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

TitleSetter.fxml:

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

<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>

<HBox alignment="CENTER" xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="application.TitleSettingController">
    <Label text="Update title: "/>
    <TextField  fx:id="titleField" />
</HBox>

TitleSettingController.java:

package application;

import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class TitleSettingController implements PrimaryStageAware {
    private Stage stage ;

    @FXML
    private TextField titleField ;

    @Override
    public void setPrimaryStage(Stage primaryStage) {
        this.stage = primaryStage ;
    }

    public void initialize()  {
        updateTitle("Initial title");
        titleField.textProperty().addListener((obs, oldTitle, newTitle) -> updateTitle(newTitle));
    }

    private void updateTitle(String title) {
        if (stage != null) {
            stage.setTitle(title);
        } else {
            System.out.println("Warning: null stage");
        }
    }

}

(将FXML与Java文件放在同一个包中)。

答案 1 :(得分:2)

我使用FXML解决了这个问题。这将是我简单的界面ChangeTitle.fxml

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

<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:controller="ChangeTitleController" prefHeight="117.0" prefWidth="198.0" 
            xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65">
   <children>
      <TextField fx:id="input" layoutX="16.0" layoutY="32.0" onAction="#doStuff" />
   </children>
</AnchorPane>

注意fx:controller=指令告诉FXML哪个类用作控制器。另请注意TextField input有一个onAction指令,告诉FXML将doStuff()作为actionHandler运行。

现在这是启动应用程序ChangeTitle.class的类:

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

public class ChangeTitle extends Application {

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

  @Override
  public void start(Stage primaryStage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("ChangeTitle.fxml"));

    Scene scene = new Scene(root);
    primaryStage.setTitle("Change me");

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

}

最后我们有一个控制器来完成实际工作ChangeTitleController.class。我们在Stage primStage = (Stage) input.getScene().getWindow();方法中使用doStuff()来处理主要阶段。

import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class ChangeTitleController implements Initializable {

  @FXML private TextField input;

  @Override
  public void initialize(URL location, ResourceBundle resources) {

  }

  @FXML private void doStuff() {
    Stage primStage = (Stage) input.getScene().getWindow();
    primStage.setTitle(input.getText());

  }

}

答案 2 :(得分:2)

您可以将Main类设为单身,并通过Main.getInstance()

与他联系

例如:

public class Main extends Application {

    private static Main instance;
    public static Main getInstance() {
        return instance;
    }

    private Stage primaryStage;

    @Override
    public void start(Stage primaryStage) throws Exception{
        instance = this;
        this.primaryStage = primaryStage;
        Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
        this.primaryStage.setTitle("Init title");
        this.primaryStage.setScene(new Scene(root, 900, 650));
        this.primaryStage.show();
        FlatterFX.style();
    }

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

    public void updateTitle(String title) {
        primaryStage.setTitle(title);
    }
}