1

我正在尝试构建一个代表 LED 矩阵(或其中许多)的应用程序,这些矩阵将在音乐上重新反应并与它同步闪烁 LED。

我的 gui 看起来像这样:

第一张照片

但是在我播放一首歌后,闪烁“leds”我得到像这样的坏点:

第二张图片

我玩的时间越长,我得到的坏点就越多。在我的日志中,我收到了这个异常:

java.lang.ClassCastException:com.sun.scenario.effect.InnerShadow 无法在 com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:970) 处转换​​为 com.sun.prism.paint.Paint 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) 在 com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter .java:323) 在 com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 在 java.util。 concurrent.FutureTask.runAndReset(FutureTask.java:308) 在 com.sun.javafx.tk.RenderJob.run(RenderJob.java:58) 在 java.util.concurrent。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 转换为 com.sun.scenario.effect.Effect。 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.com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)。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) at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576) at 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) 在 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) at com .sun.javafx.tk.RenderJob.run(RenderJob.java:58) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java :617) 在 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.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:970) 的 com.sun.javafx.sg.prism 上转换为 com.sun.prism.paint.Paint .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.NGNode.doRender(NGNode.java:2053) 上 com.sun.javafx.sg 上的 com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)。 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) at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java: 91) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 在 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) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 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 转换为 com.sun.scenario.effect.Effect。 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) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053) at 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) 在 com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:323) 在 com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91) 在 java。 util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 位于 com.sun 的 java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)。javafx.tk.RenderJob.run(RenderJob.java:58) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)在 com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125) 在 java.lang.Thread.run(Thread.java:745)

我的代码可以在GITHUB和下面找到。如果您喜欢从计算机播放到计算机输入的音乐(因此您可以从代码中获取它),如果您有该功能,则需要在声卡上启用“立体声混音”,我需要新的驱动程序才能使其工作. 否则,您可以只在麦克风中播放音乐。

这是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的库。可以在这里找到。

请对我好一点,这是我的第一个 Java FX 应用程序,我对桌面 gui 没有那么丰富的经验。

谁能指出我正确的方向,我怎样才能使这项工作?

让我知道是否有什么我能做的来帮助你帮助我。

4

0 回答 0