Skip to content

Commit

Permalink
gui
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenbmfj committed Mar 5, 2019
1 parent 2fcf8f8 commit af34cc4
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 1 deletion.
8 changes: 7 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
base
kotlin("jvm") version "1.3.21"
kotlin("jvm") version "1.3.21" apply false
}

allprojects {
group = "io.mfj"
version = "1.0-SNAPSHOT"

tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
}
14 changes: 14 additions & 0 deletions gui/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
application
kotlin("jvm")
}

dependencies {
implementation(kotlin("stdlib-jdk8"))
compile(project(":common"))
compile("org.slf4j:slf4j-api:1.7.21")
compile("org.slf4j:slf4j-simple:1.7.21")
compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8")
compile("no.tornado:tornadofx:1.7.18")
}

68 changes: 68 additions & 0 deletions gui/src/main/java/io/mfj/kotlinnight/library/gui/BooksView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.mfj.kotlinnight.library.gui

import io.mfj.kotlinnight.library.*

import javafx.beans.binding.Bindings
import javafx.scene.Parent
import javafx.scene.control.Alert
import javafx.scene.control.Button
import javafx.scene.control.TableView

import tornadofx.*

class BooksView:View() {

val controller:LibraryController by inject()

var table:TableView<GBook> by singleAssign()
var checkoutButton:Button by singleAssign()

override val root:Parent = vbox {
toolbar {
checkoutButton = button("Checkout") {
action {
val book = table.selectionModel.selectedItem
.checkouts
.entries
.first { (_,checkout) ->
checkout == null
}
.key
var checkout:Checkout? = null
runAsync {
checkout = controller.checkout( book )
} ui {
alert(
type = Alert.AlertType.INFORMATION,
title = "Checked out",
header = "Checked out ${checkout!!.book.title.title} checked out, due ${checkout!!.due}."
)
}
}
}
}
table = tableview(controller.books) {
readonlyColumn("Title",GBook::bookTitle)
readonlyColumn("Author",GBook::author)
readonlyColumn("Available",GBook::available)
}
}

override fun onDock() {
super.onDock()
controller.loadBooks()
}

init {
checkoutButton.disableProperty().bind(
table.selectionModel.selectedItemProperty().isNull
.or(
Bindings.select<Int>(
table.selectionModel.selectedItemProperty(),
"available"
).isEqualTo(0)
)
)
}

}
59 changes: 59 additions & 0 deletions gui/src/main/java/io/mfj/kotlinnight/library/gui/CheckoutsView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.mfj.kotlinnight.library.gui

import io.mfj.kotlinnight.library.*

import javafx.scene.Parent
import javafx.scene.control.Alert
import javafx.scene.control.Button
import javafx.scene.control.TableView
import tornadofx.*

class CheckoutsView:View() {

val controller:LibraryController by inject()

var table:TableView<Checkout> by singleAssign()
var checkinButton:Button by singleAssign()

override fun onDock() {
super.onDock()
runAsync {
controller.loadCheckouts()
}
}

override val root:Parent = vbox {
toolbar {
checkinButton = button("Return") {
action {
val checkout = table.selectionModel.selectedItem
runAsync {
controller.checkin( checkout )
controller.loadCheckouts()
} ui {
alert(
type = Alert.AlertType.INFORMATION,
title = "Checked in",
header = "${checkout.book.title.title} checked in"
)
}
}
}
}
table = tableview(controller.checkouts) {
readonlyColumn("Book",Checkout::book).cellFormat {
text = it.title.title
}
readonlyColumn("Out",Checkout::out)
readonlyColumn("Due",Checkout::due)
}
}

init {
checkinButton.disableProperty().bind(
table.selectionModel.selectedItemProperty().isNull
)
}


}
25 changes: 25 additions & 0 deletions gui/src/main/java/io/mfj/kotlinnight/library/gui/GBook.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.mfj.kotlinnight.library.gui

