如果重要的话,我正在使用JDK 1.7.0_51。我有以下改编的示例代码来演示我所看到的异常行为。
我以编程方式选择了表中的第0行,然后在0位置插入添加的行。我希望选定的行向下移动一个,但是它会减少两个。另外,当我监视表行的焦点属性时,我发现在添加单行时它会发生很大的变化。当它完成插入时,第2行具有指示选择的深蓝色背景,但第3行具有蓝色突出显示的边框。我不确定那是什么意思。
当表行焦点丢失时,我正在进行数据验证,以便我可以阻止用户离开当前条目,直到它正确形成。但是这种选择和焦点行为导致我的应用程序行为不端。这是我能够创建的最简单的测试用例,显示正在发生的事情。
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TableViewTest extends Application
{
private final TableView< Person > table = new TableView< Person >();
private final ObservableList< Person > data =
FXCollections.observableArrayList(
new Person( "Jacob", "Smith", "jacob.smith@example.com" ),
new Person( "Isabella", "Johnson", "isabella.johnson@example.com" ),
new Person( "Ethan", "Williams", "ethan.williams@example.com" ),
new Person( "Emma", "Jones", "emma.jones@example.com" ),
new Person( "Michael", "Brown", "michael.brown@example.com" ) );
final HBox hb = new HBox();
public static void main( String[] args )
{
launch( args );
}
@Override
public void start( Stage stage )
{
Scene scene = new Scene( new Group() );
stage.setTitle( "Table View Sample" );
stage.setWidth( 450 );
stage.setHeight( 550 );
final Label label = new Label( "Address Book" );
label.setFont( new Font( "Arial", 20 ) );
table.setEditable( true );
table.setRowFactory( getRowFactory() );
TableColumn firstNameCol = new TableColumn( "First Name" );
firstNameCol.setMinWidth( 100 );
firstNameCol.setCellValueFactory(
new PropertyValueFactory< Person, String >( "firstName" ) );
TableColumn lastNameCol = new TableColumn( "Last Name" );
lastNameCol.setMinWidth( 100 );
lastNameCol.setCellValueFactory(
new PropertyValueFactory< Person, String >( "lastName" ) );
TableColumn emailCol = new TableColumn( "Email" );
emailCol.setMinWidth( 200 );
emailCol.setCellValueFactory(
new PropertyValueFactory< Person, String >( "email" ) );
table.setItems( data );
table.getColumns().addAll( firstNameCol, lastNameCol, emailCol );
table.getSelectionModel().select( 0 );
table.getSelectionModel().getSelectedCells().addListener( new ListChangeListener< TablePosition >()
{
@Override
public void onChanged( final ListChangeListener.Change< ? extends TablePosition > c )
{
if ( !c.getList().isEmpty() )
{
for ( TablePosition pos : c.getList() )
{
System.out.println( "Row " + String.valueOf( pos.getRow() ) + " selected" );
}
}
else
{
System.out.println( "Row unselected" );
}
}
} );
final TextField addFirstName = new TextField();
addFirstName.setPromptText( "First Name" );
addFirstName.setMaxWidth( firstNameCol.getPrefWidth() );
final TextField addLastName = new TextField();
addLastName.setMaxWidth( lastNameCol.getPrefWidth() );
addLastName.setPromptText( "Last Name" );
final TextField addEmail = new TextField();
addEmail.setMaxWidth( emailCol.getPrefWidth() );
addEmail.setPromptText( "Email" );
final Button addButton = new Button( "Add" );
addButton.setOnAction( new EventHandler< ActionEvent >()
{
@Override
public void handle( ActionEvent e )
{
data.add( 0, new Person(
addFirstName.getText(),
addLastName.getText(),
addEmail.getText() ) );
addFirstName.clear();
addLastName.clear();
addEmail.clear();
}
} );
hb.getChildren().addAll( addFirstName, addLastName, addEmail, addButton );
hb.setSpacing( 3 );
final VBox vbox = new VBox();
vbox.setSpacing( 5 );
vbox.setPadding( new Insets( 10, 0, 0, 10 ) );
vbox.getChildren().addAll( label, table, hb );
( ( Group ) scene.getRoot() ).getChildren().addAll( vbox );
stage.setScene( scene );
stage.show();
}
private Callback< TableView< Person >, TableRow< Person >> getRowFactory()
{
return new Callback< TableView< Person >, TableRow< Person >>()
{
@Override
public TableRow< Person > call( final TableView< Person > arg0 )
{
return new DataTableRow();
}
};
}
public class DataTableRow extends TableRow< Person >
{
private final ChangeListener< Boolean > focusListener = new ChangeListener< Boolean >()
{
@Override
public void changed( final ObservableValue< ? extends Boolean > unused, final Boolean arg1,
final Boolean focused )
{
System.out.println( "Row " + getIndex() + " Focus: " + focused );
}
};
public DataTableRow()
{
focusedProperty().addListener( this.focusListener );
}
}
public static class Person
{
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person( String fName, String lName, String email )
{
this.firstName = new SimpleStringProperty( fName );
this.lastName = new SimpleStringProperty( lName );
this.email = new SimpleStringProperty( email );
}
public String getFirstName()
{
return firstName.get();
}
public void setFirstName( String fName )
{
firstName.set( fName );
}
public String getLastName()
{
return lastName.get();
}
public void setLastName( String fName )
{
lastName.set( fName );
}
public String getEmail()
{
return email.get();
}
public void setEmail( String fName )
{
email.set( fName );
}
}
}
我从运行它并添加一行得到的输出是:
Row unselected
Row 1 selected
Row 0 Focus: false
Row 1 Focus: true
Row 1 Focus: false
Row 2 Focus: true
Row unselected
Row unselected
Row 2 selected
Row 2 Focus: false
Row 3 Focus: true
Row 3 Focus: true
任何人都可以帮助我了解这里发生了什么以及这是否是正确的行为?
答案 0 :(得分:0)
您使用的是什么IDE?你在IntelliJ上试过吗?当我在IntelliJ中运行您的类时,我没有报告您的焦点问题。我使用的是jdk 8u20。当我去一个新行时,前一行得到去焦点并且新行被聚焦。见下文:
Row 0 Focus: true
Row 0 Focus: false
Row 1 Focus: true
Row 1 selected
Row 1 Focus: false
Row 2 Focus: true
Row 2 selected
Row unselected
Row 3 selected
Row 2 Focus: false
Row 3 Focus: true
Row 3 Focus: false
Row 4 Focus: true
Row 1 Focus: true
Row 4 Focus: false
Row 1 selected
Row 1 Focus: false
Row 5 Focus: true
Row 5 selected
Row 3 Focus: true
Row 5 Focus: false
Row 3 selected
Row 0 Focus: true
Row 3 Focus: false
Row 0 selected
Row 0 Focus: false
Row 1 Focus: true
Row 1 selected
Row 1 Focus: false
Row 2 Focus: true
Row 2 selected
Row 2 Focus: false
Row 3 Focus: true
Row 3 selected
Row 0 Focus: true
Row 3 Focus: false
Row 0 selected