带有自定义ListCell的javafx ListView中的Ghost项

时间:2016-07-20 14:05:48

标签: java javafx

我尝试使用自定义ListCell在ListView中查看自定义对象。作为演示问题的示例,我选择了java.util.File。同样出于演示目的,我在渲染时直接禁用ListCell。这些项目由线程模拟的外部进程添加。一切看起来都不错,直到我将CSS着色为禁用的ListCell。现在似乎有一些鬼项与它们被创建的ListCell一起被禁用。

我该如何解决这个问题?

  

App.java

public class App extends Application
{
    @Override
    public void start( Stage primaryStage )
    {   
        final ListView<File> listView = new ListView<>();
        listView.setCellFactory( column -> { 
            return new ListCell<File>()
            {
                protected void updateItem( File item, boolean empty )
                {   
                    super.updateItem( item, empty );

                    if( item == null || empty )
                    {
                        setGraphic( null );
                        return;
                    }

                    setDisable( true );                 
                    setGraphic( new TextField( item.getName() ) );
                }
            };
        });

        new Thread( () -> {
            for( int i=0 ; i<10 ; ++i )
            {
                try
                {
                    Thread.sleep( 1000 );
                }
                catch( Exception e )
                {
                    e.printStackTrace();
                }
                final int n = i;
                Platform.runLater( () -> {
                    listView.getItems().add( new File( Character.toString( (char)( (int) 'a' + n ) ) ) );
                });
            }       
        }).start();

        Scene scene = new Scene( listView );    
        scene.getStylesheets().add( "app.css" );

        primaryStage.setScene( scene );
        primaryStage.show();
    }

    @Override
    public void stop() throws Exception
    {
        super.stop();
    }

    public static void main( String[] args ) throws Exception
    {       
        launch( args );     
    }
}
  

app.css

.list-cell:disabled {
    -fx-background-color: #ddd;
}

1 个答案:

答案 0 :(得分:2)

您永远不会将disable属性设置回false。您需要为空单元格执行此操作。以下内容可能发生在Cell

  1. 项目已添加到Cell,并且该单元格已停用
  2. 该项目已从Cell移除,Cell变为空,但仍处于停用状态。
  3. 通常,当Cell变为空时,添加项目时对Cell所做的任何更改都应撤消。

    此外,每次将新项目分配给TextField时,都应避免重新创建Cell

    listView.setCellFactory(column -> {
        return new ListCell<File>() {
    
            private final TextField textField = new TextField();
    
            protected void updateItem(File item, boolean empty) {
                super.updateItem(item, empty);
    
                if (item == null || empty) {
                    setDisable(false);
                    setGraphic(null);
                } else {
                    setDisable(true);
                    textField.setText(item.getName());
                    setGraphic(textField);
                }
            }
        };
    });