JavaFX 2.0 FXML resource loading error - resources

#Override public void start(Stage primaryStage) {
try {
stage = primaryStage;
gotoLogin();
primaryStage.show();
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
enter code here
public User getLoggedUser() {
return loggedUser;
}
public boolean userLogging(String userId, String password){
if (Authenticator.validate(userId, password)) {
loggedUser = User.of(userId);
gotoProfile();
return true;
} else {
return false;
}
}
public void userLogout(){
loggedUser = null;
gotoLogin();
}
private void gotoProfile() {
try {
replaceSceneContent("../skinFolder/fxml/profile.fxml");
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void gotoLogin() {
try {
replaceSceneContent("../skinFolder/fxml/login.fxml");
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
private Parent replaceSceneContent(String fxml) throws Exception {
Parent page = (Parent) FXMLLoader.load(App.class.getResource(fxml), null, new JavaFXBuilderFactory());
Scene scene = stage.getScene();
if (scene == null) {
scene = new Scene(page, 700, 450);
scene.getStylesheets().add(App.class.getResource("../skinFolder/css/defaultSkin.css").toExternalForm());
stage.setScene(scene);
} else {
stage.getScene().setRoot(page);
}
stage.sizeToScene();
return page;
}}
So i am trying to use the sample of the FXML Login example, only i give other way for the fxml. And in the fxml files i gave the way to the controller.
The log shows those errors:
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javafx.fxml.FXMLLoader.loadType(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(Unknown Source)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(Unknown Source)
at javafx.fxml.FXMLLoader$Element.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at Main.App.replaceSceneContent(App.java:115)
at Main.App.gotoProfile(App.java:100)
at Main.App.userLogging(App.java:86)
at skinFolder.controllers.LoginController.processLogin(LoginController.java:28)
Login Controller Class
public class LoginController {
#FXML private TextField userId;
#FXML private PasswordField password;
#FXML private Label errorMessage;
#FXML protected void processLogin() {
if(!App.getInstance().userLogging(userId.getText(), password.getText())){
errorMessage.setText("Username/password combination is invalid.");
}
}
}
And the line 28 is:
if(!App.getInstance().userLogging(userId.getText(), password.getText())){
I mention that the fxml files are in another folder the Main file folder. I don't get why i get this error when i am using the example gave by the Oracle, but with another folder structure!
My app folder structure:
Main
Model
Security
skinFolder - css
skinFolder - fxml
skinFolder - controllers
Here is the profile.fxml code:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="Profile" styleClass="profile" xmlns:fx="http://javafx.com/fxml" fx:controller="skinFolder.controllers.ProfileController">
<children>
<Button maxHeight="2.0" text="Update" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="168.0" fx:id="update" onAction="#processUpdate"/>
<Label layoutX="56.0" layoutY="77.0" text="Please review your profile data." fx:id="message" />
<Label layoutX="56.0" layoutY="123.0" text="User:" />
<Label layoutX="56.0" layoutY="224.0" text="Phone:" />
<Label layoutX="56.0" layoutY="173.0" text="Email:" />
<TextField editable="false" layoutX="149.0" layoutY="120.0" maxWidth="2.0" minHeight="30.0" minWidth="215.0" prefHeight="30.0" prefWidth="215.0" fx:id="user" />
<TextField editable="true" layoutX="149.0" layoutY="171" maxWidth="2.0" minHeight="30.0" minWidth="215.0" prefHeight="30.0" prefWidth="215.0" fx:id="email" />
<TextField layoutX="149.0" layoutY="224" maxWidth="2.0" minHeight="30.0" minWidth="215.0" prefHeight="30.0" prefWidth="215.0" fx:id="phone" />
<CheckBox layoutX="402" layoutY="120.0" text="Subscribed to NewsLetter" fx:id="subscribed" />
<Separator layoutX="380" layoutY="110" prefHeight="155" orientation="vertical"/>
<Hyperlink layoutY="24.0" text="logout" AnchorPane.rightAnchor="52.0" fx:id="logout" onAction="#processLogout"/>
<Button disable="true" maxHeight="2" maxWidth="2.0" text="Continue" defaultButton="true" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="52.0" fx:id="Button" onAction="#processLogout"/>
<Label layoutX="150.0" layoutY="401.0" opacity="0.0" text="Profile successfully updated!" fx:id="success" />
<Label layoutX="56.0" layoutY="284.0" text="Address:" />
<TextArea maxHeight="2.0" maxWidth="2.0" minHeight="85.0" minWidth="448.0" prefHeight="85.0" prefWidth="448.0" AnchorPane.bottomAnchor="69.0" AnchorPane.leftAnchor="149.0" AnchorPane.rightAnchor="52.0" AnchorPane.topAnchor="289.0" fx:id="address" />
</children>
<styleClass>
<String fx:value="profile" />
</styleClass>
<properties>
<elementLockSel>
<Boolean fx:value="true" />
</elementLockSel>
</properties>
</AnchorPane>
Anyone any ideas?

I think it is related to your previous question (JavaFX 2.0 load fxml files from subfolder fails). See this answer. Same here for processUpdate action.

There is a problem in your profile.fxml file. You didn't include error description in stacktrace but most probably you have wrong or misspelled attribute tag in there.
Please, add profile.fxml and full stack trace to the post if you need more help.

Related

Why my custom javax.faces.context.ExceptionHandler doesn't handle javax.validation.ConstraintViolationException

My custom exception handler is not being invoked by the container to intercept (checked or unchecked) exceptions (I verified it through the debugger). I have this Entity bean class with #Email annotation for the email field, and when the user types in an invalid email through the JSF page, an error message is being displayed, however, the error message is not the one I set through the custom exception handler class, rather it is the one I have set as the default message for the #Email annotation. The error message generated by the custom exception handler has a prefix string "Exception caught by the custom Exception handler: ". I surmise that an invalid email should throw a ConstraintViolationException, which would be an ideal case for the exception handler to catch.
The JSF page allows the user information to be updated, so when I update the user's email with an invalid one and click the "Update" CommandButton, the registered action method is not being invoked (I verified it through the debugger). Furthermore, what I don't seem to figure out, is that when the "invalid email" error message is displayed on the JSF page, the "Add User" command Button gets disabled, so I can not navigate to the "Add User" JSF page. Any idea, why the exception handler and the page navigation (Add User) are not working in case of an error?
public class CustomExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
private final static Logger logger = Logger.getLogger(CustomExceptionHandler.class.getName());
public CustomExceptionHandler(ExceptionHandler w) {
wrapped = w;
}
#Override
public ExceptionHandler getWrapped() {
return wrapped;
}
#Override
public void handle() throws FacesException {
Iterator iterator = getUnhandledExceptionQueuedEvents().iterator();
while (iterator.hasNext()) {
ExceptionQueuedEvent event = (ExceptionQueuedEvent) iterator.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)event.getSource();
Throwable throwable = context.getException();
FacesContext fc = FacesContext.getCurrentInstance();
try {
Flash flash = fc.getExternalContext().getFlash();
// Put the exception in the flash scope to be displayed in the error
// page if necessary ...
String errorMessage = "Exception caught by the custom Exception handler: "+throwable.getMessage();
logger.severe(errorMessage);
flash.put("errorDetails", errorMessage);
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
//navigationHandler.handleNavigation(fc, null, "/loginmanagement");
navigationHandler.handleNavigation(fc, null, "error?faces-redirect=true");
fc.renderResponse();
} finally {
iterator.remove();
}
}
// Let the parent handle the rest
getWrapped().handle();
}
}
The factory class:
public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
#Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler result = new CustomExceptionHandler(parent.getExceptionHandler());
return result;
}
}
The faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.3"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd">
<application>
<resource-bundle>
<base-name>webmessages</base-name>
<var>bundle</var>
</resource-bundle>
<locale-config>
<default-locale>en</default-locale>
<!-- <supported-locale>es</supported-locale> -->
</locale-config>
</application>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/loginmanagement.xhtml</location>
</error-page>
<factory>
<exception-handler-factory>
org.me.mavenlistservicedb.applicationexception.CustomExceptionHandlerFactory
</exception-handler-factory>
</factory>
</faces-config>
Here is the relevant excerpt of the JSF page
<h:column>
<f:facet name="header">#{bundle.loginmanagementemail}</f:facet>
<h:inputText value = "#{l.email}"
size ="30" rendered = "#{l.canUpdate}" />
<h:outputText value = "#{l.email}"
rendered = "#{not l.canUpdate}" />
</h:column>
<f:facet name="footer">
<h:panelGroup style="display: block; border-color: aquamarine;text-align: center;">
<h:commandButton id="update"
value="Save updates"
action="#{loginManagment.saveUpdate}" />
<h:commandButton id="add"
value="Add User"
action="adduser" />
</h:panelGroup>
</f:facet>
I use Netbeans on Windows 10 with Glassfish 5.1.
Thanks

javax.validation.ConstraintViolationException

I am using JSF+JPA iam not fix this error:
javax.validation.ConstraintViolationException: Bean Validation
constraint(s) violated while executing Automatic Bean Validation on
callback event:'prePersist'. Please refer to embedded
ConstraintViolations for details.
#ManagedBean(name = "clientCon")
public class ClientController {
#PostConstruct
public void init() {
System.out.println("Salam");
clients = new Clients();
}
private EntityManagerFactory emf = null;
public ClientController() {
emf = Persistence.createEntityManagerFactory("ClinicProjectPU");
}
private List<Clients> clientList;
private Clients clients;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public Clients getClients() {
return clients;
}
public void setClients(Clients clients) {
this.clients = clients;
}
public List<Clients> getClientList() {
this.clientList = getEntityManager().createNamedQuery("Clients.findAll").getResultList();
return clientList;
}
public void createClient() {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
em.persist(clients); // the only interesting method
em.flush();
em.getTransaction().commit();
System.out.println("created");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (em != null) {
em.close();
}
}
}
}
<h:form>
<fieldset>
<h:panelGrid columns="2">
<h:outputText value="Ad" style="color: #0099cc"/>
<h:inputText class="form-client" value="#{clientCon.clients.name}" />
<h:outputText value="Soyad" style="color: #0099cc" />
<h:inputText class="form-client" value="#{clientCon.clients.surname}" />
<h:outputText value="Telefon" style="color: #0099cc" />
<h:inputText class="form-client" value="#{clientCon.clients.phone}" />
</h:panelGrid>
<div class="btns">
<center><h:commandButton action="#{clientCon.createClient()}" value="Saxla" style="width: 60%;margin-top: 5%;border-radius: 5px;color: #ffffff;background-color: #0099cc" /></center>
</div>
</fieldset>
</h:form>
javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.
at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:90)
at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.prePersist(BeanValidationListener.java:62)
at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:748)
at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:691)
at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:229)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4310)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:4287)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:518)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4229)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
at controller.ClientController.createClient(ClientController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.el.ELUtil.invokeMethod(ELUtil.java:326)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:536)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
at com.sun.el.parser.AstValue.invoke(AstValue.java:269)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:724)
To know what caused the constraint violation, you can use the following validator and logger.
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Clients>> constraintViolations = validator.validate(clients);
if (constraintViolations.size() > 0 ) {
System.out.println("Constraint Violations occurred..");
for (ConstraintViolation<Clients> contraints : constraintViolations) {
System.out.println(contraints.getRootBeanClass().getSimpleName()+
"." + contraints.getPropertyPath() + " " + contraints.getMessage());
}
}
Put the logger before persisting the entity. So between
em.getTransaction().begin();
//here goes the validator
em.persist(clients);
Compile and run. The console will show you, just before the exception stack trace, which element(s) caused the violation(s).
You can but should catch your try block containing any persistence method with ConstraintViolationException (to avoid further problems and/or inform the user an error occurred and its reason). However, in a well built system there shouldn't be any constraint violation exception during persistence. In JSF, and other MVC framework, the validation step must be totally or partially done at the client side before submit/persistence. That's a good practice I would say.
This is another way from correct answer on Sujan Sivagurunathan, i wrote not in comment because i dont have 50 reputation.
If you have AbstractFacade.java write this on create method
public void create(T entity) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
javax.validation.Validator validator = factory.getValidator();
Set<ConstraintViolation<T>> constraintViolations = validator.validate(entity);
if (constraintViolations.size() > 0 ) {
System.out.println("Constraint Violations occurred..");
for (ConstraintViolation<T> contraints : constraintViolations) {
System.out.println(contraints.getRootBeanClass().getSimpleName()+
"." + contraints.getPropertyPath() + " " + contraints.getMessage());
}
getEntityManager().persist(entity);
}
}

