java - 在 javafx 应用程序中单击对话框按钮时内存增加

标签 java memory-management memory-leaks javafx-2

我附上了下面的 javafx 示例应用程序,其中有一个用于对话框的对话框类。当单击对话框中存在的按钮时 - 它的内存增加太多。仅当对话框显示时 - 在 taskmanager 中支持它需要 57kb,然后当我们单击按钮并处理对话框时 - taskmanager 显示其内存开始增加 - 最后它崩溃,获取转储内存异常。

示例中有以下类 Dialog.java :它显示带有 ok - 取消按钮的对话框 MessageDialog.fxml :此 fxml 创建对话框 MessageDialogController 是 MessageDialog.fxml 的关联文件 JavaFXSample.java 是运行此示例的主要类。

Dialog.java

package javafxsample;

import java.io.IOException;
import java.io.InputStream;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

/**
 *
 * @author Admin
 */
public class Dialog {

    public static void ShowinfoDialog(String title, String Message, Stage parentStage, double w, double h) {
        if (title == null || title.trim().isEmpty()) {
            title = "Info";
        }
        showMessageDialog(title, Message, parentStage, "sidetheme.png", w, h);
    }

    public static void showMessageDialog(String title, String Message, Stage parentStage, String image, double w, double h) {
        Stage stage = new Stage();
        MessageDialogController messageDialogController = (MessageDialogController) replaceScene("/javafxsample/MessageDialog.fxml", stage);
        messageDialogController.init(stage, Message, image);
        if (parentStage != null) {
            stage.initOwner(parentStage);
        }
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.initStyle(StageStyle.UTILITY);
        stage.setResizable(false);
        if (title != null && !title.trim().isEmpty()) {
            stage.setTitle(title);
        }
        stage.setWidth(w);
        stage.setHeight(h);
//        Utility.setCentreLocation(stage, parentStage);
        InputStream inputStream = null;
        try {
            inputStream = Dialog.class.getResourceAsStream(image);
            stage.getIcons().add(new Image(inputStream));
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                }
            }
        }
        stage.showAndWait();
    }

    public static Initializable replaceScene(String fXml, Stage mystage) {
        InputStream in = null;
        try {
            FXMLLoader loader = new FXMLLoader();
            in = Dialog.class.getResourceAsStream(fXml);
            loader.setLocation(Dialog.class.getResource(fXml));
            loader.setBuilderFactory(new JavaFXBuilderFactory());
            AnchorPane page;
            try {
                page = (AnchorPane) loader.load(in);
            } finally {
                in.close();
            }
            Scene scene = new Scene(page);
            mystage.setScene(scene);
            return loader.getController();
        } catch (Exception ex) {
            System.out.println("Exception in replaceScene. " + fXml + ".Error:" + ex.getMessage());
            return null;
        }
    }
}

