Oi pessoal, estou com um problema que não faço ideia de como solucionar.
Estou fazendo um sistema em JavaFX, que usa o ControlsFX junto. Em certa parte estou fazendo uma TableView com as seguintes colunas: Artista, Música e Avaliação, como na imagem:
Basicamente o que eu quero fazer é: Pegar uma lista de músicas do banco de dados (MYSQL), colocar ao lado de seu respectivo artista e permitir o usuário dar a classificação que ele bem entender. Fui pesquisar sobre como colocar o Rating dentro da tabela, e achei só um tópico: http://stackoverflow.com/questions/36671874/how-to-add-a-rating-inside-a-tableview-in-javafx
Usei o código que o moço do stackoverflow colocou na resposta, mas mesmo assim, ele dava exceptions no meu código.
Na primeira tentativa, peguei o código do cara e coloquei no meu na cara dura mesmo, ficando dessa forma o método:
private void atualizaTableViewRegistros() {
colArtista.setCellValueFactory(new PropertyValueFactory<>("artista")); colMusica.setCellValueFactory(new PropertyValueFactory<>("nomeMusica"));
colRating.setCellFactory(table -> new TableCell<RatingItem, Number>() {
private final Rating rating;
private final ChangeListener<Number> ratingChangeListener;
{ rating = new Rating(5);
// listener for changes in rating ratingChangeListener = (observable, oldValue, newValue) -> { TableColumn<?, Number> column = getTableColumn();
// get the property used for this column (has to be // WritableDoubleProperty) WritableDoubleValue value = (WritableDoubleValue) column.getCellValueFactory() .call(new TableColumn.CellDataFeatures(getTableView(), column, getTableRow().getItem()));
value.set(newValue.doubleValue()); }; }
@Override protected void updateItem(Number item, boolean empty) { super.updateItem(item, empty);
rating.ratingProperty().removeListener(ratingChangeListener);
if (empty) { setGraphic(null); } else { rating.setRating(item.doubleValue());
// only listen to changes done later through user // interaction rating.ratingProperty().addListener(ratingChangeListener); setGraphic(rating); } }
});
tableViewRegistros.setItems(FXCollections.observableArrayList(musicaDAO.retornaDoArquivo(arquivo)));}
Eu também criei a classe RatingItem no meu projeto, aquela que o cara do stackOverflow criou pra gerenciar os valores do Rating:
public class RatingItem {
private final DoubleProperty rating;
public RatingItem(int rating) {
this.rating = new SimpleDoubleProperty(rating);
}
public final double getRating() {
return this.rating.get();
}
public final void setRating(double value) {
this.rating.set(value);
}
public final DoubleProperty ratingProperty() {
return this.rating;
}
}
Como resultado disso, recebi a seguinte Exception:
Exception in thread “JavaFX Application Thread” java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
… 31 more
Caused by: java.lang.NullPointerException
at pacotePrincipal.ControllerArtista$1.updateItem(ControllerArtista.java:462)
at pacotePrincipal.ControllerArtista$1.updateItem(ControllerArtista.java:1)
at javafx.scene.control.TableCell.updateItem(TableCell.java:663)
at javafx.scene.control.TableCell.indexChanged(TableCell.java:468)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:533)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.init(TableRowSkinBase.java:147)
at com.sun.javafx.scene.control.skin.TableRowSkin.(TableRowSkin.java:64)
at javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:212)
at javafx.scene.control.Control.impl_processCSS(Control.java:872)
at javafx.scene.Node.processCSS(Node.java:9058)
at javafx.scene.Node.applyCss(Node.java:9155)
at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1964)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1797)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCellLength(VirtualFlow.java:1879)
at com.sun.javafx.scene.control.skin.VirtualFlow.computeViewportOffset(VirtualFlow.java:2528)
at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1189)
at javafx.scene.Parent.layout(Parent.java:1087)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Scene.doLayoutPass(Scene.java:552)
at javafx.scene.Scene.preferredSize(Scene.java:1646)
at javafx.scene.Scene.impl_preferredSize(Scene.java:1720)
at javafx.stage.Window$9.invalidated(Window.java:846)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.stage.Window.setShowing(Window.java:922)
at javafx.stage.Window.show(Window.java:937)
at javafx.stage.Stage.show(Stage.java:259)
at pacotePrincipal.ArtistaView.start(ArtistaView.java:32)
at pacotePrincipal.Controller.clique(Controller.java:60)
… 41 more
Então resolvi dar uma olhada onde que a exceção era gerada, e cheguei nessa linha:
rating.setRating(item.doubleValue());
Então comentei ela pra ver no que dava, e o resultado foi a imagem que eu anexei aqui.
Mas eu ainda tinha dois problemas: um era o de que eu não sabia como cadastrar valores na base de dados a respeito da avaliação de cada música e o outro era o de que eu não sei como extrair as informações dos ratings da tabela.
Alguém pode me ajudar com isso?