import io.mfj.kotlinnight.library.*
import javafx.beans.property.IntegerProperty
import javafx.beans.property.SimpleStringProperty
import javafx.beans.property.StringProperty
import tornadofx.*

class GBook( val title:Title, val checkouts:MutableMap<Book,Checkout?> ) {

val bookTitle = title.title
val author = title.author

var availableProperty:IntegerProperty = calcAvailable().toProperty()
val available by availableProperty

fun updateCheckouts( checkouts:Map<Book,Checkout?> ) {
this.checkouts.putAll(checkouts)
availableProperty.value = calcAvailable()
}

private fun calcAvailable():Int =
checkouts.count { (_,checkout) -> checkout == null }

}
14 changes: 14 additions & 0 deletions gui/src/main/java/io/mfj/kotlinnight/library/gui/LibraryApp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.mfj.kotlinnight.library.gui

import tornadofx.*

class LibraryApp:App(LibraryView::class) {

companion object {
@JvmStatic
fun main(args:Array<String>) {
launch<LibraryApp>(args)
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.mfj.kotlinnight.library.gui

import io.mfj.kotlinnight.library.*

import tornadofx.*
import java.time.LocalDate

class LibraryController:Controller() {

val inventory:Inventory = InventoryImpl

val titles = mutableListOf<Title>().observable()

fun loadTitles() {
titles.setAll( inventory.getTitles() )
}

val books = mutableListOf<GBook>().observable()

fun loadBooks() {
books.setAll(
inventory.getTitles()
.map { title ->
GBook( title,
inventory.getCheckouts(title.isbn).toMutableMap() )
}
)
}

val checkouts = mutableListOf<Checkout>().observable()

fun loadCheckouts() {
checkouts.setAll( inventory.getCheckouts() )
}

fun checkout( book:Book ): Checkout {
val checkout = inventory.checkout(book, LocalDate.now().plusDays(10))
loadBooks()
loadCheckouts()
return checkout
}

fun checkin( checkout:Checkout ) {
inventory.checkin(checkout.book)
loadBooks()
loadCheckouts()
}

}
63 changes: 63 additions & 0 deletions gui/src/main/java/io/mfj/kotlinnight/library/gui/LibraryView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.mfj.kotlinnight.library.gui

import javafx.scene.control.Alert

import tornadofx.*

class LibraryView:View() {

val taskStatus:TaskStatus by inject()

init {
title = "Library"
}

override val root = borderpane {
prefWidth = 800.0
top = vbox {
menubar {
menu("File") {
item("Quit") {
action {
System.exit(0)
}
}
}
menu("Help") {
item("About") {
action {
alert(
type = Alert.AlertType.INFORMATION,
title = "About Library GUI",
header = "Library GUI v1" )
}
}
}
}
}
center = tabpane {
tab("Titles") {
isClosable = false
add<TitlesView>()
}
tab("Books") {
isClosable = false
add<BooksView>()
}
tab("Checkouts") {
isClosable = false
add<CheckoutsView>()
}
}
bottom = stackpane {
visibleWhen { taskStatus.running }
progressbar { taskStatus.progress }
useMaxWidth = true
}
label(taskStatus.message) {
useMaxWidth = true
paddingLeft = 5
}
}

}
25 changes: 25 additions & 0 deletions gui/src/main/java/io/mfj/kotlinnight/library/gui/TitlesView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.mfj.kotlinnight.library.gui

import io.mfj.kotlinnight.library.*

import javafx.scene.Parent
import tornadofx.*

class TitlesView:View() {

val controller:LibraryController by inject()

override val root:Parent = tableview(controller.titles) {
readonlyColumn("Title",Title::title)
readonlyColumn("Author",Title::author)
readonlyColumn("ISBN",Title::isbn)
}

override fun onDock() {
super.onDock()
runAsync {
controller.loadTitles()
}
}

}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ rootProject.name = "kotlinnight"
include("common")
include("web-javalin")
include("web-ktor")
include("gui")

0 comments on commit af34cc4

Please sign in to comment.