FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]
MacOs Sierra 10.12.4
A DESCRIPTION OF THE PROBLEM :
When a tree node is expanded for the first time, and previously selected node lower down the screen is incorrectly redrawn.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code provided.
Select a node.
Expand a node above it.
Wrong nodes are highlighted.
I have screen prints if you wish to see them.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only one line should be highlighted
ACTUAL -
The correct line has an outline, the node two lines down is highlighted.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.bytezone.bugs;
import java.io.File;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class BugApp extends Application
{
private final BorderPane borderPane = new BorderPane ();
private Parent createContent ()
{
TreeTableView<MyFile> table = new TreeTableView<> ();
MyTreeItem root = new MyTreeItem (new MyFile (new File ("/")));
table.setRoot (root);
table.setShowRoot (false);
TreeTableColumn<MyFile, String> fileNameColumn = new TreeTableColumn<> ("Filename");
TreeTableColumn<MyFile, Long> sizeColumn = new TreeTableColumn<> ("Size");
table.getColumns ().setAll (fileNameColumn, sizeColumn);
fileNameColumn.setCellValueFactory (new TreeItemPropertyValueFactory ("name"));
sizeColumn.setCellValueFactory (new TreeItemPropertyValueFactory ("length"));
borderPane.setCenter (table);
return borderPane;
}
@Override
public void start (Stage primaryStage) throws Exception
{
primaryStage.setTitle ("Bug Application");
primaryStage.setWidth (500);
primaryStage.setScene (new Scene (createContent ()));
primaryStage.show ();
}
public static void main (String[] args)
{
Application.launch (args);
}
}
package com.bytezone.bugs;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
public class MyTreeItem extends TreeItem<MyFile>
{
boolean firstTimeChild = true;
boolean firstTimeLeaf = true;
boolean isLeaf;
public MyTreeItem (MyFile myFile)
{
super (myFile);
}
@Override
public boolean isLeaf ()
{
return !getValue ().isDirectory ();
}
@Override
public ObservableList<TreeItem<MyFile>> getChildren ()
{
if (firstTimeChild)
{
firstTimeChild = false;
super.getChildren ().setAll (buildChildren (this));
}
return super.getChildren ();
}
private ObservableList<TreeItem<MyFile>> buildChildren (MyTreeItem treeItem)
{
ObservableList<TreeItem<MyFile>> children = FXCollections.observableArrayList ();
try (DirectoryStream<Path> directoryStream =
Files.newDirectoryStream (getValue ().getPath ()))
{
for (Path path : directoryStream)
{
File file = path.toFile ();
if (Files.isDirectory (path) && !file.getName ().startsWith ("."))
children.add (new MyTreeItem (new MyFile (file)));
}
}
catch (IOException ex)
{
System.out.println ("oops");
}
return children;
}
}
package com.bytezone.bugs;
import java.io.File;
import java.nio.file.Path;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class MyFile
{
private final File file;
private StringProperty name;
private LongProperty length;
public MyFile (File file)
{
this.file = file;
setName (file.getName ());
setLength (file.length ());
}
public boolean isDirectory ()
{
return file.isDirectory ();
}
public Path getPath ()
{
return file.toPath ();
}
public void setName (String value)
{
nameProperty ().set (value.isEmpty () ? "root" : value);
}
public String getName ()
{
return nameProperty ().get ();
}
public StringProperty nameProperty ()
{
if (name == null)
name = new SimpleStringProperty (this, "name");
return name;
}
public void setLength (long value)
{
lengthProperty ().set (value);
}
public long getLength ()
{
return lengthProperty ().get ();
}
public LongProperty lengthProperty ()
{
if (length == null)
length = new SimpleLongProperty (this, "length");
return length;
}
}
---------- END SOURCE ----------
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]
MacOs Sierra 10.12.4
A DESCRIPTION OF THE PROBLEM :
When a tree node is expanded for the first time, and previously selected node lower down the screen is incorrectly redrawn.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code provided.
Select a node.
Expand a node above it.
Wrong nodes are highlighted.
I have screen prints if you wish to see them.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only one line should be highlighted
ACTUAL -
The correct line has an outline, the node two lines down is highlighted.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.bytezone.bugs;
import java.io.File;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class BugApp extends Application
{
private final BorderPane borderPane = new BorderPane ();
private Parent createContent ()
{
TreeTableView<MyFile> table = new TreeTableView<> ();
MyTreeItem root = new MyTreeItem (new MyFile (new File ("/")));
table.setRoot (root);
table.setShowRoot (false);
TreeTableColumn<MyFile, String> fileNameColumn = new TreeTableColumn<> ("Filename");
TreeTableColumn<MyFile, Long> sizeColumn = new TreeTableColumn<> ("Size");
table.getColumns ().setAll (fileNameColumn, sizeColumn);
fileNameColumn.setCellValueFactory (new TreeItemPropertyValueFactory ("name"));
sizeColumn.setCellValueFactory (new TreeItemPropertyValueFactory ("length"));
borderPane.setCenter (table);
return borderPane;
}
@Override
public void start (Stage primaryStage) throws Exception
{
primaryStage.setTitle ("Bug Application");
primaryStage.setWidth (500);
primaryStage.setScene (new Scene (createContent ()));
primaryStage.show ();
}
public static void main (String[] args)
{
Application.launch (args);
}
}
package com.bytezone.bugs;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
public class MyTreeItem extends TreeItem<MyFile>
{
boolean firstTimeChild = true;
boolean firstTimeLeaf = true;
boolean isLeaf;
public MyTreeItem (MyFile myFile)
{
super (myFile);
}
@Override
public boolean isLeaf ()
{
return !getValue ().isDirectory ();
}
@Override
public ObservableList<TreeItem<MyFile>> getChildren ()
{
if (firstTimeChild)
{
firstTimeChild = false;
super.getChildren ().setAll (buildChildren (this));
}
return super.getChildren ();
}
private ObservableList<TreeItem<MyFile>> buildChildren (MyTreeItem treeItem)
{
ObservableList<TreeItem<MyFile>> children = FXCollections.observableArrayList ();
try (DirectoryStream<Path> directoryStream =
Files.newDirectoryStream (getValue ().getPath ()))
{
for (Path path : directoryStream)
{
File file = path.toFile ();
if (Files.isDirectory (path) && !file.getName ().startsWith ("."))
children.add (new MyTreeItem (new MyFile (file)));
}
}
catch (IOException ex)
{
System.out.println ("oops");
}
return children;
}
}
package com.bytezone.bugs;
import java.io.File;
import java.nio.file.Path;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class MyFile
{
private final File file;
private StringProperty name;
private LongProperty length;
public MyFile (File file)
{
this.file = file;
setName (file.getName ());
setLength (file.length ());
}
public boolean isDirectory ()
{
return file.isDirectory ();
}
public Path getPath ()
{
return file.toPath ();
}
public void setName (String value)
{
nameProperty ().set (value.isEmpty () ? "root" : value);
}
public String getName ()
{
return nameProperty ().get ();
}
public StringProperty nameProperty ()
{
if (name == null)
name = new SimpleStringProperty (this, "name");
return name;
}
public void setLength (long value)
{
lengthProperty ().set (value);
}
public long getLength ()
{
return lengthProperty ().get ();
}
public LongProperty lengthProperty ()
{
if (length == null)
length = new SimpleLongProperty (this, "length");
return length;
}
}
---------- END SOURCE ----------