sfxcode / sapphire-core

Scala - JavaFX Application Framework (CDI, Binding, Expressions)
https://sfxcode.github.io/sapphire-javafx
Apache License 2.0
8 stars 1 forks source link

FXBeanAdapter does not work #16

Closed ASchmidt84 closed 5 years ago

ASchmidt84 commented 5 years ago

I have a problem. I created the manufactoroverview.fxml and also the controller. I set up a FXBeanAdapter. And on each change of the selection I set on adapter the new bean. But still no changes. Their should be the textfields setup the content.

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.TextFlow?>

<?import com.sfxcode.sapphire.core.control.FXValueFactory?>

<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.operatorView.view.ManufactorOverviewController">
   <children>
      <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" HBox.hgrow="ALWAYS">
         <children>
            <FlowPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="5.0" />
               </VBox.margin>
               <children>
                  <Label text="Label" />
               </children>
            </FlowPane>
            <TableView fx:id="manufactorTable" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" VBox.vgrow="ALWAYS">
              <columns>
                  <TableColumn fx:id="name" maxWidth="1.7976931348623157E308" prefWidth="250" text="%manufactor.name">
                      <cellValueFactory>
                          <FXValueFactory property="name" />
                      </cellValueFactory>
                  </TableColumn>
                <TableColumn fx:id="internalReferenceCol" maxWidth="1.7976931348623157E308" prefWidth="250" text="%manufactor.reference">
                    <cellValueFactory>
                        <FXValueFactory property="internalReference" />
                    </cellValueFactory>
                </TableColumn>
                  <TableColumn fx:id="country" maxWidth="1.7976931348623157E308" prefWidth="250" text="%manufactor.address.countryIsoCode">
                      <cellValueFactory>
                          <FXValueFactory property="headquarter.countryIsoCode" />
                      </cellValueFactory>
                  </TableColumn>
                  <TableColumn fx:id="state" maxWidth="1.7976931348623157E308" prefWidth="250" text="%manufactor.address.state">
                      <cellValueFactory>
                          <FXValueFactory property="headquarter.place" />
                      </cellValueFactory>
                  </TableColumn>
                  <TableColumn fx:id="zip" maxWidth="1.7976931348623157E308" prefWidth="250" text="%manufactor.address.zip">
                      <cellValueFactory>
                          <FXValueFactory property="headquarter.postalCode" />
                      </cellValueFactory>
                  </TableColumn>
              </columns>
            </TableView>
            <ScrollPane fitToWidth="true" maxWidth="1.7976931348623157E308">
              <content>
                <AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0">
                     <children>
                        <GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                          <columnConstraints>
                            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                              <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                              <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                          </columnConstraints>
                          <rowConstraints>
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                              <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                          </rowConstraints>
                           <children>
                              <TextFlow fx:id="manufactorHeadline" GridPane.columnSpan="4" />
                              <Separator prefWidth="200.0" GridPane.columnSpan="4" GridPane.rowIndex="1" />
                              <Label id="test" text="Label" GridPane.rowIndex="2" />
                              <Label text="Label" GridPane.rowIndex="3" />
                              <Label text="Label" GridPane.rowIndex="4" />
                              <TextField id="internalReference" GridPane.columnIndex="1" GridPane.rowIndex="2" />
                              <TextField GridPane.columnIndex="1" GridPane.rowIndex="3" />
                              <TextField id="title" GridPane.columnIndex="1" GridPane.rowIndex="5" />
                              <TextField fx:id="forenameField" GridPane.columnIndex="1" GridPane.rowIndex="6" />
                              <TextField fx:id="surnameField" GridPane.columnIndex="1" GridPane.rowIndex="7" />
                              <ComboBox fx:id="salutationCombo" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.rowIndex="4" />
                              <TextField fx:id="companyField" GridPane.columnIndex="1" GridPane.rowIndex="8" />
                              <TextField fx:id="streetField" GridPane.columnIndex="1" GridPane.rowIndex="9" />
                              <TextField fx:id="housenumberField" GridPane.columnIndex="1" GridPane.rowIndex="10" />
                           </children>
                        </GridPane>
                     </children>
                  </AnchorPane>
              </content>
            </ScrollPane>
         </children>
      </VBox>
   </children>
</HBox>

The controller


package controller.operatorView.view

