我想在单击newButton
时将选中的复选框更改为未选中。
因此,在handelNew
函数上,我为Item.select
分配了错误的值。
当我运行handleNew
函数时,它将表中的每个Item.select
设置为false,但是该复选框仍显示为选中状态。
通过搜索,我了解我必须添加回调代码或将updateItem
覆盖到cellFactory或以下项中:
这些答案似乎对我有帮助,但是每个代码都是用Java编写的,因此我不明白应在哪里放置Callback或updateItem
函数。
我试图将Java代码转换为Kotlin,但是转换后的代码仍然让我感到困惑。
我应该在哪里添加Callback / updateItem函数,以及如何对其进行更改?
我的环境: * JavaFX 11 * JDK 11
完整的源代码存储库:https://github.com/QuietJoon/StudyKotlin-JavaFX
Item.kt
import javafx.beans.property.*
class Item(isSelected: Boolean, groupID: GroupID, name: String){
val select = SimpleBooleanProperty()
private val name = SimpleStringProperty()
private val groupID = SimpleIntegerProperty()
var isSelected:Boolean
get() = select.get()
set(on) = select.set(on)
init{
setGroupID(groupID)
setName(name)
this.isSelected = isSelected
}
fun nameProperty():StringProperty = this.name
fun getName():String = this.nameProperty().get()
fun setName(name:String) = this.nameProperty().set(name)
fun groupIDProperty():IntegerProperty = this.groupID
fun getGroupID():GroupID = this.groupIDProperty().get()
fun setGroupID(groupID:GroupID) = this.groupIDProperty().set(groupID)
override fun toString():String = getGroupID().toString() + getName()
}
typealias GroupID = Int
GUI.kt
import java.util.*
import javafx.application.Application
import javafx.collections.FXCollections
import javafx.event.ActionEvent
import javafx.event.EventHandler
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.scene.control.*
import javafx.scene.input.TransferMode
import javafx.scene.paint.Paint
import javafx.scene.shape.Rectangle
import javafx.stage.Stage
class TAB : Application() {
private var selectAllCheckBox: CheckBox? = null
override fun start(primaryStage: Stage) {
primaryStage.title = "Study Tab layout!"
primaryStage.isAlwaysOnTop = true
val fxml = javaClass.getResource("fxml/Tab.fxml")
val root: Parent = FXMLLoader.load(fxml)
val scene = Scene(root)
val itemTable = root.lookup("#TableView1") as TableView<Item>
val newButton = root.lookup("#NewButton") as Button
selectAllCheckBox = CheckBox()
scene.onDragOver = EventHandler { event ->
val db = event.dragboard
if (db.hasFiles()) {
event.acceptTransferModes(TransferMode.COPY)
} else {
event.consume()
}
}
scene.onDragDropped = EventHandler { event ->
val db = event.dragboard
var success = false
if (db.hasFiles()) {
success = true
// Session #1
val itemList = db.files.map {
val anItem = Item(false,0,it.toString())
anItem.select.addListener{ ov,old_val,new_val ->
println(anItem.getName() + "'s CB status changed from '"
+ old_val + "' to '" + new_val + "'.")
}
anItem
}
itemTable.items = FXCollections.observableArrayList(itemList)
println("End a case")
}
event.isDropCompleted = success
event.consume()
}
newButton.setOnAction { event -> handleNew(event,itemTable) }
primaryStage.scene = scene
primaryStage.show()
}
private fun handleNew(e: ActionEvent, itemTable: TableView<Item>) {
val groupIDSet: SortedSet<Int> = sortedSetOf()
for (anItem in itemTable.items) {
if (anItem.isSelected)
println(anItem.getName())
else
groupIDSet.add(anItem.getGroupID())
}
var newID = 0
for ( idx in groupIDSet ) {
if (newID < idx) break
newID++
}
for (anItem in itemTable.items) {
if (anItem.isSelected)
anItem.setGroupID(newID)
// TODO: [BUG] This does not update GUI
anItem.isSelected = false
}
}
}
util / CheckBoxColumn.kt
package util
// Read from https://takeda-san.hatenablog.com/entry/2017/07/25/232840
import Item
import javafx.beans.property.SimpleBooleanProperty
import javafx.event.Event
import javafx.scene.control.TableColumn
import javafx.scene.control.cell.CheckBoxTableCell
import javafx.scene.control.cell.PropertyValueFactory
import javafx.scene.input.MouseButton
import javafx.scene.input.MouseEvent
class CheckBoxColumn : TableColumn<Item, Boolean>() {
init {
this.cellValueFactory = PropertyValueFactory<Item, Boolean>("select")
this.setCellFactory { column ->
val cell = CheckBoxTableCell<Item, Boolean> { index ->
val selected = SimpleBooleanProperty(
this.tableView.items[index].isSelected
)
selected.addListener { _, _, n ->
this.tableView.items[index].isSelected = n
this.tableView.selectionModel.select(index)
Event.fireEvent(
column.tableView, MouseEvent(
MouseEvent.MOUSE_CLICKED, 0.0, 0.0, 0.0, 0.0,
MouseButton.PRIMARY, 1, true, true, true, true, true, true, true, true, true, true, null
)
)
}
selected
}
cell
}
}
}
Tab.fxml
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Rectangle?>
<?import util.CheckBoxColumn?>
<AnchorPane prefHeight="800.0" prefWidth="1600.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TabPane prefHeight="800.0" prefWidth="1600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs>
<Tab text="Session #1">
<content>
<AnchorPane fx:id="TabSession1" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="TableView1" editable="true" layoutX="16.0" layoutY="16.0" prefHeight="313.0" prefWidth="565.0" AnchorPane.bottomAnchor="64.0" AnchorPane.leftAnchor="16.0" AnchorPane.rightAnchor="16.0" AnchorPane.topAnchor="16.0">
<columns>
<CheckBoxColumn minWidth="64.0" text="Check" />
<TableColumn minWidth="64.0" text="Group ID">
<cellValueFactory>
<PropertyValueFactory property="groupID" />
</cellValueFactory>
</TableColumn>
<TableColumn prefWidth="256.0" text="Name">
<cellValueFactory>
<PropertyValueFactory property="name" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
<Button fx:id="NewButton" layoutX="16.0" layoutY="384.0" mnemonicParsing="false" text="Make New" AnchorPane.bottomAnchor="16.0" AnchorPane.leftAnchor="16.0" />
<Button fx:id="GoButton" layoutX="1543.0" layoutY="731.0" mnemonicParsing="false" text="Go" AnchorPane.bottomAnchor="16.0" AnchorPane.rightAnchor="16.0" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab text="Session #2">
<content>
<AnchorPane fx:id="TabSession2" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<Rectangle fx:id="StatusIndicator" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="32.0" layoutX="100.0" layoutY="10.0" stroke="BLACK" strokeType="INSIDE" width="256.0" AnchorPane.leftAnchor="16.0" AnchorPane.topAnchor="16.0" />
<Label fx:id="FilePathsLabel" layoutX="100.0" layoutY="60.0" text="Nothing" AnchorPane.leftAnchor="16.0" AnchorPane.topAnchor="64.0" />
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>