2014-11-06 49 views
-1

我在使用javafx選項卡時遇到了一些問題。我需要在新表上獲取附加對象,即BillingTable類。我希望將它分配到字段表,但是我不斷收到一個異常,告訴我該轉換不起作用。選項卡存儲在帶名稱選項卡的tabPane中。這裏是我的代碼:將對象連接到javafx選項卡

tabs.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() { 
      @Override 
      public void changed(ObservableValue<? extends Tab> ov, Tab oldTab, Tab newTab) { 
       System.out.println("Tab Selection changed"); 
       TreeTableView<BillingTable> treeTableView = (TreeTableView<BillingTable>) newTab.getContent(); 
       table = treeTableView.getRoot().getValue(); 
      } 
     }); 

BillingTable類:

public class BillingTable { 

private TreeTableView<BillingTableRow> table; 
private TreeItem<BillingTableRow> root; 
private TreeTableColumn<BillingTableRow, String> nameColumn; 
private TreeTableColumn<BillingTableRow, Double> totalColumn; 
private TreeTableColumn<BillingTableRow, Double> dayColumn; 
private TreeTableColumn<BillingTableRow, Double> eveningColumn; 
private TreeTableColumn<BillingTableRow, Double> nightColumn; 
private TreeTableColumn<BillingTableRow, Double> weekendColumn; 
private TreeTableColumn<BillingTableRow, Double> holidayColumn; 
private TreeTableColumn<BillingTableRow, Boolean> billedColumn; 

/** 
* Create a new billing table. 
*/ 
public BillingTable() { 
    initiateTable(); 
} 

/** 
* Add row to the billing table. 
* 
* @return Added row. 
*/ 
public TreeItem<BillingTableRow> addRow(BillingTableRow row) { 
    TreeItem<BillingTableRow> child = new TreeItem<>(row); 
    root.getChildren().add(child); 
    return child; 
} 

/** 
* Add TreeItem to the table root. 
* 
* @param treeItem 
*   TreeItem to add to the root. 
* @return Added row. 
*/ 
public TreeItem<BillingTableRow> addRow(TreeItem<BillingTableRow> treeItem) { 
    root.getChildren().add(treeItem); 
    root.getValue().addChild(treeItem.getValue()); 
    return treeItem; 
} 

/** 
* Add client to the billing table. 
* 
* @param client 
*   Client to add. 
* @return Created row in billing table. 
*/ 
public TreeItem<BillingTableRow> addClient(Client client) { 
    TreeItem<BillingTableRow> row = new TreeItem<>(new BillingTableRow(client)); 
    addRow(row); 
    return row; 
} 

/** 
* Initiate TreeTableView of billing data. 
*/ 
private void initiateTable() { 
    table = new TreeTableView<>(); 

    // Define columns 
    nameColumn = new TreeTableColumn<>("Namn"); 
    totalColumn = new TreeTableColumn<>("Summa"); 
    dayColumn = new TreeTableColumn<>("Dag"); 
    eveningColumn = new TreeTableColumn<>("Kväll"); 
    nightColumn = new TreeTableColumn<>("Natt"); 
    weekendColumn = new TreeTableColumn<>("Helg"); 
    holidayColumn = new TreeTableColumn<>("Storhelg"); 
    billedColumn = new TreeTableColumn<>("Faktureras"); 

    // Change column sizing 
    nameColumn.setPrefWidth(150); 
    totalColumn.setPrefWidth(60); 
    dayColumn.setPrefWidth(60); 
    eveningColumn.setPrefWidth(60); 
    nightColumn.setPrefWidth(60); 
    weekendColumn.setPrefWidth(60); 
    holidayColumn.setPrefWidth(60); 
    billedColumn.setPrefWidth(80); 

    // Bind columns to variables 
    nameColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("name")); 
    totalColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("timeTotal")); 
    dayColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("timeDay")); 
    eveningColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("timeEvening")); 
    nightColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("timeNight")); 
    weekendColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("timeWeekend")); 
    holidayColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("timeHoliday")); 
    billedColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("billed")); 

    // Make cells editable for all columns 
    makeEditableCells(); 

    // Add columns to table 
    table.getColumns().add(nameColumn); 
    table.getColumns().add(totalColumn); 
    table.getColumns().add(dayColumn); 
    table.getColumns().add(eveningColumn); 
    table.getColumns().add(nightColumn); 
    table.getColumns().add(weekendColumn); 
    table.getColumns().add(holidayColumn); 
    table.getColumns().add(billedColumn); 

    root = new TreeItem<BillingTableRow>(new BillingTableRow("Root")); 
    root.setExpanded(true); 

    table.setRoot(root); 
    table.setShowRoot(false); 
    table.setTableMenuButtonVisible(true); 

} 
... 

