我正在尝试在JavaFX中创建一个可编辑的TableView,显示存储在自定义类StocktingLocation中的各种值。其中一些值是字符串,而另一些是各种数值数据类型(短整型、整型、双精度型),并且某些字符串具有与之关联的特定必需格式。我正在使用类似于以下代码块的东西来定义每个表列,使用SortStringConverter()或类似的东西来获取文本输入并将其转换为目标数据类型:
TableColumn<InventoryLocation,Short> CabinetColumn = new TableColumn<>("Cabinet");
CabinetColumn.setMinWidth(50);
CabinetColumn.setCellValueFactory(new PropertyValueFactory<>("Cabinet"));
CabinetColumn.setCellFactory(TextFieldTableCell.forTableColumn(new ShortStringConverter()));
但是,我想首先防止用户输入任何无效数据。对于上面的示例,他们应该无法键入任何非数字字符。在我的应用程序的其他地方,在简单的TextFields中,我正在使用这样的东西来对用户输入强制执行正则表达式匹配:
quantity.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
if (!newValue.matches("\\d*")) {
quantity.setText(newValue.replaceAll("[^\\d]", ""));
}
}
});
如何应用类似于可编辑表格视图使用的文本条目?目前,第一个代码块将允许用户写他们喜欢的任何值,如果字符串不能转换为短整型,将抛出一个数字格式异常。我希望代码首先防止他们输入无效的值。
您需要创建自定义表格单元 - 例如:
public class EditableBigDecimalTableCell<T> extends TableCell<T, BigDecimal> {
private TextField textField;
private int minDecimals, maxDecimals;
/**
* This is the default - we will use this as 2 decimal places
*/
public EditableBigDecimalTableCell () {
minDecimals = 2;
maxDecimals = 2;
}
/**
* Used when the cell needs to have a different behavior than 2 decimals
*/
public EditableBigDecimalTableCell (int min, int max) {
minDecimals = min;
maxDecimals = max;
}
@Override
public void startEdit() {
if(editableProperty().get()){
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.requestFocus();
}
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(getItem() != null ? getItem().toPlainString() : null);
setGraphic(null);
}
@Override
public void updateItem(BigDecimal item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
textField.selectAll();
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private void createTextField() {
textField = new TextField();
textField.setTextFormatter(new DecimalTextFormatter(minDecimals, maxDecimals));
textField.setText(getString());
textField.setOnAction(evt -> {
if(textField.getText() != null && !textField.getText().isEmpty()){
NumberStringConverter nsc = new NumberStringConverter();
Number n = nsc.fromString(textField.getText());
commitEdit(BigDecimal.valueOf(n.doubleValue()));
}
});
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyPressed((ke) -> {
if (ke.getCode().equals(KeyCode.ESCAPE)) {
cancelEdit();
}
});
textField.setAlignment(Pos.CENTER_RIGHT);
this.setAlignment(Pos.CENTER_RIGHT);
}
private String getString() {
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMinimumFractionDigits(minDecimals);
nf.setMaximumFractionDigits(maxDecimals);
return getItem() == null ? "" : nf.format(getItem());
}
@Override
public void commitEdit(BigDecimal item) {
if (isEditing()) {
super.commitEdit(item);
} else {
final TableView<T> table = getTableView();
if (table != null) {
TablePosition<T, BigDecimal> position = new TablePosition<T, BigDecimal>(getTableView(),
getTableRow().getIndex(), getTableColumn());
CellEditEvent<T, BigDecimal> editEvent = new CellEditEvent<T, BigDecimal>(table, position,
TableColumn.editCommitEvent(), item);
Event.fireEvent(getTableColumn(), editEvent);
}
updateItem(item, false);
if (table != null) {
table.edit(-1, null);
}
}
}
}
使用格式化程序将阻止不需要的值。
public class DecimalTextFormatter extends TextFormatter<Number> {
private static DecimalFormat format = new DecimalFormat( "#.0;-#.0" );
public DecimalTextFormatter(int minDecimals, int maxDecimals) {
super(
new StringConverter<Number>() {
@Override
public String toString(Number object) {
if(object == null){
return "";
}
String format = "0.";
for (int i = 0; i < maxDecimals; i++) {
if(i < minDecimals ) {
format = format + "0" ;
}else {
format = format + "#" ;
}
}
format = format + ";-" + format;
DecimalFormat df = new DecimalFormat(format);
String formatted = df.format(object);
return formatted;
}
@Override
public Number fromString(String string){
try {
return format.parse(string);
} catch (ParseException e) {
return null;
}
}
},
0,
new UnaryOperator<TextFormatter.Change>() {
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
if ( change.getControlNewText().isEmpty() )
{
return change;
}
ParsePosition parsePosition = new ParsePosition( 0 );
Object object = format.parse( change.getControlNewText(), parsePosition );
if(change.getControlNewText().equals("-")){
return change;
}
if(change.getCaretPosition() == 1){
if(change.getControlNewText().equals(".")){
return change;
}
}
if ( object == null || parsePosition.getIndex() < change.getControlNewText().length() )
{
return null;
}
else
{
int decPos = change.getControlNewText().indexOf(".");
if(decPos > 0){
int numberOfDecimals = change.getControlNewText().substring(decPos+1).length();
if(numberOfDecimals > maxDecimals){
return null;
}
}
return change;
}
}
}
);
}
}
然后在你的专栏中使用它:
numberColumn.setCellFactory(col -> new EditableBigDecimalTableCell<MyDTO>());
在JavaFX 8中,我尝试在将新行添加到表中后编辑单元格,以优化用户体验。 选择了正确的行,但单元不会进入编辑模式。嗯,我很偶然地看到了这种情况,但很难再现。我做错了什么?
我试图在JavaFX中创建一个可编辑的TableView。我从2个连接的表中获取数据,所以我在TableView中使用对象。 我已经将表和列设置为可编辑,,我尝试对列的执行操作(例如,类似于textfield)。 我还没能解决这个问题。 那么,如何使包含对象的单元格可编辑呢?谢谢你的回答
如果找到manager用户,则将表设置为可编辑,并执行以下操作:
我构建了一个用于显示数据的小JavaFX TableView。用户应该能够在桌面视图中编辑数据。问题是:某些字段只允许特定值。如果用户输入了错误的值,则该字段设置为0。 这是我的班级: 所以当我编辑一个tableviewcell并输入“q”(这个值是不允许的)并按Enter时,调试器在上面的catch块中跳转,将观察列表中的特定值设置为0(我可以在调试器中看到这一点,当我展开这个对象时)但是tab
我正在为JavaFX和数据库实践做一个项目(主要是我是初学者),在那里我有一个独特的类,保存音乐会的记录(名称、地点、日期等)。我最初将这些保存在填充表视图的可观察数组列表中。从这里,记录可以被编辑、删除或添加新的。 我现在使用ORMLite和sqlite将这些存储在数据库中。这样我就可以对数据执行过滤(即在特定位置显示所有事件),然后在表上显示。 我的问题是,当我从数据库中读取数据时,我会将其转
在阅读了大量涉及setOnEditCommit的可编辑TableView解决方案后,我今天对Oracle非常生气,这不是正确的方法。 以下是我在挖掘JavaFX源代码后发现的一个更好、更简单的解决方案: