我正在尝试构建一个代表一个led矩阵(或其中许多)的应用程序,这些矩阵将在音乐上重新启动并与它同步闪烁LED。
我的gui看起来像这样:
但是在我播放了一段时间的歌曲后,闪烁着" leds"我得到像这样的坏像素:
我玩的时间越长,得到的死像素越多。在我的日志中,我得到了这个例外:
java.lang.ClassCastException:com.sun.scenario.effect.InnerShadow无法强制转换为com.sun.prism.paint.Paint 在com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:970) 在com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:606) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477) at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:323) 在com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91) at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) 在com.sun.javafx.tk.RenderJob.run(RenderJob.java:58) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at com.sun.javafx.tk.quantum.QuantumRenderer $ PipelineRunnable.run(QuantumRenderer.java:125) 在java.lang.Thread.run(Thread.java:745) java.lang.ClassCastException:com.sun.prism.paint.LinearGradient无法强制转换为com.sun.scenario.effect.Effect 在com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:1034) 在com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:606) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477) at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:323) 在com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91) at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) 在com.sun.javafx.tk.RenderJob.run(RenderJob.java:58) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at com.sun.javafx.tk.quantum.QuantumRenderer $ PipelineRunnable.run(QuantumRenderer.java:125) 在java.lang.Thread.run(Thread.java:745) java.lang.ClassCastException:com.sun.scenario.effect.InnerShadow无法强制转换为com.sun.prism.paint.Paint 在com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:970) 在com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:606) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477) at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:323) 在com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91) at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) 在com.sun.javafx.tk.RenderJob.run(RenderJob.java:58) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at com.sun.javafx.tk.quantum.QuantumRenderer $ PipelineRunnable.run(QuantumRenderer.java:125) 在java.lang.Thread.run(Thread.java:745) java.lang.ClassCastException:com.sun.prism.paint.LinearGradient无法强制转换为com.sun.scenario.effect.Effect 在com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:1034) 在com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:606) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235) 在com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) 在com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) 在com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945) 在com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477) at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:323) 在com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91) at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) 在com.sun.javafx.tk.RenderJob.run(RenderJob.java:58) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at com.sun.javafx.tk.quantum.QuantumRenderer $ PipelineRunnable.run(QuantumRenderer.java:125) 在java.lang.Thread.run(Thread.java:745)
我的代码可以在GITHUB找到,如下所示。如果您喜欢从计算机播放的音乐到计算机的输入(这样您可以从代码中获取),您需要启用" Stereo Mix"在你的声卡上,如果你有这个功能,我需要新的驱动程序才能使它工作。其他你可以用麦克风播放音乐。
这是 Main.java :
package org.ledalizer;
import ddf.minim.*;
import ddf.minim.analysis.BeatDetect;
import eu.hansolo.enzo.canvasled.Led;
import eu.hansolo.enzo.canvasled.LedBuilder;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.concurrent.Task;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.input.DragEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by david on 2015-09-29.
*/
public class Main extends Application {
public static final int MATRIX_HEIGHT = 30,
MATRIX_WIDTH = 5,
MATRIX_COUNT = 3;
MatrixPane[] matrixPanes = new MatrixPane[MATRIX_COUNT];
class MinimInput {
String sketchPath( String fileName ) {
return "";
}
InputStream createInput(String fileName) {
return new InputStream() {
@Override
public int read() throws IOException {
return 0;
}
};
};
}
@Override
public void start(Stage stage) throws Exception {
FlowPane flowPane = new FlowPane(Orientation.HORIZONTAL, 10, 5);
for(int matrixId=0; matrixId < MATRIX_COUNT; matrixId++) {
MatrixPane matrixPane = new MatrixPane(MATRIX_WIDTH, MATRIX_HEIGHT);
matrixPane.addAllLedsEventHandler(MouseDragEvent.MOUSE_DRAG_ENTERED, toggleLedEventHandler);
matrixPane.addAllLedsEventHandler(MouseEvent.MOUSE_PRESSED, toggleLedEventHandler);
matrixPane.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
((MatrixPane) event.getSource()).setAllOn();
}
}
}
);
matrixPanes[matrixId] = matrixPane;
flowPane.getChildren().add(matrixPane);
}
Scene scene = new Scene(flowPane);
scene.addEventFilter(MouseEvent.DRAG_DETECTED , new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
scene.startFullDrag();
}
});
stage.setTitle("Ledalizer");
stage.setScene(scene);
stage.show();
Thread th = new Thread(new Runnable() {
@Override
public void run() {
Minim minim = new Minim(new MinimInput());
AudioInput input = minim.getLineIn(Minim.STEREO, 512);
BeatDetect beatDetect = new BeatDetect(512, 44100.0f);
beatDetect.detectMode(BeatDetect.SOUND_ENERGY);
beatDetect.setSensitivity(50);
//BeatListener bl = new BeatListener(beatDetect, input);
/*
FlashPanelTask hatFlash = new FlashPanelTask(matrixPanes[0], 300);
FlashPanelTask snareFlash = new FlashPanelTask(matrixPanes[1], 300);
FlashPanelTask kickFlash = new FlashPanelTask(matrixPanes[2], 300);
*/
/*
Thread hatFlashThread = new Thread(hatFlash);
Thread snareFlashThread = new Thread(snareFlash);
Thread kickFlashThread = new Thread(kickFlash);
*/
int i = 0;
while (true) {
beatDetect.detect(input.mix);
if(beatDetect.isOnset()) {
matrixPanes[0].setAllOn();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
matrixPanes[0].setAllOff();
}
}
}
});
th.start();
}
class FlashPanelTask implements Runnable {
private MatrixPane matrixPane;
private int time;
public FlashPanelTask(MatrixPane matrixPane, int time) {
this.matrixPane = matrixPane;
this.time = time;
}
@Override
public void run() {
matrixPane.setAllOn();
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
matrixPane.setAllOff();
}
}
class BeatListener implements AudioListener
{
private BeatDetect beat;
private AudioInput source;
BeatListener(BeatDetect beat, AudioInput source)
{
this.source = source;
this.source.addListener(this);
this.beat = beat;
}
public void samples(float[] samps) {
beat.detect(source.mix);
}
public void samples(float[] sampsL, float[] sampsR) {
beat.detect(source.mix);
}
}
EventHandler toggleLedEventHandler = new EventHandler() {
@Override
public void handle(Event event) {
Object o = event.getSource();
if(o instanceof Led) {
Led l = (Led) o;
l.setOn(!l.isOn());
}
}
};
EventHandler enableLedEventHandler = new EventHandler() {
@Override
public void handle(Event event) {
Object o = event.getSource();
if(o instanceof Led) {
((Led) o).setOn(true);
}
}
};
}
这是 MatrixPane.java :
package org.ledalizer;
import eu.hansolo.enzo.canvasled.Led;
import eu.hansolo.enzo.canvasled.LedBuilder;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.layout.BackgroundPosition;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by david on 2015-09-30.
*/
public class MatrixPane extends GridPane {
int matrixId;
int width, height;
Led[][] leds;
List<Led> ledList;
public MatrixPane(int width, int height, int matrixId) {
init(width, height, matrixId);
}
public MatrixPane(int width, int height) {
init(width, height);
}
private void init(int width, int height, int matrixId) {
this.matrixId = matrixId;
init(width, height);
}
private void init(int width, int height) {
this.width = width;
this.height = height;
leds = new Led[width][height];
ledList = new ArrayList<>();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Led led = LedBuilder.create()
.ledColor(Color.LIGHTBLUE)
.frameVisible(true)
.build();
leds[x][y] = led;
ledList.add(led);
this.add(led, x, y);
}
}
}
public void addAllLedsEventHandler(final EventType<? extends Event> eventType,
final EventHandler<? super Event> eventHandler) {
ledList.forEach((led) -> led.addEventHandler(eventType, eventHandler));
}
public void addLedEventHandler(MatrixPoint point, final EventType<Event> eventType,
final EventHandler<? super Event> eventHandler ) {
leds[point.getX()][point.getY()].addEventHandler(eventType, eventHandler);
}
public void setAllColor(Color color) {
setAll(null, color);
}
public void setAllOff() {
setAll(false, null);
}
public void setAllOn() {
setAll(true, null);
}
public void setAll(Boolean on, Color color) {
ledList.forEach(led -> {
setLed(led, on, color);
}
);
}
public void setUpToColor(int limit, Color color) {
setUpTo(limit, null, color);
}
public void setOnUpTo(int limit) {
setUpTo(limit, true, null);
}
public void setOffUpTo(int limit) {
setUpTo(limit, false, null);
}
public void setUpTo(int limit, Boolean on, Color color) {
for(int y=0; y<limit; y++) {
setRow(y, on, color);
}
}
public void setDownToColor(int limit, Color color) {
setDownTo(limit, null, color);
}
public void setOffDownTo(int limit) {
setDownTo(limit, false, null);
}
public void setOnDownTo(int limit) {
setDownTo(limit, true, null);
}
public void setDownTo(int limit, Boolean on, Color color) {
for(int y=limit; y<height; y++) {
setRow(y, on, color);
}
}
public void setRowColor(int y, Color color) {
setRow(y, null, color);
}
public void setRowOn(int y) {
setRow(y, true, null);
}
public void setRowOff(int y) {
setRow(y, false, null);
}
public void setRow(int y, Boolean on, Color color) {
for(int x=0; x<width; x++) {
setLed(x, y, on, color);
}
}
public void setColumnOn(int x) {
setColumn(x, true, null);
}
public void setColumnOff(int x) {
setColumn(x, false, null);
}
public void setColumnColor(int x, Color color) {
setColumn(x, null, color);
}
public void setColumn(int x, Boolean on, Color color) {
for(int y=0; y<height; y++) {
setLed(x, y, on, color);
}
}
public void setRectangleAreaOn(int x1, int y1, int x2, int y2) {
setRectangleArea(x1, y1, x2, y2, true, null);
}
public void setRectangleAreaOff(int x1, int y1, int x2, int y2) {
setRectangleArea(x1, y1, x2, y2, false, null);
}
public void setRectangleAreaColor(int x1, int y1, int x2, int y2, Color color) {
setRectangleArea(x1, y1, x2, y2, null, color);
}
public void setRectangleArea(int x1, int y1, int x2, int y2, Boolean on, Color color) {
int xLow = getLowest(x1, x2);
int xHigh = getHighest(x1, x2);
int yLow = getLowest(y1, y2);
int yHigh = getHighest(y1, y2);
for(int x=xLow; x < xHigh; x++) {
for(int y=yLow; y < yHigh; y++) {
setLed(x, y, on, color);
}
}
}
private int getHighest(int i1, int i2) {
return i1 > i2 ? i1 : i2;
}
private int getLowest(int i1, int i2) {
return i1 < i2 ? i1 : i2;
}
public void setLedColor(int x, int y, Color color) {
setLed(leds[x][y], null, color);
}
public void setLedOff(int x, int y) {
setLed(leds[x][y], false, null);
}
public void setLedOn(int x, int y) {
setLed(leds[x][y], true, null);
}
public void setLed(int x, int y, Boolean on, Color color) {
setLed(leds[x][y], on, color);
}
public void setLedsColor(List<MatrixPoint> points, Color color) {
setLeds(points, null, color);
}
public void setLedsOn(List<MatrixPoint> points) {
setLeds(points, true, null);
}
public void setLedsOff(List<MatrixPoint> points) {
setLeds(points, false, null);
}
public void setLeds(List<MatrixPoint> points, Boolean on, Color color) {
points.forEach(p -> setLed(p.getX(), p.getY(), on, color));
}
public void setLedOn(MatrixPoint point) {
setLed(point.getX(), point.getY(), true, null);
}
private void setLed(Led led, Boolean on, Color color) {
if(on != null) {
led.setOn(on);
}
if(color != null) {
led.setLedColor(color);
}
}
}
Led.java 来自Hansolo的一个名为Enzo的库。它可以找到here。
请对我好,这是我的第一个Java FX应用程序,我不熟悉桌面guis。
任何人都可以指出我正确的方向,我该如何做到这一点?
请告诉我是否有任何可以帮助您的方法。