Adding JavaFX2 Controls dynamically

I'm quite new to java and javafx and have a problem which i could not solve.
I need to dynamically add new custom controlls to a javafx scene. Further i need interaction between the main control and the added controls.
I found already some useful information in the web but could not put it together.
So i build a little example for explanation:
main class:
public class Test_TwoController extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Fxml1.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The main fxml:
<AnchorPane id="fxml1_anchorpane_id" fx:id="fxml1_anchorpane" prefHeight="206.0" prefWidth="406.0" xmlns:fx="http://javafx.com/fxml" fx:controller="test_twocontroller.Fxml1Controller">
<children>
<HBox id="fxml1_hbox_id" fx:id="fxml1_hbox" prefHeight="200.0" prefWidth="400.0">
<children>
<Button id="fxml1_button_id" fx:id="fxml1_button" mnemonicParsing="false" onAction="#button_action" prefHeight="200.0" prefWidth="200.0" text="Button" />
</children>
</HBox>
</children>
</AnchorPane>
and its controller:
public class Fxml1Controller implements Initializable {
#FXML HBox hbox;
#FXML Button button;
#Override
public void initialize(URL url, ResourceBundle rb) { }
public void button_action(ActionEvent event) throws IOException {
// 1. add an instance of Fxml2 to hbox
// 2. change to tab2 in new Fxml2
// or
// notify Fxml2Controller to change to tab2 in Fxml2
}
}
And now the control to dynamically add:
Its fxml:
<AnchorPane id="fxml2_anchorpane_id" fx:id="fxml2_anchorpane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml" fx:controller="test_twocontroller.Fxml2Controller">
<children>
<TabPane id="fxml2_tabpane_id" fx:id="fxml2_tabpane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab id="fxml2_tab1_id" fx:id="fxml2_tab1" text="tab1">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab id="fxml2_tab2_id" fx:id="fxml2_tab2" onSelectionChanged="#onSelectionChanged" text="tab2">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
and the controler:
public class Fxml2Controller {
#FXML TabPane tabpane;
#FXML Tab tab1;
#FXML Tab tab2;
public Fxml2Controller() throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Fxml2.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
}
public void onSelectionChanged(Event e) throws IOException {
FXMLLoader loader = new FXMLLoader();
// how can i get the current Fxml1 anchorpane instance?
AnchorPane root = (AnchorPane) loader.load(getClass().getResource("Fxml1.fxml").openStream());
Button b = (Button)root.lookup("#fxml1_button_id");
b.setText("New Button Text"); // dont change the buttons text!!!
}
}
The usage is: A fxml2 should be added to the hbox of fxml1. Then after a button click in fxml1 the tabs of fxml2 should change.
You may have a look at that image http://s13.postimage.org/uyrmgylo7/two_controlls.png
So my questions are:
how can i add one or more of the fxml2 controller into the hbox of fxml1?
how can i access one control from another or communicate between controlls? See onSelectionChanged() method in Fxml2Controller for detail.
Thank you in advance,
solarisx
You seem to have mixed quite a few concepts together which are distinct. First of all, a Stage can be understood as a window on the screen. It has a Scene object which holds the actual SceneGraph. In your example, you are creating a new Stage and a new Scene that get filled which the content of your second fxml-file. This means that, if working, a second window will pop up containing your stuff. I don't think that this is what you want to achieve.
Moreover, when the FXMLLoader reads a file, it looks for the class that is specified as its controller and constructs an instance of it via reflection. This means that when you call the load method in the constructor of the controller of the fxml-file you are loading with it, you are causing an infinite loop.
The last thing to understand is that the object that load() returns is an arbitrary node which can be put into the SceneGraph of your application just like any other node.
So to make your concept work, you should make the following:
Move the loading-code which is currently in the constructor of your second controller to the button_Action method of your first controller.
Throw away the new-stage-new-scene code in the button_action and take the Node returned by the FXMLLoader and add it to the children of the HBox.
For your second question, you can get the controller instance if you actually create an instance of an FXMLLoader instead of calling the static method, and use the load() method in it. After calling load() you can retrieve the controller and root object of the fxml-file via getController() and getRoot(). You can then use them just like any arbitrary object in your logic.

