How to pass variable from VaadinServlet to UI? - scala

I'm new to Vaadin. I want to use it to build admin backend. As I am familiar DI (Guice), I would like to inject dependencies into servlet. However, I don't know how to pass from servlet to UI layer. Below is my sample codes:
#Singleton
#VaadinServletConfiguration(productionMode = false, ui = classOf[LoginUI])
class TestServlet #Inject()(userDAO: UserDAO) extends VaadinServlet with LazyLogging {
//How to userDAO to LoginUI?
override def servletInitialized(): Unit = {
}
}
#Theme("valo")
class LoginUI extends UI with LazyLogging {
override def init(request: VaadinRequest) = {
logger.debug("Init Login UI")
val content: VerticalLayout = new VerticalLayout
setContent(content)
val label: Label = new Label("Hello, world!")
content addComponent label
content addComponent new Button("Click Me!",
new ClickListener {
override def buttonClick(event: ClickEvent) =
Notification.show("The time is ")
})
}
}
I see that although it is UI, it acts like controller layer, so I think it does not anti-pattern when doing that. I find it even more difficult to inject things into UI. However, if I can inject directly into UI, it would be better.

Related

libGDX Classes relationship

I am trying Libgdx Game Class to make a game.And I am following a book.There is an example. Example has 4 classes and 1 DesktopLauncher. DesktopLauncher use StarfishCollector3() class to main function. Despite I dont call create method and render method which are in GameBeta abstract class to StarfishCollector3, the project is working.Can you explain what I dont know.
class StarfishCollector3 : GameBeta() {
var turtle:Turtle=null
var starfish:ActorBeta=null
var ocean:ActorBeta=null
var winMessage:ActorBeta=null
var win:Boolean = true
override fun initialize() {
ocean= ActorBeta()
ocean.setTexture(Texture( Gdx.files.internal("water.jpg") ))
mainStage.addActor(ocean)
starfish = ActorBeta();
starfish.setTexture(Texture(Gdx.files.internal("starfish.png")) );
starfish.setPosition( 380F,380F );
mainStage.addActor( starfish );
turtle = Turtle()
turtle.setTexture( Texture(Gdx.files.internal("turtle-1.png")) )
turtle.setPosition( 20F,20F )
mainStage.addActor( turtle )
winMessage = ActorBeta();
winMessage.setTexture( Texture(Gdx.files.internal("you-win.png")) );
winMessage.setPosition( 180F,180F );
winMessage.setVisible( false );
mainStage.addActor( winMessage );
win = false }
override fun update(dt: Float) {
if (turtle.overlaps(starfish as ActorBeta)){
starfish.remove()
winMessage.setVisible(true)} }
}
abstract class GameBeta: Game() {
protected var mainStage: Stage=null
abstract fun initialize()
override fun create() {`
mainStage = Stage()
initialize() }
abstract fun update(dt:Float)
.
override fun render() {
var dt= Gdx.graphics.getDeltaTime()
mainStage.act()
update(dt)
Gdx.gl.glClearColor(0F,0F,0F,1F)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
mainStage.draw()
}
}
The heirarchy of StarfishCollector3 is that it extends GameBeta, which extends Game, which implements ApplicationListener.
In DesktopLauncher you instantiate a StarfishCollector3 and pass it as an implicit ApplicationListener to an Application constructor by calling something like new LwjglApplication(starfishCollectior, config);. When you instantiate that LwjglApplication (or Lwjgl3Application or AndroidApplication, etc. depending on backend), the constructor of that Application class sets up the game engine. It creates all the classes for managing OpenGL and drawing the game in a repeating loop, pausing and resuming, etc.
So the Application class is using your StarfishCollector3 as an ApplicationListener and calling its relevant lifecycle methods at the appropriate times.

How to use actionlistener in Scala Swing

I would like to make click counter in Scala Swing. I used for this ActionListener interface. But I don't know if I did it correctly. The program works, but I want to find out how to do this according to best practies. I will be very thankful for the answer how to do it correctly.
import javax.swing._
import java.awt._
import java.awt.event._
class UI extends JFrame {
var title_ : String = "Hello, Swing in Scala"
setTitle(title_)
val textArea = new JTextArea
var text : String = "Hello, Swing world in Scala!"
textArea.setText(text)
val scrollPane = new JScrollPane(textArea)
val panel = new JPanel
var text2 : String = "Click Here"
val button =new JButton(text2)
panel.add(button)
var clicks:Int = 0
def onClick(): Unit = {
clicks += 1
text = "Number of button clicks: " + clicks.toString
textArea.setText(text)
}
button.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = onClick() })
getContentPane.add(scrollPane, BorderLayout.CENTER)
getContentPane.add(panel, BorderLayout.SOUTH)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
setSize(new Dimension(600, 400))
setLocationRelativeTo(null)
def display() {
setVisible(true)
}
}
object SwingExample extends App {
val ui = new UI
ui.display()
println("End of main function")
}
there are simple things, which improve code quality and maintainability.
it seems that text, text2 and title_ can remove and put that value directly into.
to shorten it, try this statement for the onClick
def onClick(): Unit = {
clicks += 1
textArea.setText(s"Number of button clicks: $clicks")
}
see String Interpolation.
you can shorten your ActionListener by
button.addActionListener(e => onClick())

Print data received by REST call when using #Resource in Grails

Following along with groovies docs on REST, i've setup a model like so:
import grails.rest.*
#Resource(uri='/books')
class Book {
String title
static constraints = {
title blank:false
}
}
I'd print out the parameters I receive when creating and saving. Is there away to override these methods created by the #Resource(uri='/books') annotation? Or handle the annotation a closure or something to do this?
I think you may have 2 choices if you wish to have a default RESTful interface and modify it somewhat for your needs.
Use the $ grails generate-controller [Domain Class Name] command that will generate the appropriate controller and change the generated file as needed.
Create a Book controller and extend the RestfulController; then override the default methods with the #Override annotation, print/log the params, and then call the matching super method.
import grails.rest.RestfulController
class BookController extends RestfulController {
static responseFormats = ['json', 'xml']
BookController() {
super(Book)
}
#Override
def save() {
println params
super.save params
}
#Override
def update() {
println params
super.update params
}
}

How to signal/notify super-controller of change in sub-controller?

In JavaFX, how do you model the following:
I show a List of Customers in a Scene. On the left side there is a table on the right side (contentPane) the currently select customer's details are shown.
(Relevant part of) Main-Controller:
#jfxf.FXML
protected def newButtonPressed(): Unit =
{
contentPane.getChildren.clear
contentPane.getChildren.add(FXMLLoader.load(GUILoader.load("customers/form.fxml")))
}
There is a Button to add a new Customer. Upon clicking this button instead of opening a Popup, I replace the "details"-part of the scene and add a form there.
Now for this form (designed - like the rest of the GUI - in the SceneBuilder and saved as .fxml) I use another controller.
class Form extends Main with jfxf.Initializable
{
#jfxf.FXML
private var foreNameTextField: jfxsc.TextField = _
#jfxf.FXML
private var lastNameTextField: jfxsc.TextField = _
#jfxf.FXML
private var ageTextField: jfxsc.TextField = _
override def initialize(url: URL, resourceBundle: ResourceBundle): Unit =
{
}
#jfxf.FXML
protected def ok(): Unit =
{
// TODO validation
val newPerson = new Person(-1, foreNameTextField.getText, lastNameTextField.getText, ageTextField.getText.toInt)
// Save to DB
// Close whole form
}
}
When I'm done with filling in a new customer's detail I click on another button (that calls ok()) and save it to a database.
What I want to do now is close the form and replace it with the detail-form.
Something like calling a protected method in the main-controller like:
protected def clearDetails(): Unit =
{
contentPane.getChildren.clear
contentPane.getChildren.add(savedOldDetails)
}
won't work of course. (Will throw a runtime-exception because there is no contentpane in the sub/form-controller (even if I make it protected)
In Qt (C++) I'd use signals/slots and connect them accordingly.
Seems like in JavaFX there is nothing the like. How am I supposed to share such information?
Do I need to create a "super-controller" for the contentPane?
(I don't know Scala, so I'll write this in Java, hope that is ok).
You can define an observable property in the Form controller, and observe it when you load the form from the main controller:
public class Form implements Initializable {
private final ObjectProperty<Person> person = new SimpleObjectProperty<>(null);
public ObjectProperty<Person> personProperty() {
return person ;
}
public final Person getPerson() {
return personProperty().get();
}
public final void setPerson(Person person) {
personProperty().set(person);
}
// ... code you had before...
#FXML
protected void ok() {
Person person = new Person(-1, foreNameTextField.getText(), lastNameTextField.getText(), ageTextField.getText());
// save to DB...
personProperty().set(person);
}
}
Now in your main controller, load the form as follows:
#FXML
protected void newButtonPressed() {
contentPane.getChildren().clear();
FXMLLoader loader = new FXMLLoader(getClass().getResource("customers/form.fxml"));
Parent form = loader.load();
Form formController = loader.getController();
formController.personProperty().addListener((obs, oldPerson, newPerson) {
if (newPerson != null) {
// clear form, etc, e.g.
clearDetails();
}
});
contentPane.getChildren().add(form);
}

Incorporate fields from MegaProtoUser into a wizard screen

I'm just starting out with scala and lift and am a bit stuck regarding incorporating form fields from MegaProtoUser into a wizard screen.
I have the following MegaProtoUser code:
object User extends User
with MongoMetaRecord[User]
with MetaMegaProtoUser[User] {
override def skipEmailValidation = true
}
class User private () extends MongoRecord[User]
with MegaProtoUser[User] {
def meta = User
//protected methods ...
}
And my wizard setup looks like the following:
object SignupWizard extends Wizard {
object completeInfo extends WizardVar(false)
val person = new Screen {
//Incoroporate MegaProtoUser fields here ...
override def nextScreen = {
business
}
}
val business = new Screen {
val business = field("Business name","")
}
def finish() {
S.notice("Thank you for registering!")
completeInfo.set(true)
}
}
I want to incorporate some selected (not all) fields from my MegaProtoUser class into the person screen but do not now how to do this with the methods available to both. Any help is much appreciated.
AbstractScreen's addFields method can add individual fields, as well as adding all the fields from a Record object. This works on both LiftScreen and Wizard's Screen.
// assuming you just want to create a new user
object user extends WizardVar(User.createRecord)
val person = new Screen {
// addFields(() => user.is) would add all fields
addFields(() => user.is.email)
addFields(() => user.is.password)
addFields(() => user.is.timezone)
override def nextScreen = {
business
}
}