我在包含两个TableView
的javaFX中创建TableColumns
。 TableView Span的宽度超过了所有TableColumn
的宽度,但它不是问题。我不明白的是当我点击包含数据的行外的区域以及列的外部区域(红色区域)时,我收到错误。谁能解释为什么会出现这种错误?
run:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.handleSelectedCellsListChangeEvent(TableView.java:2657)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2180)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2140)
at com.sun.javafx.scene.control.behavior.TableRowBehavior.doSelect(TableRowBehavior.java:196)
at com.sun.javafx.scene.control.behavior.TableRowBehavior.mousePressed(TableRowBehavior.java:88)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:204)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3689)
at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3414)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1676)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2467)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345)
at com.sun.glass.ui.View.handleMouseEvent(View.java:526)
at com.sun.glass.ui.View.notifyMouse(View.java:898)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
BUILD SUCCESSFUL (total time: 5 seconds)
这是我的代码:(顺便说一下这段代码基于javaFX默认样本,并且在该示例中也会出现错误)
package fjr.java.proyek.tex;
//import java.awt.TextField;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ChangeCurrentFrame extends Application{
double width = 400;
double height = 400;
public void start(Stage stage) throws Exception {
Group root = new Group();
stage.setScene(new Scene (root , width, height));
root.getChildren().add(getTable());
stage.show();
}
public TableView<CurrentFrame > getTable(){
TableView<CurrentFrame> tabel = new TableView<CurrentFrame>();
TableColumn<CurrentFrame, Boolean> stateColumn = new TableColumn<CurrentFrame, Boolean>();
stateColumn.setText("Is Compile");
stateColumn.setMinWidth(60);
stateColumn.setCellValueFactory(new PropertyValueFactory<CurrentFrame, Boolean>("enable")) ;
stateColumn.setCellFactory(new Callback<TableColumn<CurrentFrame, Boolean>,
TableCell<CurrentFrame, Boolean>>(){
@Override
public TableCell<CurrentFrame, Boolean> call(
TableColumn< CurrentFrame, Boolean> p ){
return new TableCell<CurrentFrame, Boolean>(){
private CheckBox checkBox;
private ObservableValue<Boolean> ov;
{
checkBox = new CheckBox();
checkBox.setAlignment(Pos.CENTER);
setAlignment(Pos.CENTER);
setGraphic(checkBox);
}
@Override public void updateItem(Boolean item, boolean empty){
super.updateItem(item, empty);
if(empty){
setText(null);
setGraphic(null);
}else{
setGraphic(checkBox);
if(ov instanceof BooleanProperty){
checkBox.selectedProperty(). unbindBidirectional((BooleanProperty) ov);
}
ov = getTableColumn().getCellObservableValue(getIndex());
if(ov instanceof BooleanProperty){
checkBox.selectedProperty(). bindBidirectional((BooleanProperty) ov);
}
}
}
};
}
});
TableColumn<CurrentFrame, String> nameColumn = new TableColumn<CurrentFrame, String>();
nameColumn.setText("Label");
nameColumn.setMinWidth(80);
nameColumn.setCellValueFactory(new PropertyValueFactory<CurrentFrame, String>("name"));
nameColumn.setCellFactory(new Callback<TableColumn<CurrentFrame, String>,
TableCell<CurrentFrame, String>>() {
@Override
public TableCell<CurrentFrame, String> call(
TableColumn<CurrentFrame, String> arg0) {
return new TableCell<CurrentFrame,String>(){
private TextField textField;
@Override public void startEdit(){
super.startEdit();
if(textField == null){
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
}
@Override public void cancelEdit(){
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override public void updateItem(String item, boolean empty){
super.updateItem(item, empty);
if(empty){
setText(null);
setGraphic(null);
}else{
if(isEditing()){
if(textField != null){
textField.setText(getString());
}
setText(null);
setGraphic(textField);
}else{
setText(getString());
setGraphic(null);
}
}
}
private String getString(){
return getItem() == null ? "" : getItem().toString();
}
private void createTextField(){
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if(t.getCode() == KeyCode.ENTER){
commitEdit(textField.getText());
}else if(t.getCode() == KeyCode.ESCAPE){
cancelEdit();
}
}
});
}
};
}
});
nameColumn.setOnEditCommit(new EventHandler<CellEditEvent<CurrentFrame, String >>() {
@Override
public void handle(CellEditEvent<CurrentFrame, String> t) {
((CurrentFrame) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setName(t.getNewValue());
}
});
tabel.setItems(getData());
tabel.setEditable(true);
tabel.getColumns().addAll(stateColumn, nameColumn);
return tabel ;
}
public ObservableList<CurrentFrame> getData(){
return FXCollections.observableArrayList(
new CurrentFrame(true, "makan"),
new CurrentFrame(false, "siang"),
new CurrentFrame(false, "jangan"),
new CurrentFrame(true, "suka"),
new CurrentFrame(false, "ribut")) ;
}
public static class CurrentFrame { // ini harus publik ya....
private BooleanProperty isEnable;
private StringProperty framename;
private CurrentFrame(boolean enable, String name){
this.isEnable = new SimpleBooleanProperty(enable);
this.framename = new SimpleStringProperty(name);
isEnable.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> arg0,
Boolean t2, Boolean t1) {
System.out.println(nameProperty().get()+" enable "+ t1 );
}
});
}
public void setEnable(boolean state){
isEnable.set(state);
}
public void setName(String name){
this.framename.set(name);
}
public BooleanProperty enableProperty(){
return isEnable;
}
public StringProperty nameProperty(){
return framename;
}
}
public static void main(String[] args){
launch(args);
}
}
答案 0 :(得分:2)
该错误仍然存在于Java 8u11中,但有一种解决方法:
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
这可以防止所有列的区域都可见,因此不再有堆栈跟踪。 这样做的缺点是所有列都将调整大小以适应表格宽度。
答案 1 :(得分:1)
我相信我发现了一个现有的错误报告: