I would like to perform a simple change of the text of a label, using vaadin 7 & scala.
here is my UI:
package com.example.scaladinchat
import com.github.nscala_time.time.Imports._
import vaadin.scala.UI
import vaadin.scala.VerticalLayout
import vaadin.scala.Label
import vaadin.scala.server.ScaladinRequest
import vaadin.scala.Button
import metier.Objets.Rdv
import models.{ oracle => myOracle }
import vaadin.scala.PushMode
class N02Parameters extends UI with myOracle { app =>
pushConfiguration.pushMode = PushMode.Automatic
val l = Label("zigouigoui")
def changeLabel{
access{
l.value="roploplo"
}
}
override def init(request: ScaladinRequest) {
content = new VerticalLayout {
add(l)
val b = Button("Click me!", { e =>
changeLabel
})
add(b)
}
}
}
but when I call the page, there is at the top-right of my window an waiting animation, and I wait but nothing happens.
can you tell me what's going wrong?
thanks
As I can not yet comment, I ask as an answer:
You can get the page running using only a label right? Cause I had a problem referring to scala and vaadin in connection with apache tomcat, which looked as you discribed.
Related
I have a Kotlin Multiplatform project where I want to use Events to control views.
The basic idea is this:
Buttons & Co fire an Event when clicked
These events get caught and handled by the responsible program components, which will in turn fire other events
Eventually, some kind of ViewEvent is fired, which is subscribed to by the ViewController
The ViewController then tells the program what should be drawn on the screen
In theory, that sounds like it should work. In practice, what happens is that while it gets to the point where the ViewController receives the event and reacts accordingly, the actual views are unaffected.
My ViewController looks like this:
import androidx.compose.runtime.Composable
import com.tri_tail.ceal_chronicler.events.OpenCharacterSelectionViewEvent
import com.tri_tail.ceal_chronicler.ui.main_view.MainView
import com.tri_tail.ceal_chronicler.ui.main_view.MainViewState
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
class ViewController {
private var mainViewState = MainViewState.TITLE
init {
val eventBus = EventBus.getDefault()
eventBus.register(this)
}
#Composable
fun draw() {
MainView(mainViewState)
}
#Subscribe
fun onOpenCharacterSelectionViewEvent(event: OpenCharacterSelectionViewEvent) {
mainViewState = MainViewState.CHARACTER
}
}
I debugged that, and was able to see that the mainViewState changes, as expected. However, the draw() function is never called again, and so the changed mainViewState never arrives in the MainView.
I've already tried making mainViewState a mutableStateOf(mainViewState), but that didn't change anything.
Furthermore, I can't just call draw() inside the onOpenCharacterSelectionViewEvent, because it is not #Composable, and adding that annotation to the method causes the build to fail.
At this point, I am not even sure whether what I am trying to do here can work this way. Can someone please help me out here?
I have also published a version of the code with the current non-working solution here: https://github.com/KiraResari/ceal-chronicler/tree/event-system
For my KMM project i use open source viewModel for KMM.
This one https://github.com/adeo-opensource/kviewmodel--mpp
I suggest transfer your MVC architecture to MVI and use this KMM viewModel to control your state as in usual android app.
Okay, so after worrying at this for several days, I have now come up with a solution that works.
Basically, the reason why it doesn't work as I tried it is that the frontend lives in its own little world, and it is very difficult for something from outside that world to affect it.
However, it can be done using delegates. Basically, what I called the ViewController in above is more of a MainViewModel, and it needs to look like this:
import com.tri_tail.ceal_chronicler.events.OpenCharacterSelectionViewEvent
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
class MainViewModel {
var state = MainViewState.TITLE
var updateState: ((MainViewState) -> Unit) = { }
set(value) {
field = value
updateState(state)
}
init {
val eventBus = EventBus.getDefault()
eventBus.register(this)
}
#Subscribe
fun onOpenCharacterSelectionViewEvent(event: OpenCharacterSelectionViewEvent) {
state = MainViewState.CHARACTER
updateState(state)
}
}
The other part of the magic happens in the MainView, where the state needs to be a remember with a mutableStateOf(..., policy = neverEqualPolicy()), and the delegate needs to be set like this:
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.*
import com.tri_tail.ceal_chronicler.models.main_view.MainViewModel
import com.tri_tail.ceal_chronicler.models.main_view.MainViewState
import com.tri_tail.ceal_chronicler.theme.AppTheme
import com.tri_tail.ceal_chronicler.ui.TitleScreen
import com.tri_tail.ceal_chronicler.ui.characters.DisplayCharacterSelector
#Composable
fun MainView(model: MainViewModel = MainViewModel()) {
var state by remember {
mutableStateOf(
model.state,
policy = neverEqualPolicy()
)
}
model.updateState = {
state = it
}
AppTheme {
when (state) {
MainViewState.TITLE -> TitleScreen()
MainViewState.CHARACTER -> DisplayCharacterSelector()
}
}
}
And that's all there is to it! Works like a charm, no extra libraries required.
im new to alot of this, trying to combine two projects together in Android Studio,
im getting an error of the bellow code. Line 52, "override fun onCreateView(" giving me a error overrides nothing. can anyone fix this code? searching elsewhere on this site talks about "Kotlin '?' indicates that this value can be null in Kotlin." but im struggling to fix it. Thank you xx
package com.example.version4.ui.map
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.example.version4.R
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
class MapsFragment : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.text_map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val OrchidsSpa = LatLng(52.316296, -2.261900)
mMap.addMarker(MarkerOptions().position(OrchidsSpa).title("Marker in Bryony's # Orchids Spa"))
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(OrchidsSpa,12F))
}
private lateinit var mapsViewModel: MapsViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mapsViewModel =
ViewModelProviders.of(this).get(MapsViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_maps, container, false)
val textView: TextView = root.findViewById(R.id.text_map)
mapsViewModel.text.observe(this, Observer {
textView.text = it
})
return root
}
}
onCreateView is in Fragment, not AppCompatActivity.
I'm trying to use SqlStorage in an ionic app. I'm getting the error in the title. I'm guessing I need to include SqlStorage but I'm not sure where. My code looks a lot like what's in the docs http://ionicframework.com/docs/v2/api/platform/storage/SqlStorage/ . How do you include SqlStorage?
var prefrences = {
foo: bar
}
let storage = new Storage(SqlStorage);
storage.set('storedPreferences', preferences);
Add SqlStorage to your list of 'include' packages via import statement. i.e
import {SqlStorage} from 'ionic-angular';
For example
import {SqlStorage,...} from 'ionic-angular';
#Page({
templateUrl: 'path/to/template'
})
export class MyPage {
constructor(){
let storage = new Storage(SqlStorage);
...
}
...
}
How do I get the child component for a particular position on a Scala Swing BorderPanel? I can place components OK. In this particular case I want to check the component at BorderPanel.Position.Centre. Also am I right that there can only be one child component or a null at each position: North, East etc?
Well, the layout is a Map from component to position, so the following works (not sure if there's an easier way):
import scala.swing.SimpleSwingApplication
import scala.swing.MainFrame
import scala.swing.BorderPanel
import scala.swing.Label
object BorderLayoutTest extends SimpleSwingApplication {
def top = new MainFrame {
contents = new BorderPanel {
val label = new Label("hi")
import BorderPanel.Position._
layout(label) = Center
println("North: " + layout.find(_._2 == North)) //None
println("Center: "+ layout.find(_._2 == Center)) //Some( ... )
}
}
}
I'm writing a small GUI program. Everything works except that I want to recognize mouse double-clicks. However, I can't recognize mouse clicks (as such) at all, though I can click buttons and select code from a list.
The following code is adapted from Ingo Maier's "The scala.swing package":
import scala.swing._
import scala.swing.event._
object MouseTest extends SimpleGUIApplication {
def top = new MainFrame {
listenTo(this.mouse) // value mouse is not a member of scala.swing.MainFrame
reactions += {
case e: MouseClicked =>
println("Mouse clicked at " + e.point)
}
}
}
I've tried multiple variations: mouse vs. Mouse, SimpleSwingApplication, importing MouseEvent from java.awt.event, etc. The error message is clear enough--no value mouse in MainFrame--so, where is it then? Help!
Maybe that way?
object App extends SimpleSwingApplication {
lazy val ui = new Panel {
listenTo(mouse.clicks)
reactions += {
case e: MouseClicked =>
println("Mouse clicked at " + e.point)
}
}
def top = new MainFrame {
contents = ui
}
}
BTW, SimpleGUIApplication is deprecated
The MouseClicked event has an attribute clicks, which should be 2 if it was a double-click. Have a look at java.awt.event.MouseEvent for the original source if you're curious.