JavaFXSample.java

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package javafxsample;

    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;

    /**
     *
     * @author JavaUser1
     */
    public class JavaFXSample extends Application {

        @Override
        public void start(final Stage primaryStage) {
            Button btn = new Button();
            btn.setText("   Click on ME  ");
            btn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    Dialog.ShowinfoDialog("Sample", "Clicked on button", primaryStage, 400.0, 150.0);
                }
            });

            StackPane root = new StackPane();
            root.getChildren().add(btn);

            Scene scene = new Scene(root, 300, 250);

            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        }

        /**
         * The main() method is ignored in correctly deployed JavaFX application.
         * main() serves only as fallback in case the application can not be
         * launched through deployment artifacts, e.g., in IDEs with limited FX
         * support. NetBeans ignores main().
         *
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    }

MessageDialog.fxml

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

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

<AnchorPane id="AnchorPane" prefHeight="138.0" prefWidth="306.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxsample.MessageDialogController">
  <children>
    <TitledPane animated="false" collapsible="false" prefHeight="138.0" prefWidth="347.0" text="" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="-40.0">
      <content>
        <AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
          <children>
            <GridPane prefHeight="112.0" prefWidth="282.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
              <children>
                <Label fx:id="lblicon" text="" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0">
                  <GridPane.margin>
                    <Insets top="20.0" fx:id="x1" />
                  </GridPane.margin>
                </Label>
                <Label fx:id="lblMessage" text="" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="0">
                  <font>
                    <Font size="14.0" />
                  </font>
                  <GridPane.margin>
                    <Insets left="2.0" top="20.0" />
                  </GridPane.margin>
                </Label>
                <Separator prefWidth="200.0" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="1" />
                <Separator prefWidth="200.0" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="1">
                  <GridPane.margin>
                    <Insets top="4.0" />
                  </GridPane.margin>
                </Separator>
                <HBox id="HBox" fx:id="hBox" alignment="CENTER" spacing="5.0" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
              </children>
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="82.0" minWidth="82.0" prefWidth="82.0" />
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="-1.0" minWidth="10.0" prefWidth="220.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints maxHeight="-1.0" minHeight="10.0" prefHeight="68.0" vgrow="SOMETIMES" />
                <RowConstraints maxHeight="15.0" minHeight="15.0" prefHeight="15.0" vgrow="SOMETIMES" />
                <RowConstraints maxHeight="29.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" />
              </rowConstraints>
            </GridPane>
          </children>
        </AnchorPane>
      </content>
    </TitledPane>
  </children>
</AnchorPane>

MessageDialogController.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javafxsample;

import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

/**
 * FXML Controller class
 *
 * @author Admin
 */
public class MessageDialogController implements Initializable {

    @FXML
    private Label lblMessage;
    @FXML
    private Label lblicon;
    @FXML
    private HBox hBox;
    private Stage myStage;
    private String clicked = "cancel";

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }

    public void btnOkEvent(ActionEvent event) {
        clicked = "yes";
        myStage.close();
    }

    public void btnCancelEvent(ActionEvent event) {
        clicked = "no";
        myStage.close();
    }

    public void init(Stage stage, String Message, String image) {
        Button btnOk = new Button("OK");
        btnOk.setPrefSize(70.0, 23.0);
        btnOk.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                btnOkEvent(t);
            }
        });
        hBox.getChildren().add(btnOk);
        lblMessage.setText(Message);
        if (image != null && !image.trim().isEmpty()) {
            Image imageRunBackupPlan = new Image(getClass().getResourceAsStream(image));
            lblicon.setGraphic(new ImageView(imageRunBackupPlan));
        }
        this.myStage = stage;
    }

    public void init(Stage stage, String Message, String btnOkText, String btnCancelText, String image) {
        clicked = "cancel";
        Button btnOk = new Button(btnOkText);
        btnOk.setPrefHeight(23);
        Button btnCancel = new Button(btnCancelText);
        btnCancel.setPrefHeight(23);
        hBox.getChildren().addAll(btnOk, btnCancel);
        btnOk.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                btnOkEvent(t);
            }
        });
        btnCancel.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                btnCancelEvent(t);
            }
        });
        lblMessage.setText(Message);
        if (image != null && !image.trim().isEmpty()) {
            InputStream inputStream = null;
            Image imageRunBackupPlan = new Image(getClass().getResourceAsStream(image));
            lblicon.setGraphic(new ImageView(imageRunBackupPlan));
        }
        this.myStage = stage;
    }

    public String clickedOn() {
        return clicked;
    }
}

最佳答案

如果您的 Dialog.java 的目的只是创建一个对话框,则删除它并使用它。 它只是一个您必须导入到项目中的 jar 文件

http://code.makery.ch/blog/javafx-2-dialogs

关于java - 在 javafx 应用程序中单击对话框按钮时内存增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15004106/

相关文章:

java - javax.sql 和 java.sql 之间的区别?

iOS 废弃内存 VM : Image IO

c++ - Valgrind 将此检测为可能的内存泄漏

java - Java 中的隐式转换

java - 将通用类参数限制为实现 Map 的类

c++ - std::unique_ptr 是为数组分配内存的错误工具吗?

c - 性能:内存集

c++ - _CrtSetBreakAlloc 使用内存内容而不是分配号

java - 加载 Podcast 音频导致 Java 中出现 OutOfMemoryError

java - 非 BMP 平面字符的 Unicode 转义序列