How to modify a Label from another Controller (lookup + update)?

I have created a tabPane. Under each tab, I have included () an fxml to show the actual session user, with this code :
home-tab.fxml has this line :
<fx:include fx:id="topTab" source="../top-tab.fxml"/>
top-tab.fxml :
<AnchorPane maxHeight="20.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="wuendo.client.TopTabController">
<children>
<HBox id="hbox_top" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<Label id="label_session" prefHeight="20.0" text="SESSION : " />
<Label fx:id="sessionLabel" prefHeight="20.0" text="" />
</HBox>
</children>
</AnchorPane>
TopTabController.java :
#FXML public Label sessionLabel;
HomeTabController.java :
#FXML private TopTabController topTabController;
#Override
public void initialize(URL url, ResourceBundle rb) {
URL location = getClass().getResource("../top-tab.fxml");
FXMLLoader fxmlLoader = new FXMLLoader(location);
AnchorPane root = null;
try {
root = (AnchorPane) fxmlLoader.load();
} catch (IOException ex) {
Logger.getLogger(HomeTabController.class.getName()).log(Level.SEVERE, null, ex);
}
topTabController = (TopTabController) fxmlLoader.getController();
Label txt = (Label) root.lookup("#sessionLabel");
txt.setText("blabla");
System.out.println("sessionLabel= " + topTabController.sessionLabel.getText());
}
When I execute this, the console prints "blabla", but the label is not modified in the program (gui)
What do I have to do to see the value updated ?
Thank you all
The FXMLLoader is already created the TopTabController while the home-tab.fxml is being loaded. And it is the rendered one in the scene. However you are creating/loading another instance of TopTabController which is not added to the any scene. And you are changing the text of the label in the second one. The correct approach is to modify the already loaded 1st instance and not to load other one:
#Override
public void initialize(URL url, ResourceBundle rb) {
topTabController.sessionLabel.setText("Real blabla");
System.out.println("sessionLabel= " + topTabController.sessionLabel.getText());
}
Side note, The link you provided in the comment was useful.

