我的java fx应用程序中的实时更改使其失败

时间:2015-10-10 15:33:51

标签: java user-interface javafx led minim

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

我的gui看起来像这样:

First picture

但是在我播放了一段时间的歌曲后,闪烁着" leds"我得到像这样的坏像素:

Second picture

我玩的时间越长,得到的死像素越多。在我的日志中,我得到了这个例外:

  

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。

任何人都可以指出我正确的方向,我该如何做到这一点?

请告诉我是否有任何可以帮助您的方法。

0 个答案:

没有答案