JavaFX java.lang.IllegalArgumentException:无法将javafx.scene.control.Label字段sample.Controller.location设置为java.net.URL

时间:2019-05-21 22:22:48

标签: java javafx fxml

我的JavaFX应用程序具有一个标签,其fx:id为location。它在FXML文件中定义。当我尝试运行该应用程序时,出现以下错误:

  

java.lang.IllegalArgumentException:无法将javafx.scene.control.Label字段sample.Controller.location设置为java.net.URL

我正在将JDK 12与JavaFX 11.0.2一起使用。

我在SO上看到了其他答案,说这是由location标签的类型冲突引起的。例如,它可以在FXML文件中声明为Label,但在Java代码中则是别的(在本例中为java.net.URL)。但是,正如您在下面的代码中看到的那样,我在任何地方都没有使用URL类。

将fx:id更改为其他名称(例如loc)会使错误消失,因此location必须是一个“魔术”名称。

是什么原因造成的?

sample.fxml

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Label fx:id="location" layoutX="133.0" layoutY="146.0" text="Output" />
   </children>
</Pane>

Main.java

package sample;

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

public class Main extends Application
{

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 400, 275));
        primaryStage.show();
    }


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

Controller.java

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class Controller
{
    @FXML
    Label location;

}

module-info.java

module MyTest
{
    requires javafx.controls;
    requires javafx.fxml;
    opens sample;
}

1 个答案:

答案 0 :(得分:5)

通过检查FXMLLoader相对容易找到:

int main(int argc, char *argv[]) {
std::vector<GLfloat> ballVerts;
    GLuint ballVbo;

for(int i = 0; i <= 40; i++)
{
    double lat0 = M_PI * (-0.5 + (double) (i - 1) / 40);
    double z0  = sin(lat0);
    double zr0 =  cos(lat0);

    double lat1 = M_PI * (-0.5 + (double) i / 40);
    double z1 = sin(lat1);
    double zr1 = cos(lat1);

    for(int j = 0; j <= 40; j++)
    {
        double lng = 2 * M_PI * (double) (j - 1) / 40;
        double x = cos(lng);
        double y = sin(lng);

        ballVerts.push_back(x * zr0); //X
        ballVerts.push_back(y * zr0); //Y
        ballVerts.push_back(z0);      //Z

        ballVerts.push_back(0.0f);
        ballVerts.push_back(1.0f);
        ballVerts.push_back(0.0f);
        ballVerts.push_back(1.0f); //R,G,B,A

        ballVerts.push_back(x * zr1); //X
        ballVerts.push_back(y * zr1); //Y
        ballVerts.push_back(z1);      //Z

        ballVerts.push_back(0.0f);
        ballVerts.push_back(1.0f);
        ballVerts.push_back(0.0f);
        ballVerts.push_back(1.0f); //R,G,B,A
    }
}

glGenBuffers(1, &ballVbo);
glBindBuffer(GL_VERTEX_ARRAY, ballVbo);

GLuint sphereSize = 3200*7*4; //3200 vertixes * 7 floats
glBufferData(GL_VERTEX_ARRAY,sphereSize, &ballVerts[0], GL_STATIC_DRAW);



 //Draw a ball

glBindBuffer(GL_VERTEX_ARRAY, ballVbo);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 7*4, 0);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 7*4, (void*)(3*4));

glDrawArrays(GL_TRIANGLE_STRIP, 0, 3200);

glBindBuffer(GL_ARRAY_BUFFER, 0);
}

基本上,这意味着/** * A key for location URL in namespace map. * @see #getNamespace() * @since JavaFX 2.2 */ public static final String LOCATION_KEY = "location"; /** * A key for ResourceBundle in namespace map. * @see #getNamespace() * @since JavaFX 2.2 */ public static final String RESOURCES_KEY = "resources"; private URL location; private ResourceBundle resources; private <T> T loadImpl(InputStream inputStream, Class<?> callerClass) throws IOException { ... namespace.put(LOCATION_KEY, location); namespace.put(RESOURCES_KEY, resources); ... } (如locationresourcescontroller)是保留的关键字

这些关键字被添加到Controller(可观察的地图:namespace)中,ObservableMap<String, Object> namespace是FXML文件的URL,类似于:

location

稍后,将评估FXML文件的不同namespace.put("location", "file:/path/to/your/FXML/file"); 标签并将其添加到相同的名称空间:

fx:id

在这种情况下,如果您的private void processValue() throws LoadException { ... if (fx_id != null) { namespace.put(fx_id, value); injectFields(fx_id, value); } ... } fx:id,则您将执行以下操作:

"location"

很明显,由于您使用的是相同的密钥,因此您要用一个新对象(在本例中为Label)覆盖以前的URL。

稍后,当FXMLLoader尝试注入此位置时:

namespace.put("location", Label@12dafafa);

发生异常,因为可以将地图从键injectFields(LOCATION_KEY, location); 获得的Label设置为URL字段:

"location"

虽然没有记录,但这意味着您不能将Can not set javafx.scene.control.Label field org.openjfx.FXMLController.location to java.net.URL 标签("location""resources"也不能用作"controller"标签的值)将与这些关键字发生冲突。