2014-04-03 246 views
0

我目前正试图从一个解码的视频到的TableView行添加一些图像,他们没有出现。只有空的TableColumns。 TableView已经在JavaFx Scene Builder中与Label一起设计。插入图片到TableView中的JavaFX - 图片不显示

这里就是我有这么远:

public class MainScreenController implements Initializable { 

@FXML 
private Label previewBoxLabel; 

@FXML 
private TableView tableView; 

private ObservableList<ImageView> imageList = FXCollections.observableArrayList(); 

@FXML 
public void AddClipBeta(){ 

    //Code which uses an external class in order to decode video (Variables Frames, width and height are not shown but are present in the actual code) 
    VideoSegment clip = new VideoSegment(0, file.getPath(), 0, Frames, width, height); 

//Opens the file in decoding class - ready to output frames   
    try{clip.openFile();} catch(Exception e){} 

//First frame is updated on the preview box 
    previewBoxLabel.setGraphic(new ImageView(convertToFxImage(clip.getThumbnail()))); 


    System.out.println(file.getPath()); 
    int i =0; 

//While loop in test phase to see whether or not 10 frames will be visible in the table 
    while(i != 10){ 

    //Creates and sets columns to tableView 
     TableColumn<ImageView, ImageView> col = new TableColumn<ImageView, ImageView>(); 
     col.setPrefWidth(100); //Set width of column 
     tableView.getColumns().add(col); 

     col.setCellFactory(new Callback<TableColumn<ImageView, ImageView>, TableCell<ImageView, ImageView>>() { 

      @Override 
      public TableCell<ImageView, ImageView> call(TableColumn<ImageView, ImageView> p) { 


        TableCell<ImageView, ImageView> cell = new TableCell<ImageView, ImageView>(){ 
        }; 

        return cell; 
      } 


     }); 

    //Adds current frame to list 
     imageList.add(new ImageView(convertToFxImage(clip.getThumbnail()))); 

    //Gets next video frame 
     try{clip.getNextFrame();} catch(Exception e){} 

    //Updates counter 
     i++; 
    } 

//Sets list of frames on the table 
    tableView.setItems(imageList); 


} 

// There is a problem with this implementation: transparent pixels on the BufferedImage aren't converted to transparent pixels on the fxImage. 
public static javafx.scene.image.Image convertToFxImage(java.awt.image.BufferedImage awtImage) { 
    if (Image.impl_isExternalFormatSupported(BufferedImage.class)) { 
     return javafx.scene.image.Image.impl_fromExternalImage(awtImage); 
    } else { 
     return null; 
    } 
} 

我一直在努力了解的TableView如何工作的最后几天,这将是一个真正的突破,如果我们能得到的这条底线。

感谢您的阅读和提前任何帮助!

+0

看一看教程。从[ListView]开始(http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/list-view.htm#CEGGEDBF),这很简单,但例12-4会给你一个了解细胞如何工作。那么也许通过[TableView中](http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/table-view.htm#CJAGAAEE)教程读取。 –

+0

会做!希望我可以得到这个结果。 – Mally

回答

0

我设法与你们的帮助排序了这一点。基本上,我所做的是使一个类与一群getter和setter方法的以及发生在ImageViews并将它设置为一个变量,它通过的构造函数类的构造。然后,我回到我的代码,增加了以下内容:

类具有getter和setter:

import javafx.scene.image.ImageView; 


public class tableDataModel { 

private ImageView image; 

public tableDataModel(ImageView image){ 
    this.image = image; 
} 

public ImageView getImage(){ 
    return image; 
} 

public void setImage(ImageView image){ 
    this.image = image; 
} 

}

代码从MainScreenController:

TableColumn<tableDataModel, ImageView> col = new TableColumn<>(); 
    tableView.getColumns().add(col); 
    imageList.add(new tableDataModel(new ImageView(convertToFxImage(clip.getThumbnail())))); 
col.setPrefWidth(50); 
    col.setCellValueFactory(new PropertyValueFactory<tableDataModel, ImageView>("image")); 

    int i = 0; 
    while (i != 10) { 



    try { 
      imageList.add(new tableDataModel(new ImageView(convertToFxImage(clip.getNextFrame())))); 
     } catch (Exception e) { 
     } 
     i++; 
} 
tableView.setItems(imageList); 
0

当设置CellFactory,你需要采取在考虑,它会覆盖一些默认bevaiours如设置文本和图像。

例如。我必须创建一个ListViewApplication s,双击启动。我必须设置一个CellFactory以便为每个单独的单元格的鼠标单击添加一个监听器。

applications.setCellFactory(new Callback<TreeView<Application>, TreeCell<Application>>() { 

     @Override 
     public TreeCell<Application> call(TreeView<Application> param) { 
      return new TreeCell<Application>() { 

       @Override 
       protected void updateItem(Application item, boolean empty) { 
        //call the origional update first 
        super.updateItem(item, empty); 
        //the root item in my list is null, this check is required to keep a null pointer from happening 
        if (item != null) { 
         // text and graphic are stored in the Application object and set. 
         this.setText(item.getApplicationListName()); 
         this.setGraphic(item.getGraphic()); 

         // registers the mouse event to the cell. 
         this.setOnMouseClicked((MouseEvent e) -> { 
          if (e.getClickCount() == 2) { 
           try { 
            this.getItem().launch(tabBar); 
           } catch (UnsupportedOperationException ex) { 
            Dialogs.create().nativeTitleBar().masthead("Comming Soon™").message("Application is still in development and will be available Soon™").nativeTitleBar().title("Unavailable").showInformation(); 
           } 
          } else { 
           e.consume(); 
          } 

         }); 
        }else if(empty){ 
         this.setText(null); 
         this.setGraphic(null); 
         this.setOnMouseClicked(null); 
        } 
       } 
      }; 
     } 
    }); 

这是从一些其他代码拼凑在一起,所以如果有什么你想要解释,让我知道!

+0

我了解你的代码,但我遇到的问题实际上是将内容添加到单元格中。我是否需要用getter和setter创建一个类并将其引用到表,列表和单元格? – Mally

+0

您需要将数据从其演示文稿中分离出来。如果您的TableView的数据类型是某种类型的节点(在您的情况下为ImageView),那几乎总是一个错误。首先找出你在每一行中呈现的数据类型,然后根据相应的行数据找出每列将显示的数据。这是你的cellValueFactory。然后弄清楚如何将这些数据实际呈现给单元中的用户。这是你的cellFactory。 –

+0

@James_D是对的。我想说,如果你不想在表中出现某个节点出于某种原因,最好的办法是用getter和setter来创建某种包装类,而不是直接使用该节点类型。 另外,'CellValueFactory'和'CellFactory'是两个完全不同的野兽,具体取决于你想要做什么。 'CellFactory'可以让你重载它自己的单元格的默认背景。 'CellValueFactory'可以让你定义一个特定的表格属性,该表格是用来显示在该单元格中的。 'Cell Factory'可以让你改变单元格的行为。 – LinkXXI