Inheritance mapping throwing an exception with MOXy

I followed the second option mentioned in JAXB inheritance in MOXY to map my parent class and child class listed below. MOXy is throwing the below exception and not sure what the issue is
Parent class
public class UnitedStatesAddressData extends AbstractAddress implements UnitedStatesAddress, Serializable, Cloneable
{
private String primaryAddress;
public String getPrimaryAddress()
{
return primaryAddress;
}
public void setPrimaryAddress(final String primaryAddress)
{
this.primaryAddress = primaryAddress;
}
}
Child Class
public class TokenizedUnitedStatesAddressData extends UnitedStatesAddressData implements TokenizedUnitedStatesAddress,
CloneableAddress
{
private String houseNumber;
private String preDirectional;
private String streetName;
private String streetType;
//getters and setters ignored
}
external binding file
<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd"
version="2.4" package-name="com.abc.ic.domain.impl.country.us" xml-accessor-type="PROPERTY">
<xml-schema element-form-default="QUALIFIED" namespace="http://xml.abc.com/XMLSchema/InterConnect">
<!-- Do not specify 'prefix'. We doesn't want the namespace prefix in our instance documents as they increase the payload size. -->
<xml-ns namespace-uri="http://xml.abc.com/XMLSchema/InterConnect" />
</xml-schema>
<java-types>
<java-type name="TokenizedUnitedStatesAddressData">
<xml-root-element name="USAddress" />
<xml-type prop-order="preDirectional houseNumber streetName streetType postDirection unitDesignator apartmentNumber primaryAddress secondaryAddress cityName stateAbbreviation zipCode" />
<java-attributes>
<xml-element name="StreetPreDirection" java-attribute="preDirectional" />
<xml-element name="StreetNumber" java-attribute="houseNumber" />
<xml-element name="StreetName" java-attribute="streetName" />
<xml-element name="StreetType" java-attribute="streetType" />
<xml-element name="StreetPostDirection" java-attribute="postDirection" />
<xml-element name="UnitDesignator" java-attribute="unitDesignator" />
<xml-element name="UnitNumber" java-attribute="apartmentNumber" />
<xml-element name="AddressLine1" java-attribute="primaryAddress" />
<xml-element name="AddressLine2" java-attribute="secondaryAddress" />
<xml-element name="City" java-attribute="cityName" />
<xml-element name="State" java-attribute="stateAbbreviation" />
<xml-element name="PostalCode" java-attribute="zipCode" />
</java-attributes>
</java-type>
<java-type name="UnitedStatesAddressData" xml-transient="true">
<xml-root-element />
</java-type>
</java-types>
</xml-bindings>
Error
javax.xml.bind.JAXBException:
Exception Description: The property or field primaryAddress is annotated to be transient so can not be included in the proporder annotation.
- with linked exception:
[Exception [EclipseLink-50009] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The property or field primaryAddress is annotated to be transient so can not be included in the proporder annotation.]
at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:908)
at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:157)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:170)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:157)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:117)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:331)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at com.abc.ic.platform.sts.domain.transformation.response.JaxbTest.beforeClass(JaxbTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: Exception [EclipseLink-50009] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The property or field primaryAddress is annotated to be transient so can not be included in the proporder annotation.
at org.eclipse.persistence.exceptions.JAXBException.transientInProporder(JAXBException.java:225)
at org.eclipse.persistence.jaxb.compiler.TypeInfo.setProperties(TypeInfo.java:342)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.buildTypeInfo(AnnotationsProcessor.java:755)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.postBuildTypeInfo(AnnotationsProcessor.java:669)
at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:344)
at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:145)
at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:904)
... 28 more
UPDATE
I've tested this by removing "prop-order" and this works fine except that I can no longer control the order of the elements in generated XML. I believe this is a bug in the code.
The cause for this is that the child class overrides the method from parent class as sown below but since the parent class has been defined to be xml-transient="true", the below check from TypeInfo is failing.
child class overriding getPrimaryAddress
public class TokenizedUnitedStatesAddressData extends UnitedStatesAddressData implements TokenizedUnitedStatesAddress,
CloneableAddress
{
#override
public String getPrimaryAddress()
{
return primaryAddress;
}
}
TypeInfo.java offending code
if (p.isTransient() && propOrderList.contains(p.getPropertyName()))
{
throw org.eclipse.persistence.exceptions.JAXBException.transientInProporder(p.getPropertyName());
}
UPDATE 2
The issue is not with the AbstractAddress. After some debugging, the issue seems to be with the below logic in the AnnotationProcessor.getPropertyPropertiesForClass(final JavaClass cls, final TypeInfo info, final boolean onlyPublic, final boolean onlyExplicit)
if ((setMethod == null) && !(hasJAXBAnnotations(getMethod)))
{
// if there's no corresponding setter, and not explicitly
// annotated, don't process
isPropertyTransient = true;
}
This method will tag any method that doesn't have both the get/set methods defined as "transient". In my case, I override just the getPrimaryAddress() method in TokenizedUnitedStatesAddressData class and not the corresponding setter. And hence the Annotationprocessor is designating it as a transient property neglecting the fact that this method is being overridden.
FIX
The issue is fixed after making sure that the overridden methods are properly handled in the transient check as shown below
if ((setMethod == null) && !(hasJAXBAnnotations(getMethod)))
{
if (!isMethodOverrriden(cls.getQualifiedName(), getMethod.getName()))
{
// if there's no corresponding setter, and not explicitly
// annotated, don't process
isPropertyTransient = true;
}
}
public static boolean isMethodOverrriden(final String classQualifiedName, final String methodName)
{
Method myMethod;
try
{
myMethod = Class.forName(classQualifiedName).getMethod(methodName, null);
}
catch (Exception e1)
{
return false;
}
Class<?> declaringClass = myMethod.getDeclaringClass();
if (declaringClass.equals(Object.class))
{
return false;
}
Class<?> superclass = declaringClass.getSuperclass();
if (superclass == null)
{
return false;
}
else
{
try
{
superclass.getMethod(myMethod.getName(), myMethod.getParameterTypes());
}
catch (NoSuchMethodException e)
{
// recursively check all super classes
isMethodOverrriden(superclass.getName(), methodName);
}
return true;
}
}
Even though you have marked UnitedStatesAddressData as #XmlTransient (using MOXy's external mapping document), it's super class AbstractAddress is still a mapped class. As such properties from AbstractAddress can not be specified in the propOrder setting for TokenizedUnitedStatesAddressData. The solution will be to make AbstractAddress #XmlTransient as well.
Fix
I have modified your mapping document to do this below assuming that the AbstractAddress class is in the same package as the rest of your domain model.
<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd"
version="2.4" package-name="com.abc.ic.domain.impl.country.us" xml-accessor-type="PROPERTY">
<xml-schema element-form-default="QUALIFIED" namespace="http://xml.abc.com/XMLSchema/InterConnect">
<!-- Do not specify 'prefix'. We doesn't want the namespace prefix in our instance documents as they increase the payload size. -->
<xml-ns namespace-uri="http://xml.abc.com/XMLSchema/InterConnect" />
</xml-schema>
<java-types>
<java-type name="TokenizedUnitedStatesAddressData">
<xml-root-element name="USAddress" />
<xml-type prop-order="preDirectional houseNumber streetName streetType postDirection unitDesignator apartmentNumber primaryAddress secondaryAddress cityName stateAbbreviation zipCode" />
<java-attributes>
<xml-element name="StreetPreDirection" java-attribute="preDirectional" />
<xml-element name="StreetNumber" java-attribute="houseNumber" />
<xml-element name="StreetName" java-attribute="streetName" />
<xml-element name="StreetType" java-attribute="streetType" />
<xml-element name="StreetPostDirection" java-attribute="postDirection" />
<xml-element name="UnitDesignator" java-attribute="unitDesignator" />
<xml-element name="UnitNumber" java-attribute="apartmentNumber" />
<xml-element name="AddressLine1" java-attribute="primaryAddress" />
<xml-element name="AddressLine2" java-attribute="secondaryAddress" />
<xml-element name="City" java-attribute="cityName" />
<xml-element name="State" java-attribute="stateAbbreviation" />
<xml-element name="PostalCode" java-attribute="zipCode" />
</java-attributes>
</java-type>
<java-type name="UnitedStatesAddressData" xml-transient="true">
<xml-root-element />
</java-type>
<java-type name="AbstractAddress" xml-transient="true">
<xml-root-element />
</java-type>
</java-types>
</xml-bindings>
For More Information
http://blog.bdoughan.com/2012/08/jaxbs-xmltransient-and-property-order.html

Resources