和異常:

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: gui.BillingTableRow cannot be cast to gui.BillingTable 
at application.Main$1.changed(Main.java:136) 
at application.Main$1.changed(Main.java:1) 
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(Unknown Source) 
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(Unknown Source) 
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(Unknown Source) 
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(Unknown Source) 
at javafx.beans.property.ObjectPropertyBase.markInvalid(Unknown Source) 
at javafx.beans.property.ObjectPropertyBase.set(Unknown Source) 
at javafx.scene.control.SelectionModel.setSelectedItem(Unknown Source) 
at javafx.scene.control.TabPane$TabPaneSelectionModel.select(Unknown Source) 
at javafx.scene.control.TabPane$TabPaneSelectionModel.select(Unknown Source) 
at javafx.scene.control.TabPane$TabPaneSelectionModel.findNearestAvailableTab(Unknown Source) 
at javafx.scene.control.TabPane$TabPaneSelectionModel.lambda$new$17(Unknown Source) 
at javafx.scene.control.TabPane$TabPaneSelectionModel$$Lambda$66/1951002621.onChanged(Unknown Source) 
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(Unknown Source) 
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(Unknown Source) 
at javafx.collections.ObservableListBase.fireChange(Unknown Source) 
at javafx.collections.ListChangeBuilder.commit(Unknown Source) 
at javafx.collections.ListChangeBuilder.endChange(Unknown Source) 
at javafx.collections.ObservableListBase.endChange(Unknown Source) 
at javafx.collections.ModifiableObservableListBase.add(Unknown Source) 
at java.util.AbstractList.add(Unknown Source) 
at application.Main.addTab(Main.java:705) 
at application.Main.start(Main.java:142) 
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(Unknown Source) 
at com.sun.javafx.application.LauncherImpl$$Lambda$69/1795971577.run(Unknown Source) 
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(Unknown Source) 
at com.sun.javafx.application.PlatformImpl$$Lambda$45/1051754451.run(Unknown Source) 
at com.sun.javafx.application.PlatformImpl.lambda$null$164(Unknown Source) 
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1600778379.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(Unknown Source) 
at com.sun.javafx.application.PlatformImpl$$Lambda$46/1775282465.run(Unknown Source) 
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) 
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source) 
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 
+0

顯示您定義和添加選項卡的代碼。顯示「表」變量的定義。 – 2014-11-06 15:43:38

+0

另外我想說明你在哪裏定義了「TreeTableView」及其根元素......我認爲根元素的值不是正確的運行時類型。如果你在任何地方有任何編譯器警告(特別是關於原始類型),那是第一個看的地方。 – 2014-11-06 15:57:25

+0

請顯示證明問題的SSCCE。不這樣做需要浪費猜測(正如你在答案中看到的那樣;-)直到添加示例爲止的downvoting。 – kleopatra 2014-11-07 10:32:31

回答

0

一種當您發佈涉及異常問題懇求:

你能不能總是指示中的哪一行代碼產生的異常?堆棧跟蹤告訴我們它是第136行,但無法知道您發佈的代碼段中的哪一行是136。

我要去只是做一個猜測約該行產生異常的投郵件實際上是

table = treeTableView.getRoot().getValue(); 

(而不是與明確的投行)。

如果你有一個TreeTableView<BillingTable>,那麼它的根是一個TreeItem<BillingTable>。所以treeTableView.getRoot()返回一個TreeItem<BillingTable>和調用getValue()上返回BillingTable,這可能是table(否則它不會編譯)的類型。

錯誤消息顯示,在運行時,評估treeTableView.getRoot().getValue()實際上是返回BillingTableRow類型的對象,而不是預期的開票表。

這可能發生的唯一方法是如果您在初始化的某處使用原始類型。參數化類型在運行時基本上不會被記住(「類型擦除」),所以類型檢查是所有編譯器檢查。如果使用原始類型,編譯器將允許您在TreeItem中放置錯誤類型的對象,或在TreeTableView中放置錯誤類型的TreeItem

