JavaFX Componentes Internos a uma TableView [RESOLVIDO]

2 respostas
programaçãojava
T

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?

2 Respostas

A

Pelo que entendi, você quer salvar a avaliação no momento em que o rating for alterado?

Se for isso, coloque uma chamada para o seu dao no listner do Rating.

Dê uma olhada nisso: https://github.com/Andrauss/LivrosFx, vai te ajudar

T

Muito obrigado cara, você me ajudou demais!

Criado 24 de dezembro de 2016
Ultima resposta 24 de dez. de 2016
Respostas 2
Participantes 2