JavaFX - ChangeLisener在场景中发布问题并打开场景

时间:2014-08-12 17:32:33

标签: javafx javafx-2 javafx-8

我正在写信以获取有关JavaFX的一些信息。我使用SceneBuilder设计了一个应用程序,它有一个主要场景,包括一些文本字段和用于浏览文件的按钮。一旦程序运行,还有一个用于输出的文本区域。我在Controller的initialize方法中添加了更改侦听器,以便在更新输出文本区域时修改日志文件。

最初,我使用输出文本区域对其进行了测试,以显示日志文件。当我从主文件菜单中选择“查看日志”菜单项后,我能够正确地记录并在此输出文本区域中显示日志。我遇到了一个似乎并不是很干净的问题,当我显示它想要记录该显示的日志时。我想不出一个干净的工作,并决定我宁愿在自己的辅助弹出场景中打开日志。

我的一个问题是,如果我在Controller的initialize方法内的输出文本区域放置一个更改侦听器,当我尝试“查看日志”时,它会抛出一个空指针异常,并指向更改侦听器所在的行被添加。但请注意,虽然它会尝试打开日志窗口时抛出此异常,但更改侦听器和输出文本区域仍然可以正常工作。

如果我删除了更改侦听器,则窗口打开正常 - 但是在logFileOutputTextArea中没有更新任何内容。

控制器文件:

public class AppController implements Initializable
{
    @FXML
    private TextArea logFileOutputTextArea;


    @Override
    public void initialize(URL url, ResourceBundle rb)
    {


        verifierOutputTextArea.textProperty().addListener(new ChangeListener<String>()
        {
            @Override
            public void changed(ObservableValue<? extends String> ov, String t, String t1)
            {
                // IF we have a valid file
                if (verifierOutputTextArea.textProperty().getValue().equals("Valid"))
                {
                  openOutputFolderButton.visibleProperty().setValue(!openOutputFolderButton.visibleProperty()
                        .getValue());
                }

            }
        });


        verifierOutputTextArea.textProperty().addListener(new ChangeListener<String>()
        {
            @Override
            public void changed(ObservableValue<? extends String> ov, String t, String t1)
            {
                appendLog(verifierOutputTextArea.textProperty().getValue());    // append the output to the log

            }
        });

        // Check for a preset input file location
        checkDefaultInputDirectory();

    } // END INITIALIZE


    @FXML
    private void openLog()
    {

        try
        {
            Stage dialogStage = new Stage();

            Parent root = FXMLLoader.load(getClass().getResource("fxml/logwindow.fxml"));

            Scene scene = new Scene(root);

            dialogStage.setScene(scene);
            dialogStage.setTitle("Log");
            dialogStage.show();
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }

        Path logFilePath = Paths.get(StaticTools.LOG_FILE_LOCATION);



        // IF the file doesn't exist
        if (!Files.exists(logFilePath))
        {
            this.logFileOutputTextArea.textProperty().setValue("Log has not been created yet!");
        }
        else
        {
            try
            {
                byte[] fileByteArray = Files.readAllBytes(logFilePath);

                this.logFileOutputTextArea.setText(StaticTools.cryptTool(new String(fileByteArray), Cipher.DECRYPT_MODE));


            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

    } // END OPENLOG

} // END CONTROLLER

日志窗口.fxml:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" minHeight="-Infinity" minWidth="-Infinity" prefHeight="304.0"
        prefWidth="478.0" xmlns="http://javafx.com/javafx/8"
      fx:controller="application.javafx.AppController">
    <children>
        <GridPane layoutX="14.0" layoutY="22.0" prefHeight="269.0" prefWidth="446.0">
            <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
            </columnConstraints>
            <rowConstraints>
                <RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="20.0" vgrow="SOMETIMES"/>
                <RowConstraints vgrow="SOMETIMES"/>
            </rowConstraints>
            <children>
                <Label text="Log File">
                    <padding>
                        <Insets bottom="5.0"/>
                    </padding>
                </Label>
                <TextArea fx:id="logFileOutputTextArea" editable="false" prefHeight="200.0" prefWidth="200.0"
                          wrapText="true" GridPane.rowIndex="1"/>
            </children>
        </GridPane>
    </children>
</AnchorPane>

每个fxml文件是否需要单独的控制器?为什么将初始化语句和更改侦听器放入initialize方法会导致问题?为什么在主场景中的输出文本区域被修改后,通过清除文本或设置文本,是否每次都向另一个窗口添加alt-tabbing抛出java.lang.IllegalArgumentException: argument type mismatch例外?

感谢您的时间!

1 个答案:

答案 0 :(得分:1)

您似乎尝试将一个控制器类用于两个不同的fxml文件:LogWindow.fxml和一些其他fxml文件,它通过菜单项上的事件处理程序调用{​​{1}}。

如果是这种情况,您将最终得到两个控制器实例:一个由showLog()创建,用于加载“main”fxml,另一个由FXMLLoader创建。加载LogWindow.fxml。正在由“main”fxml创建的实例上调用FXMLLoader方法,因此它将填充“main”fxml中定义的文本区域(如果有的话,否则您可能会得到空指针异常)。这当然不是LogWindow.fxml中的文本区域,因此文本不会显示在那里。

您可能想为LogWindow.fxml创建一个单独的控制器类,并在其showLog()方法中填充文本区域。