所以在初始化過程中的某個地方,你做了一件沿着

TreeTableView<BillingTable> treeTableView = new TreeTableView<>(); 
TreeItem root = new TreeItem(someBillingTableRow); 
treeTableView.setRoot(root); 

行或者你做

TreeTableView treeTableView = new TreeTableView(); 
TreeItem<BillingTableRow> root = new TreeItem<>(someBillingTableRow); 
treeTableView.setRoot(root); 

這是錯誤的,因爲,在這兩種情況下,你要設置的根樹表格視圖轉換爲具有BillingTableRow作爲值的樹項目,而不是BillingTable

如果你做的一切提供正確的類型,那麼你避免這些問題(我的意思是,你會得到一個編譯錯誤,而不是運行時錯誤,這是很容易解決):

TreeTableView<BillingTable> treeTableView = new TreeTableView(); 
TreeItem<BillingTable> root = new TreeItem<>(...); 
treeTableView.setRoot(root); 

編譯器現在強制執行,無論您傳遞給構造函數TreeItem是什麼類型。

編輯

當然,如果你的TreeTableView真的是TreeTableView<BillingTableRow>那麼你做

TreeTableView<BillingTableRow> treeTableView = new TreeTableView(); 
TreeItem<BillingTableRow> root = new TreeItem<>(...); 
treeTableView.setRoot(root); 

然後在TreeTableView根值是BillingTableRow,所以你解決您的代碼相應地:

BillingTableRow table ; 

tabs.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() { 
      @Override 
      public void changed(ObservableValue<? extends Tab> ov, Tab oldTab, Tab newTab) { 
       System.out.println("Tab Selection changed"); 
       TreeTableView<BillingTableRow> treeTableView = (TreeTableView<BillingTableRow>) newTab.getContent(); 
       table = treeTableView.getRoot().getValue(); 
      } 
     }); 
+0

問題在於,BillingTable中的所有內容都使用BillingTableRow,這意味着我使用'TreeTableView 表;'在其中設置我的表。我已經爲課程添加了一些代碼。 – 2014-11-06 21:13:00

+0

然後你需要在你的處理程序中做正確的downcast。如果'TreeTableView'是一個'TreeTableView ',那麼你可以下調它,當你從根節點獲取值時,將它賦值給'BillingTableRow'。 (請參閱更新後的答案。)「TreeTableView」中的值只是一種類型,只需決定它們是什麼並堅持。 – 2014-11-06 21:24:49

+0

因此,我不能使用不同的類來攜帶數據並將它們呈現爲表格? – 2014-11-06 21:27:03

0

必須爲所有標籤setContent(TreeTableView) 和所有TreeTableView在標籤setRoot( TreeItem); 我希望是解決方案。

你可以看到這個例子的代碼工作:

table=new BillingTable(); 


    TabPane tabs=new TabPane(); 
    tabs.setPrefWidth(400); 
    tabs.setPrefHeight(400); 

    Tab tab = new Tab(); 
    tab.setText("Tab1"); 
    Tab tab1 = new Tab(); 
    tab1.setText("Tab2"); 
    Tab tab2 = new Tab(); 
    tab2.setText("Tab3"); 
    tabs.getTabs().add(tab); 
    tabs.getTabs().add(tab1); 
    tabs.getTabs().add(tab2); 
    TreeTableView<BillingTable> tt=new TreeTableView<BillingTable>(); 

    tt.getColumns().add(new TreeTableColumn<BillingTable,String>(){}); 

    tt.setRoot(new TreeItem<BillingTable>()); 


    tab.setContent(tt); 
    tab1.setContent(tt); 
    tab2.setContent(tt); 

    tabs.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() { 
     @Override 
     public void changed(ObservableValue<? extends Tab> ov, Tab oldTab, Tab newTab) { 
      System.out.println("Tab Selection changed"); 

      TreeTableView<BillingTable> treeTableView = (TreeTableView<BillingTable>) newTab.getContent(); 

      table = treeTableView.getRoot().getValue(); 
     } 
    }); 
+0

會嘗試。我希望它能起作用。 – 2014-11-06 13:09:50

+0

它沒有工作。問題沒有解決。你的代碼中的 – 2014-11-06 15:22:31

+0

我想知道表instanceof?和標籤instanceof? – Mailkov 2014-11-06 15:33:47