- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Java 8.0 x64、Win7 x64、Clojure、Emacs。
我在 Clojure 中使用 TableView
做一些事情,其中我正在 proxy
ing TableCell
因此我可以在其中呈现和编辑任意内容它。这些值是原子内部映射的字段。代码如下。它利用了大量的实用函数和宏来简化这个过程,但你明白了要点。主要是单元格的图文属性的管理。
有一个键盘处理程序附加到 ComboBox
,因此它知道用户何时按下 ENTER
等。此处理程序在单元格散焦时被删除,因此我们最终不会在对象中有多个处理程序。
在此示例中,我有三列,一列用于字段名称(一个仅显示文本且不可编辑的简单单元格工厂),一列用于值(花式单元格工厂),一列用于类型(简单细胞工厂)。使用一些示例数据的输出如下所示:
当我根据 Value 对表格进行排序时,事情似乎工作正常,如下所示:
通常,当键盘处理程序触发时,它会调用单元格的 commitEdit
函数,该函数会调用其 TableCell
父类(super class) commitEdit
。然后,幕后的 TableView
魔术调用列的 onEditCommit
处理程序,该处理程序实际上将编辑提交到数据库。父类(super class) commitEdit
返回后,单元格的 commitEdit
就没有什么可做的了。单元格的 updateItem
然后由 TableView
自动调用,用单元格的正常内容替换 ComboBox
。
问题
当我根据 Field
列对表格进行排序一次或多次,或者根据 Type
列对表格进行排序两次或更多次 并尝试使用 ComboBox
(在本例中为颜色选择器)编辑内容,需要额外单击才能使 ComboBox
下拉,然后按 ENTER
按键不起作用,具体如下:
原因
在损坏的情况下,TableCell
的父类(super class)似乎会立即返回并且不会调用列的 onCommitEdit
处理程序,单元格的处理程序也不会updateItem
被调用,因此单元格不会呈现回其正常的非编辑状态,即没有 ComboBox
。
奇怪的是这个问题有时也会出现在非颜色的 ComboBox
中(sides
字段有一个 ComboBox
编辑器例如数字)。
那么这是 JavaFX TableView
中的错误吗?还是我做错了什么?
(defn add-handlers!
"Adds common keyboard handler and focus listener to temporary editing graphic.
graphic is typically textfield or combo-box. cell is tablecell which
is being edited. getterfn is function to get value from graphic so
it can be commited to database."
[graphic cell getterfn]
(let [focus-listener (make-focus-change-listener cell getterfn)]
(println "adding focus and keyboard listener")
(add-listener! graphic :focused focus-listener)
(.setOnKeyPressed graphic (eventhandler [e] ;; here "cell" still refers to the tablecell
(condp = (.getCode e)
KeyCode/ENTER (do (println "ENTER pressed. Removing focus listener")
(remove-listener! graphic :focused focus-listener) ;; Prevent double-commit on defocus
(.commitEdit cell (getterfn)))
KeyCode/ESCAPE (do (println "ESC pressed. Removing focus listener")
(remove-listener! graphic :focused focus-listener) ;; Prevent double-commit on defocus
(.cancelEdit cell)) ;; Removes textfield
KeyCode/TAB (let [index (.. cell getTableRow getIndex)
next-column (get-next-column cell (not (.isShiftDown e)))]
(println "TAB pressed. Removing focus listener")
(remove-listener! graphic :focused focus-listener) ;; Prevent double-commit on defocus
(.commitEdit cell (getterfn))
(.edit (.getTableView cell) index next-column))
nil))))) ;; do nothing
(defn make-combobox
"Implements dropdown combobox. 'cell' is fancy table cell in
question. 'items' is list of things for dropdown, which can be
anything that the dropdown can render and choose as the final item"
[cell initvalue & [items]]
(let [cmb (jfxnode ComboBox (observable items))
cell-factory FANCY-LISTCELL-FACTORY
blank-cell (.call cell-factory nil)]
(doto cmb
(add-handlers! cell #(.getValue cmb))
(.setValue initvalue)
(.setButtonCell blank-cell)
(.setCellFactory cell-factory))))
(defn render-cell-with-item!
"Puts correct item in cell graphic and/or text property based on item
type. Additional arguments for editing such as drop-down, are
handled in the startEdit function; this function just renders the
cell when called by updateItem or cancelEdit."
[cell item]
(cond
(instance? Node item) (set-graphic-text! cell item nil) ;; for a graphic/Node item
(instance? Boolean item) (let [[var full-accesspath] (calc-full-accesspath cell)
cb (jfxnode CheckBox
:text (str item)
:selected item
:disable (not (mutable? var)))]
(.setEditable cell false)
(set-graphic-text! cell cb nil)
(when (mutable? var)
(uni-bind! (.selectedProperty cb) var full-accesspath)))
(instance? clojure.lang.PersistentVector item) (set-graphic-text! cell (Label. "Put vector editor here") nil)
(instance? Color item) (set-graphic-text! cell (make-color-box item) (color-map-inverse item))
;; All other types go here, presumably text types, so assume editable
:else (set-graphic-text! cell nil (si/to-normstr item)))) ;; else set underlying text
(def FANCY-TABLECELL-FACTORY
"The main callback interface which constructs the actual each cell
for arbitrary types. Assumes an editable cell for text representations."
(callback [column]
(proxy [TableCell] []
(updateItem [item empty]
(proxy-super updateItem item empty)
(when (not empty)
(render-cell-with-item! this item)))
(startEdit []
(proxy-super startEdit)
;; Change to appropriate graphic when editing
(println "in proxy's startEdit. Column commitHandler is" (.getOnEditCommit column))
(let [item (apply access-db (calc-full-accesspath this))
options (get-field-options this)] ;; could be nil ...
(if-let [combo-items (:combo-items options)] ;; ... so put as argument to :combo-items
(let [cmb (make-combobox this item combo-items)]
(set-graphic-text! this cmb nil)
(.requestFocus cmb)
(.show cmb)) ;; This makes drop-down appear without clicking twice.
(when (textish? item)
(let [tf (make-textfield-editor this)]
(set-graphic-text! this tf nil) ;; just set tf as graphic; leave existing text alone
(.requestFocus tf)
(.selectAll tf))))))
(cancelEdit []
;; CancelEdit gets called either by defocus or by ESC.
;; In any case, use the item currently in the database
;; for this cell and just render as in updateItem
(proxy-super cancelEdit)
(let [item (apply access-db (calc-full-accesspath this))]
(render-cell-with-item! this item)))
(commitEdit [value]
;; Nothing to do here. All commits happen either in the textField callback or in the column edit callback
(println "in cell's commitEdit, before super")
(proxy-super commitEdit value)
(println "in cell's commitEdit, after super")))))
(defn inner-table-view*
"Make inner table view for use by inspector-view and table-view"
[var accesspath columns]
(let [obslist (observable (var-snapshot var accesspath))]
(jfxnode TableView
:user-data {:var var ;; the actual var...
:accesspath accesspath } ;; ... and how to get to the displayed data
:items obslist
:columns columns
:editable (mutable? var))))
(defn inspector-view
"Takes plain map or atom/var/ref/agent of map and displays fields
and values in JFX TableView. Compound values (ie maps, vectors,
etc., for now are just displayed as their string value. If access
is supplied, assumes m is var/ref/atom and assigns appropriate
linkage between m and view contents. The topmost available var or
map is assigned to the TableView, and the accessor for each field is
assigned to each column."
[var & {:keys [accesspath field-options]}]
(let [ismutable (mutable? var)
field-col (jfxnode TableColumn "Field"
:cell-value-factory CELL-VALUE-FACTORY
:cell-factory SIMPLE-TABLECELL-FACTORY
:user-data {:accessfn key } ;; label-only option not relevant yet
:editable false
:sortable true)
value-col (jfxnode TableColumn "Value"
:cell-value-factory CELL-VALUE-FACTORY
:cell-factory FANCY-TABLECELL-FACTORY
:user-data {:accessfn val} ;; val is fn for accessing cell values from data item
:on-edit-start (eventhandler [e] (println "editing column " (.getOldValue e) (.getNewValue e)))
:on-edit-cancel (eventhandler [e] (println "canceling column with event" e))
:on-edit-commit (eventhandler [e] (do (println "column's on-edit-commit handler calling column-commit") (column-commit e)))
:editable ismutable
:comparator columnComparator)
type-col (jfxnode TableColumn "Type"
:cell-value-factory CELL-VALUE-FACTORY
:cell-factory SIMPLE-TABLECELL-FACTORY
:user-data {:accessfn #(type (val %))}
:editable false
:sortable true)
cols [field-col value-col type-col]
tv (inner-table-view* var accesspath cols)]
;; Add options to table's userData. This is for inspector-view
;; not table-view, so we don't put this in inner-table-view
;; function
(let [userdata (.getUserData tv)
newuserdata (conj userdata {:field-options field-options})]
(.setUserData tv newuserdata))
;; Add watches, use tv instance as key so we can remove it later
;; This gets called each time db is changed.
(if (mutable? var)
(add-watch var tv (fn [k r o n] ;; Key Ref Old New
(println "Inside KRON with new var" n)
;; Capture the existing sort order and type
;; Taken from http://stackoverflow.com/questions/11096353/javafx-re-sorting-a-column-in-a-tableview
(let [sort-order (vec (.getSortOrder tv)) ;; need to remember ObservableList<TableColumn> and vectorize or it gets reset from underneath us
sort-types (map #(.getSortType %) sort-order)
sortables (map #(.isSortable %) sort-order)]
;; Here we actually put the items into the tableview after the change
(.setItems tv (observable (var-snapshot var accesspath)))
;; Sort order is now empty up so we put back what was in it
(let [new-sort-order (.getSortOrder tv)] ;; get ObservableList<TableColumn>
(.setAll new-sort-order (into-array sort-order)) ;; reset the sort order based on what was there before
;; Assign sorting to each column
(doseq [col sort-order, sort-type sort-types, sortable sortables]
(.setSortType col sort-type)
(.setSortable col sortable)))))))
tv))
最佳答案
我发现了问题,这当然是在我的代码中。
因为 JFX 重用单元格,所以即使在单元格中呈现不同的内容时,单元格的 editable
属性仍然存在。在我的例子中,我的数据库中有一个 bool 值成员,我将其呈现为一个复选框。复选框本身是可点击的,但呈现它的单元格不可编辑。当此单元格在使用不同项目排序后重新呈现时,非编辑状态持续存在并搞砸了新项目的编辑,这不知何故导致下拉框无法正常消失。实际上这个错误也出现在非组合框项目中,例如文本编辑等。
因此解决方案是为呈现的每个项目类型显式设置单元格的可编辑属性。
关于combobox - JavaFX 8.0 TableView 是否存在排序错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31888184/
我正在尝试对每个条目有多个值的关联数组进行排序。 例如 [0] => stdClass Object ( [type] => node [sid] => 158 [score] => 0.059600
我在 mysql 中有“日期”列以这种格式保存日期 2014 年 9 月 17 日(日-月-年) 我需要对它们进行升序排序,所以我使用了这个命令: SELECT * FROM table ORDER
我目前正在将 MySQL 存储过程重写为 MS SQL 存储过程,但遇到了问题。 在 MySQL 存储过程中,有一个游标,它根据最近的日期 (effdate) 选择一个值并将其放入变量 (thestt
我想要 gwt r.QuestionId- 排序。但是我得到未排序的 QuestionId 尽管我提到了 QuestionId ASC 的顺序。 SELECT r.QuestionId,
我有一个关于在 scandir 函数中排序的基本问题。到目前为止,我阅读了 POSIX readdir 的手册页,但没有找到有关订购保证的具体信息。 但是当我遍历大目录(无法更改,只读)时,我在多个系
基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。 正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非
我有两张 table 。想象第一个是一个目录,包含很多文件(第二个表)。 第二个表(文件)包含修改日期。 现在,我想选择所有目录并按修改日期 ASC 对它们进行排序(因此,最新的修改最上面)。我不想显
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
在 C++ 中,我必须实现一个“类似 Excel/Access”(引用)的查询生成器,以允许对数据集进行自定义排序。如果您在 Excel 中使用查询构建器或 SQL 中的“ORDER BY a, b,
我面临这样的挑战: 检索按字段 A 排序的文档 如果字段 B 存在/不为空 . 否则 按字段排序 C. 在 SQL 世界中,我会做两个查询并创建一个 UNION SELECT,但我不知道如何从 Mon
我想对源列表执行以下操作: map 列表 排序 折叠 排序 展开 列表 其中一些方法(例如map和toList)是可链接的,因为它们返回非空对象。但是,sort 方法返回 void,因为它对 List
我制作了一个用于分析 Windows 日志消息编号的脚本。 uniq -c 数字的输出很难预测,因为根据数字的大小会有不同的空白。此时,我手动删除了空白。 这是对消息进行排序和计数的命令: cat n
我有以下词典: mydict1 = {1: 11, 2: 4, 5: 1, 6: 1} mydict2 = {1: 1, 5: 1} 对于它们中的每一个,我想首先按值(降序)排序,然后按键(升序)排序
我刚刚开始使用泛型,目前在对多个字段进行排序时遇到问题。 案例: 我有一个 PeopleList 作为 TObjectList我希望能够通过一次选择一个排序字段,但尽可能保留以前的排序来制作类似 Ex
有没有办法在 sql 中组合 ORDER BY 和 IS NULL 以便我可以在列不为空时按列排序,但如果它为null,按另一列排序? 最佳答案 类似于: ORDER BY CASE WHEN
我有一个包含 2 列“id”和“name”的表。 id 是常规的自动增量索引,name 只是 varchar。 id name 1 john 2 mary 3 pop 4 mary 5 j
场景 网站页面有一个带有分页、过滤、排序功能的表格 View 。 表中的数据是从REST API服务器获取的,数据包含数百万条记录。 数据库 REST API 服务器 Web 服务器 浏览器 问
假设我有一本字典,其中的键(单词)和值(分数)如下: GOD 8 DONG 16 DOG 8 XI 21 我想创建一个字典键(单词)的 NSArray,首先按分数排序,然后按字
如何在 sphinx 上通过 sql 命令选择前 20 行按标题 WEIGHT 排序,接下来 20 行按标题 ASC 排序(总共 40 个结果),但不要给出重复的标题输出。 我尝试了这个 sql 命令
我有一个奇怪的问题,当从 SQLite 数据库中选择信息并根据日期排序时,返回的结果无效。 我的SQL语句是这样的: Select pk from usersDates order by dateti
我是一名优秀的程序员,十分优秀!