2014-11-06 4 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

Показать код, в котором вы определяете и добавляете вкладки. Покажите определение переменной «table». –

+0

Также я думаю, что вы указали, где вы определили «TreeTableView» и его корневой элемент ... Я думаю, что как-то значение для корневого элемента не соответствует правильному типу времени выполнения. Если у вас есть какие-либо предупреждения о компиляторе где-нибудь (особенно о сырых типах), это первое место для просмотра. –

+0

, пожалуйста, покажите SSCCE, который демонстрирует проблему. Не делать этого требует расточительных догадок (как вы видите в ответах ;-) Downvoting, пока не будет добавлен пример. – kleopatra

ответ

0

Отвод, когда вы размещаете вопросы, которые связаны с исключениями:

Вы можете всегда указать, какие строки в коде, порождающие исключение? Трассировка стека говорит нам, что это строка 136, но нет способа узнать, какая строка - 136 из фрагмента кода, который вы опубликовали.

Я собираюсь просто сделать предположение из сообщения о броске, что линия, генерирующего исключение фактически

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

(а не линия с явным гипсе).

Если у вас есть TreeTableView<BillingTable>, то это корень TreeItem<BillingTable>. Таким образом, treeTableView.getRoot() возвращает TreeItem<BillingTable> и вызывает getValue(), который возвращает BillingTable, который предположительно является типом table (иначе он не будет скомпилирован).

Сообщение об ошибке показывает, что во время выполнения оценка treeTableView.getRoot().getValue() фактически возвращает объект типа BillingTableRow вместо ожидаемой таблицы фактурирования.

Единственный способ, которым это могло случиться, - это использовать исходный тип где-то вдоль инициализации. Параметризированные типы в основном не запоминаются во время выполнения («стирание типа»), поэтому проверки типов - это все проверки компилятора. Если вы используете необработанные типы, компилятор позволит вам поместить неправильный тип объекта в TreeItem или неправильный тип TreeItem в TreeTableView.

Так где-то в процессе инициализации вы сделали что-то вдоль линий

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); 

Это неправильно, потому что в обоих случаях, вы настраиваете корень из tree table view to tree item, который имеет значение BillingTableRow как его значение, а не BillingTable.

Если вы предоставите типов за все правильно, то вам избежать этих проблем (я имею в виду, вы получите ошибку компиляции вместо ошибки во время выполнения, что гораздо легче исправить):

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

Теперь нарушитель теперь обеспечивает, чтобы все, что вы передавали в конструктор TreeItem, является правильным типом.

Edit:

Конечно, если ваш 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 ; 'для настройки моей таблицы внутри нее. Я добавил код для этого класса. –

+0

Затем вам нужно сделать правильный снимок в вашем обработчике. Если «TreeTableView» является «TreeTableView », то вы отбрасываете его на это, а когда вы извлекаете значение из корневого узла, вы назначаете его «BillingTableRow». (См. Обновленный ответ.) Значения в вашем «TreeTableView» - это всего лишь один тип, просто решайте, что они собой представляют и придерживайтесь. –

+0

Так что я не могу использовать разные классы для переноса данных и их рендеринга в виде таблицы? –

0

Вы должны для всех вкладок setContent (табличного дерева) и для всех табличного дерева в закладках 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

Попробуем это. Надеюсь это работает. –

+0

Это не сработало. Проблема не решена. –

+0

в вашем коде я хочу знать таблицу instanceof? и вкладки instanceof? Таблица – Mailkov

Смежные вопросы