import com.sfxcode.sapphire.core.controller.ViewController
import com.sfxcode.sapphire.core.fxml.FxmlLoader
import com.sfxcode.sapphire.core.value.{BeanConversions, FXBean, FXBeanAdapter, KeyBindings}
import controller.utils.FXUtils
import de.scalamat.manufactorManagement.api.manufactor.response.ManufactorApi
import javafx.fxml.FXML
import javax.inject.Inject
import model.rest.ManufactorPortal
import scalafx.application.Platform
import scalafx.collections.ObservableBuffer
import scalafx.scene.control.TableView
import scalafx.scene.text.Text

import scala.util.Try

@FxmlLoader(path = "/fxml/operator/view/manufactoroverview.fxml")
class ManufactorOverviewController extends AbstractViewController with BeanConversions {

  import scalafx.Includes._

  @Inject
  var _dataPortal: ManufactorPortal = _
  def dataPortal = _dataPortal

  @FXML
  private var manufactorHeadline: javafx.scene.text.TextFlow = _

  @FXML
  private var manufactorTable: javafx.scene.control.TableView[FXBean[ManufactorApi]] = _

  private val manufactorBuffer: ObservableBuffer[FXBean[ManufactorApi]] = ObservableBuffer()

  lazy val manufactorAdapter: FXBeanAdapter[ManufactorApi] = FXBeanAdapter[ManufactorApi](this)
  manufactorAdapter.beanProperty.onChange((_, _, e) ⇒ println(e) )

  override def didGainVisibilityFirstTime(): Unit = {
    super.didGainVisibilityFirstTime()

    manufactorTable.items = manufactorBuffer

    println("!!!!!!!!!!!!!!!!!!!!!!!!!!")
    println(this.managedChildren)
    println("!!!!!!!!!!!!!!!!!!!!!!!!!!")

//    manufactorTable.columnResizePolicy = TableView.ConstrainedResizePolicy

    dataPortal.list(Long.MaxValue).map{u ⇒
      manufactorBuffer ++= u
    }.recover{
      case e ⇒ println(e)
    }
    dataPortal.count().map(r ⇒ r)
  }

  override def didGainVisibility(): Unit = {
    super.didGainVisibility()

    val bindingList = List("internalReference","test","title"/*,"country","state","zip"*/)
    val bindings = KeyBindings(bindingList)
//    bindings.add("manufactorHeadline","name")
//    bindings.add("housenumberField","headquarter.houseNumber")
//  bindings.add("internalReference","internalReference")
//    bindings.add("companyField","headquarter.company")
//    bindings.add("streetField","headquarter.street")
//    bindings.add("country","!{_.self.headquarter.countryIsoCode}")

    manufactorAdapter.addBindings(bindings)
    println("------------------------")
    println(bindings.childrenMap)
    println(manufactorAdapter.bindingMap)
    println(manufactorAdapter.guessPropertyForNode("internalReference"))
    println(manufactorAdapter.guessPropertyForNode("title"))
    println("####################")
    val s = FXBeanAdapter[ManufactorApi](this)
    s.addBindings(KeyBindings("test","internalReference"))
    println("s.converterMap " + s.converterMap)
    println(s.bindingMap)

    manufactorTable.selectionModel().selectedItem.onChange((_,_,e) ⇒ {
      if(e == null){
        manufactorAdapter.unset()
        manufactorHeadline.children.clear()
      } else {
        println(e.name)
        manufactorHeadline.children.clear()
        manufactorHeadline.children += new Text(e.name)
        manufactorAdapter.revert()
        manufactorAdapter.set(e)
      }
    })

//    adapter.addBindings(KeyBindings("internalReference","internalReference"))
    println("FERTIG")
  }

}
sfxcode commented 5 years ago

Bindings are created by the value of the id or fx:id attributes in the fxml file.

If node lookup from application root node does not work, you can fix it by adding a parent Node to FXBeanAdapter.

  @FXML
  var editPane: GridPane = _

  // second parameter parent Node is optional,
  // but sometimes needed for the correct NodeLocator lookup
  lazy val adapter: FXBeanAdapter[Person] = FXBeanAdapter[Person](this, editPane)

I will try to add some information in the project description.

Remember, bind to non String values needs add converter to the FXBeanAdapter.

adapter.addIntConverter("age")

Hope this will fix your problem.

Greetings Tom

ASchmidt84 commented 5 years ago

Good Morning Tom, yeah that is the way it rocks :+1:

I would appreciate a documentation. I like your project. And here in my company I forced to used it. It is a great piece of software.

What is about addIntConverter. Their is no such method in FXBeanAdapter. How can I use adapter? Is their a way to use collection in adapter? Sometimes I have an object (is a remote JSON) with an collection inside and I would like to display all of that or sometimes only a field. Thank you

ASchmidt84 commented 5 years ago

The issue is solved