├── Android
└── tasker
│ └── LedTable.prj.xml
├── Arduino-LedTable
├── .cproject
├── .project
├── .settings
│ └── it.baeyens.core.prefs
├── AdaFruitEx.cpp
├── AdaFruitEx.h
├── LedTable.cpp
└── LedTable.h
├── LICENSE
├── README.md
└── RPi-Java-LedTable
├── .classpath
├── .gitignore
├── .project
├── MANIFEST.MF
├── README.md
├── build.xml
├── effectAnimations
├── circle_7x7
│ ├── circle1.bmp
│ ├── circle10.bmp
│ ├── circle11.bmp
│ ├── circle12.bmp
│ ├── circle13.bmp
│ ├── circle2.bmp
│ ├── circle3.bmp
│ ├── circle4.bmp
│ ├── circle5.bmp
│ ├── circle6.bmp
│ ├── circle7.bmp
│ ├── circle8.bmp
│ └── circle9.bmp
└── square_5x5
│ ├── square1.bmp
│ ├── square2.bmp
│ └── square3.bmp
├── lib
└── pi4j
│ ├── junit.jar
│ ├── pi4j-core-javadoc.jar
│ ├── pi4j-core-sources.jar
│ ├── pi4j-core.jar
│ ├── pi4j-device-javadoc.jar
│ ├── pi4j-device-sources.jar
│ ├── pi4j-device.jar
│ ├── pi4j-example-javadoc.jar
│ ├── pi4j-example-sources.jar
│ ├── pi4j-example.jar
│ ├── pi4j-gpio-extension-javadoc.jar
│ ├── pi4j-gpio-extension-sources.jar
│ ├── pi4j-gpio-extension.jar
│ ├── pi4j-service-javadoc.jar
│ ├── pi4j-service-sources.jar
│ └── pi4j-service.jar
├── logging.properties
├── settings.txt
├── src
├── com
│ └── mikelduke
│ │ └── java
│ │ └── util
│ │ └── log
│ │ └── LogUtil.java
└── net
│ └── mdp3
│ └── java
│ ├── rpi
│ └── ledtable
│ │ ├── LedTable.java
│ │ ├── LedTable_Selection.java
│ │ ├── LedTable_Settings.java
│ │ ├── LedTable_Util.java
│ │ ├── effects
│ │ ├── AnimationEffect.java
│ │ ├── Effect.java
│ │ ├── EffectFactory.java
│ │ ├── EffectInfo.java
│ │ ├── EffectInfoParameter.java
│ │ ├── EffectMode.java
│ │ ├── Effect_Util.java
│ │ ├── ImageScanEffect.java
│ │ ├── MidiEffect.java
│ │ ├── PulseEffect.java
│ │ ├── RainbowEffect.java
│ │ ├── RandomFillEffect.java
│ │ ├── SetColorEffect.java
│ │ ├── TransparencyAnimationEffect.java
│ │ └── playlist
│ │ │ ├── Playlist.java
│ │ │ ├── PlaylistEvent.java
│ │ │ ├── PlaylistEventListener.java
│ │ │ ├── PlaylistItem.java
│ │ │ └── PlaylistTimer.java
│ │ ├── gui
│ │ ├── EffectWindow.java
│ │ ├── MainWindow.java
│ │ ├── PlaylistWindow.java
│ │ └── TablePanel.java
│ │ ├── table
│ │ ├── Table.java
│ │ ├── TableCMD.java
│ │ ├── TableFactory.java
│ │ ├── TableFile.java
│ │ ├── TableSPI.java
│ │ ├── TableSerial.java
│ │ └── WriteListener.java
│ │ └── webservice
│ │ ├── WebserviceCommands.java
│ │ ├── WebserviceFunctions.java
│ │ └── WebserviceHandler.java
│ └── util
│ ├── console
│ ├── ConsoleArgumentHandler.java
│ ├── ConsoleBatch.java
│ ├── ConsoleReader.java
│ └── ConsoleUtil.java
│ ├── file
│ ├── FileNameFormatter.java
│ └── SimpleFileIO.java
│ ├── gui
│ └── MenuBarHelper.java
│ ├── misc
│ ├── MapUtil.java
│ └── ObjectNotInitializedException.java
│ ├── settings
│ ├── CmdLineProperties.java
│ ├── Settings.java
│ └── SettingsLoader.java
│ ├── string
│ └── StringUtils.java
│ ├── test
│ ├── BatchTest.java
│ ├── BatchTest.txt
│ ├── ConsoleArgumentHandlerTest.java
│ ├── SettingsSaveTest.java
│ ├── SettingsTest.java
│ ├── SettingsTest.txt
│ ├── SimpleFileIOTest.java
│ ├── Util_Test.java
│ └── WebserviceTest.java
│ ├── webservice
│ ├── WSResponse.java
│ ├── Webservice.java
│ ├── WebserviceBase.java
│ ├── WebserviceClient.java
│ ├── WebserviceConstants.java
│ ├── WebserviceListener.java
│ └── WebserviceUtil.java
│ └── xml
│ ├── DomXml.java
│ └── XmlHelper.java
├── testAnimation
├── 001.bmp
├── 002.bmp
├── 003.bmp
└── 004.bmp
├── testAnimation2
├── ChristmasTree.bmp
└── HOHOHO.bmp
├── testImages
├── ChristmasTree.bmp
├── HI.bmp
├── HOHOHO.bmp
├── test.bmp
├── testScale1.bmp
└── test_vert.bmp
└── www
├── LedTable.html
└── LedTable.js
/Arduino-LedTable/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | LedTable
4 |
5 |
6 | Arduino_Uno
7 |
8 |
9 |
10 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
11 | clean,full,incremental,
12 |
13 |
14 |
15 |
16 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
17 | full,incremental,
18 |
19 |
20 |
21 |
22 |
23 | org.eclipse.cdt.core.cnature
24 | org.eclipse.cdt.core.ccnature
25 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
26 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
27 | it.baeyens.arduinonature
28 |
29 |
30 |
31 | Adafruit_WS2801
32 | 2
33 | PivateLibPath/Adafruit_WS2801
34 |
35 |
36 | SPI
37 | 2
38 | ArduinoLibPath/SPI
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Arduino-LedTable/.settings/it.baeyens.core.prefs:
--------------------------------------------------------------------------------
1 | avrtarget/ClockFrequency=16000000
2 | avrtarget/ExtRAMSize=0
3 | avrtarget/ExtendedRAM=false
4 | avrtarget/MCUType=atmega328p
5 | avrtarget/UseEEPROM=false
6 | avrtarget/UseExtendedRAMforHeap=true
7 | avrtarget/avrdude/BitBangDelay=
8 | avrtarget/avrdude/Bitclock=
9 | avrtarget/avrdude/EEPROMFile=
10 | avrtarget/avrdude/EEPROMFromConfig=true
11 | avrtarget/avrdude/FlashFile=
12 | avrtarget/avrdude/FlashFromConfig=true
13 | avrtarget/avrdude/NoChipErase=false
14 | avrtarget/avrdude/NoSigCheck=false
15 | avrtarget/avrdude/NoVerify=false
16 | avrtarget/avrdude/NoWrite=false
17 | avrtarget/avrdude/OtherOptions=
18 | avrtarget/avrdude/ProgrammerID=programmerconfig.9
19 | avrtarget/avrdude/UseCounter=false
20 | avrtarget/avrdude/WriteEEPROM=false
21 | avrtarget/avrdude/WriteFlash=true
22 | eclipse.preferences.version=1
23 |
--------------------------------------------------------------------------------
/Arduino-LedTable/AdaFruitEx.cpp:
--------------------------------------------------------------------------------
1 | #include "SPI.h"
2 | #include "Adafruit_WS2801.h"
3 | #include "AdaFruitEx.h"
4 | #include "LedTable.h"
5 |
6 | /****************************************************************************
7 | * This File has been modified from the original example code that comes with
8 | * the AdaFruit WS2801 Library. The two examples gridtest and strandtest have
9 | * been combined into one library, with the necessary header file for eclipse.
10 | * Some other minor modifications have been made, such as including the strip
11 | * variable as a parameter in several of the functions in order to make it
12 | * work correctly.
13 | *
14 | * The original Header/Liscense is included below.
15 | *
16 | * Modified by Mikel Duke http://www.mikelduke.com
17 | *
18 | * https://github.com/adafruit/Adafruit-WS2801-Library
19 | *****************************************************************************/
20 |
21 | /*****************************************************************************
22 | Example sketch for driving Adafruit WS2801 pixels!
23 |
24 |
25 | Designed specifically to work with the Adafruit RGB Pixels!
26 | 12mm Bullet shape ----> https://www.adafruit.com/products/322
27 | 12mm Flat shape ----> https://www.adafruit.com/products/738
28 | 36mm Square shape ----> https://www.adafruit.com/products/683
29 |
30 | These pixels use SPI to transmit the color data, and have built in
31 | high speed PWM drivers for 24 bit color per pixel
32 | 2 pins are required to interface
33 |
34 | Adafruit invests time and resources providing this open source code,
35 | please support Adafruit and open-source hardware by purchasing
36 | products from Adafruit!
37 |
38 | Written by David Kavanagh (dkavanagh@gmail.com).
39 | BSD license, all text above must be included in any redistribution
40 |
41 | *****************************************************************************/
42 | /*
43 | // Choose which 2 pins you will use for output.
44 | // Can be any valid output pins.
45 | // The colors of the wires may be totally different so
46 | // BE SURE TO CHECK YOUR PIXELS TO SEE WHICH WIRES TO USE!
47 | uint8_t dataPin = 2; // Yellow wire on Adafruit Pixels
48 | uint8_t clockPin = 3; // Green wire on Adafruit Pixels
49 |
50 | // Don't forget to connect the ground wire to Arduino ground,
51 | // and the +5V wire to a +5V supply
52 |
53 | // Set the first variable to the NUMBER of pixels in a row and
54 | // the second value to number of pixels in a column.
55 | //Adafruit_WS2801 strip = Adafruit_WS2801((uint16_t)12, (uint16_t)8, dataPin, clockPin);
56 | */
57 |
58 | void drawX(uint8_t w, uint8_t h, uint8_t wait, Adafruit_WS2801 strip) {
59 | uint16_t x, y;
60 | for (x=0; x 0) return;
103 |
104 | delay(wait);
105 | strip.setPixelColor(x, y, 0, 0, 0);
106 | }
107 | }
108 |
109 | void rainbow(uint8_t wait, Adafruit_WS2801 strip) {
110 | uint8_t i, j;
111 |
112 | for (j=0; j < 256; j++) { // 3 cycles of all 256 colors in the wheel
113 | for (i=0; i < strip.numPixels(); i++) {
114 | strip.setPixelColor(i, Wheel( (i + j) % 255));
115 | }
116 | strip.show(); // write all the pixels out
117 |
118 | //Added to quickly break the loop when serial data comes in
119 | if (Serial.available() > 0) return;
120 |
121 | delay(wait);
122 | }
123 | }
124 |
125 | // Slightly different, this one makes the rainbow wheel equally distributed
126 | // along the chain
127 | void rainbowCycle(uint8_t wait, Adafruit_WS2801 strip) {
128 | uint8_t i, j;
129 |
130 | for (j=0; j < 256 * 5; j++) { // 5 cycles of all 25 colors in the wheel
131 | for (i=0; i < strip.numPixels(); i++) {
132 | // tricky math! we use each pixel as a fraction of the full 96-color wheel
133 | // (thats the i / strip.numPixels() part)
134 | // Then add in j which makes the colors go around per pixel
135 | // the % 96 is to make the wheel cycle around
136 | strip.setPixelColor(i, Wheel( ((i * 256 / strip.numPixels()) + j) % 256) );
137 |
138 | //Added to quickly break the loop when serial data comes in
139 | if (Serial.available() > 0) return;
140 | }
141 | strip.show(); // write all the pixels out
142 | delay(wait);
143 | }
144 | }
145 |
146 | // fill the dots one after the other with said color
147 | // good for testing purposes
148 | void colorWipe(uint32_t c, uint8_t wait, Adafruit_WS2801 strip) {
149 | uint8_t i;
150 |
151 | for (i=0; i < strip.numPixels(); i++) {
152 | strip.setPixelColor(i, c);
153 | strip.show();
154 |
155 | //Added to quickly break the loop when serial data comes in
156 | if (Serial.available() > 0) return;
157 |
158 | delay(wait);
159 | }
160 | }
161 |
162 | /* Helper functions */
163 |
164 | // Create a 24 bit color value from R,G,B
165 | uint32_t Color(byte r, byte g, byte b)
166 | {
167 | uint32_t c;
168 | c = r;
169 | c <<= 8;
170 | c |= g;
171 | c <<= 8;
172 | c |= b;
173 | return c;
174 | }
175 |
176 | //Input a value 0 to 255 to get a color value.
177 | //The colours are a transition r - g -b - back to r
178 | uint32_t Wheel(byte WheelPos)
179 | {
180 | if (WheelPos < 85) {
181 | return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
182 | } else if (WheelPos < 170) {
183 | WheelPos -= 85;
184 | return Color(255 - WheelPos * 3, 0, WheelPos * 3);
185 | } else {
186 | WheelPos -= 170;
187 | return Color(0, WheelPos * 3, 255 - WheelPos * 3);
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/Arduino-LedTable/AdaFruitEx.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | * AdaFruitEx.h
3 | *
4 | * Created on: Jul 15, 2013
5 | * Author: Mikel
6 | *
7 | * Header file created to use the Adafruit WS2801 library and examples in
8 | * eclipse
9 | *
10 | * http://www.mikelduke.com
11 | *
12 | * https://github.com/adafruit/Adafruit-WS2801-Library
13 | *
14 | *****************************************************************************/
15 |
16 | #ifndef ADAFRUITEX_H_
17 | #define ADAFRUITEX_H_
18 |
19 | uint32_t Color(byte r, byte g, byte b);
20 | uint32_t Wheel(byte WheelPos);
21 |
22 | void rainbow(uint8_t wait, Adafruit_WS2801 strip);
23 | void rainbowCycle(uint8_t wait, Adafruit_WS2801 strip);
24 | void colorWipe(uint32_t c, uint8_t wait, Adafruit_WS2801 strip);
25 |
26 | void drawX(uint8_t w, uint8_t h, uint8_t wait, Adafruit_WS2801 strip);
27 | void bounce(uint8_t w, uint8_t h, uint8_t wait, Adafruit_WS2801 strip);
28 |
29 |
30 | #endif /* ADAFRUITEX_H_ */
31 |
--------------------------------------------------------------------------------
/Arduino-LedTable/LedTable.cpp:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | * LedTable.cpp
3 | *
4 | * Created on: Jul 14, 2013
5 | * Author: Mikel
6 | *
7 | * http://www.mikelduke.com
8 | *
9 | * Main program for use in the LedTable coffee table project based on an 8x12 array
10 | * of WS2801 RGB leds on a string.
11 | *
12 | * This program runs on an Arduino Uno using 50pc WS2801 based RGB LEDS similar to
13 | * these http://www.adafruit.com/products/322
14 | *
15 | * This program requires the use of the Adafruit WS2801 Arduino Library available
16 | * here https://github.com/adafruit/Adafruit-WS2801-Library
17 | *
18 | * The code compiled in Eclipse when set up for Arduino following these instructions
19 | * http://www.baeyens.it/eclipse/ and maybe using the Arduino IDE if renamed to .ino
20 | * but this is untested and changes are probably needed.
21 | *
22 | * Demo 1: https://www.youtube.com/watch?v=T2C9mu11J88
23 | * Demo 2: https://www.youtube.com/watch?v=4fyQAG1ji9Y
24 | * Demo 3: https://www.youtube.com/watch?v=qthHU0W8SG4
25 | *
26 | *****************************************************************************/
27 |
28 | #include "SPI.h"
29 | #include "Adafruit_WS2801.h"
30 | #include "LedTable.h"
31 | #include "AdafruitEx.h"
32 |
33 | #define TIMEOUT 2000
34 |
35 | uint8_t dataPin = 2; // Yellow wire on Adafruit Pixels
36 | uint8_t clockPin = 3; // Green wire on Adafruit Pixels
37 |
38 | int arrayX = 12;
39 | int arrayY = 8;
40 | int numLeds = arrayX * arrayY;
41 |
42 | enum States { STOPPED, DEMO, PULSE1, PULSE2, SERIAL_READ, SET_COLOR, PULSE_RANDOM, WAITING};
43 | int state = DEMO;
44 | String statusStr = "init";
45 |
46 | Adafruit_WS2801 strip = Adafruit_WS2801((uint16_t)arrayX, (uint16_t)arrayY, dataPin, clockPin);
47 |
48 | void setup() {
49 | randomSeed(analogRead(0));
50 | Serial.begin(57600);
51 | Serial.println("Led Table");
52 |
53 | strip.begin();
54 | strip.show();
55 | }
56 |
57 | void loop() {
58 | if (Serial.available() > 0) {
59 | char c;
60 | c = Serial.read();
61 | //Serial.print("Received: ");
62 | //Serial.println(c);
63 | handleRead(c);
64 | }
65 |
66 | if (state == STOPPED) {
67 | statusStr = "Stopped";
68 | setTableColor(0, 0, 0);
69 | }
70 | else if (state == DEMO) runDemos(0);
71 | else if (state == PULSE1) tablePulse(1);
72 | else if (state == PULSE2) tablePulse2(5);
73 | else if (state == SERIAL_READ) readLedArray();
74 | else if (state == PULSE_RANDOM) randomColorPulse(1);
75 | else if (state == WAITING) delay(5);
76 | //strip.show();
77 | }
78 |
79 | void handleRead(char c) {
80 | if (c == 'X') {
81 | sendStatus();
82 | }
83 | else if (c == '0') {
84 | state = STOPPED;
85 | dumpSerial();
86 | }
87 | else if (c == '1') {
88 | state = DEMO;
89 | dumpSerial();
90 | }
91 | else if (c == '2') {
92 | state = PULSE1;
93 | dumpSerial();
94 | }
95 | else if (c == '3') {
96 | state = PULSE2;
97 | readLedTableColor();
98 | dumpSerial();
99 | }
100 | else if (c == '4') {
101 | state = SERIAL_READ;
102 | //readLedArray();
103 | //dumpSerial();
104 | }
105 | else if (c == '5') {
106 | state = SET_COLOR;
107 | dumpSerial();
108 | }
109 | else if (c == '6') {
110 | state = PULSE_RANDOM;
111 | dumpSerial();
112 | }
113 | //else dumpSerial();
114 | }
115 |
116 | void runDemos(uint8_t wait) {
117 | statusStr = "Running AdaFruit Demos";
118 | runGridDemos(wait);
119 | runStrandDemos(wait);
120 | }
121 |
122 | void runGridDemos(uint8_t wait) {
123 | //Serial.println("Running AdaFruit Grid Demos");
124 | drawX(12, 8, 100, strip);
125 | bounce(12, 8, 50, strip);
126 | }
127 |
128 | void runStrandDemos(uint8_t wait) {
129 | //Serial.println("Running Adafruit Strip Demos");
130 | colorWipe(Color(255, 0, 0), wait, strip);
131 | colorWipe(Color(0, 255, 0), wait, strip);
132 | colorWipe(Color(0, 0, 255), wait, strip);
133 | rainbow(wait, strip);
134 | rainbowCycle(wait, strip);
135 | }
136 |
137 | void tablePulse(int inc) {
138 | statusStr = "Running Table Pulses";
139 | for (byte i = 0; i < 255; i += inc) {
140 | setTableColor(i, 0, 0);
141 |
142 | //Added to quickly break the loop when serial data comes in
143 | if (Serial.available() > 0) return;
144 | }
145 | for (byte i = 0; i < 255; i += inc) {
146 | setTableColor(0, i, 0);
147 |
148 | //Added to quickly break the loop when serial data comes in
149 | if (Serial.available() > 0) return;
150 | }
151 | for (byte i = 0; i < 255; i += inc) {
152 | setTableColor(0, 0, i);
153 |
154 | //Added to quickly break the loop when serial data comes in
155 | if (Serial.available() > 0) return;
156 | }
157 | //Added to quickly break the loop when serial data comes in
158 | if (Serial.available() > 0) return;
159 | }
160 |
161 | void setTableColor(byte r, byte g, byte b) {
162 | for (int x = 0; x < arrayX; x++) {
163 | for (int y = 0; y < arrayY; y++) {
164 | strip.setPixelColor(x, y, r, g, b);
165 | }
166 | }
167 | strip.show();
168 | }
169 |
170 | void dumpSerial() {
171 | while (Serial.available() > 0) {
172 | byte b;
173 | b = Serial.read();
174 | }
175 | }
176 |
177 | void sendStatus() {
178 | Serial.print("Status: ");
179 | Serial.println(statusStr);
180 | }
181 |
182 | void readLedTableColor() {
183 | int r = 0;
184 | int g = 0;
185 | int b = 0;
186 |
187 | r = Serial.parseInt();
188 | g = Serial.parseInt();
189 | b = Serial.parseInt();
190 |
191 | setTableColor(r, g, b);
192 | }
193 |
194 | //Serial buffer is only 64b!
195 | void readLedArray() {
196 | int ledsRead = 0;
197 | int delayTime = 0;
198 | while (ledsRead < numLeds) {
199 | while (Serial.available() < 3) {
200 | delay(5);
201 | delayTime += 5;
202 | if (delayTime > TIMEOUT) {
203 | state = STOPPED;
204 | return;
205 | }
206 | }
207 | char r = Serial.read();
208 | char g = Serial.read();
209 | char b = Serial.read();
210 | strip.setPixelColor(ledsRead, r, g, b);
211 | ledsRead++;
212 | }
213 | strip.show();
214 | state = WAITING;
215 | }
216 |
217 | void tablePulse2(int inc) {
218 | //statusStr = "Running Table Pulses";
219 | for (int i = 20; i <= 255; i += inc) {
220 | setTableColor((byte)i, 0, 0);
221 | //if (Serial.available() > 0) return;
222 | }
223 | for (int i = 255; i >= 20; i -= inc) {
224 | setTableColor((byte)i, 0, 0);
225 | //if (Serial.available() > 0) return;
226 | }
227 | for (int i = 20; i <= 255; i += inc) {
228 | setTableColor(0, (byte)i, 0);
229 | //if (Serial.available() > 0) return;
230 | }
231 | for (int i = 255; i >= 20; i -= inc) {
232 | setTableColor(0, (byte)i, 0);
233 | //if (Serial.available() > 0) return;
234 | }
235 | for (int i = 20; i <= 255; i += inc) {
236 | setTableColor(0, 0, (byte)i);
237 | //if (Serial.available() > 0) return;
238 | }
239 | for (int i = 255; i >= 20; i -= inc) {
240 | setTableColor(0, 0, (byte)i);
241 | //if (Serial.available() > 0) return;
242 | }
243 | //Added to quickly break the loop when serial data comes in
244 | if (Serial.available() > 0) return;
245 | }
246 |
247 | void randomColorPulse(int inc) {
248 | byte oldR = strip.pixels[0];
249 | byte oldG = strip.pixels[1];
250 | byte oldB = strip.pixels[2];
251 |
252 | byte newR = random(255);
253 | byte newG = random(255);
254 | byte newB = random(255);
255 |
256 | while ((newR > oldR + inc/2) || (newR < oldR - inc/2)) {
257 | if (oldR < newR) {
258 | oldR += inc;
259 | }
260 | else if (oldR > newR) {
261 | oldR -= inc;
262 | }
263 | setTableColor(oldR, oldG, oldB);
264 | if (Serial.available() > 0) return;
265 | }
266 | while ((newG > oldG + inc/2) || (newG < oldG - inc/2)) {
267 | if (oldG < newG) {
268 | oldG += inc;
269 | }
270 | else if (oldG > newG) {
271 | oldG -= inc;
272 | }
273 | setTableColor(oldR, oldG, oldB);
274 | if (Serial.available() > 0) return;
275 | }
276 | while ((newB > oldB + inc/2) || (newB < oldB - inc/2)) {
277 | if (oldB < newB) {
278 | oldB += inc;
279 | }
280 | else if (oldB > newB) {
281 | oldB -= inc;
282 | }
283 | setTableColor(oldR, oldG, oldB);
284 | if (Serial.available() > 0) return;
285 | }
286 | }
287 |
--------------------------------------------------------------------------------
/Arduino-LedTable/LedTable.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | * LedTable.h
3 | *
4 | * Created on: Jul 14, 2013
5 | * Author: Mikel
6 | *
7 | * http://www.mikelduke.com
8 | *
9 | * This program runs on an Arduino Uno using 50pc WS2801 based RGB LEDS similar to
10 | * these http://www.adafruit.com/products/322
11 | *
12 | * This program requires the use of the Adafruit WS2801 Arduino Library available
13 | * here https://github.com/adafruit/Adafruit-WS2801-Library
14 | *
15 | * The code compiled in Eclipse when set up for Arduino following these instructions
16 | * http://www.baeyens.it/eclipse/ and maybe using the Arduino IDE if renamed to .ino
17 | * but this is untested and changes are probably needed.
18 | *
19 | *****************************************************************************/
20 |
21 | // Only modify this file to include
22 | // - function definitions (prototypes)
23 | // - include files
24 | // - extern variable definitions
25 | // In the appropriate section
26 |
27 | #ifndef LedTable_H_
28 | #define LedTable_H_
29 | #include "Arduino.h"
30 | //add your includes for the project LedTable here
31 |
32 |
33 | //end of add your includes here
34 | #ifdef __cplusplus
35 | extern "C" {
36 | #endif
37 | void loop();
38 | void setup();
39 | #ifdef __cplusplus
40 | } // extern "C"
41 | #endif
42 |
43 | //constructors for functions that run a demo of adafruit examples
44 | void runDemos(uint8_t wait);
45 | void runGridDemos(uint8_t wait);
46 | void runStrandDemos(uint8_t wait);
47 |
48 | void tablePulse(int inc);
49 | void tablePulse2(int inc);
50 | void randomColorPulse(int inc);
51 | void setTableColor(byte r, byte g, byte b);
52 |
53 | void handleRead(char c);
54 | void dumpSerial();
55 |
56 | void sendStatus();
57 | void readLedTableColor();
58 | void readLedArray();
59 |
60 | //Do not add code below this line
61 | #endif /* LedTable_H_ */
62 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | LedTable
2 | ========
3 |
4 | http://www.mikelduke.com
5 |
6 | Code for my LedTable, an 8x12 rgb led string based table using WS2801 chips and
7 | controlled by and Arduino using a RPi for internet connectivity and higher level
8 | functionality.
9 |
10 | The Arduino code requires the Adafruit WS2801 Library and contains modifications
11 | to the included example code to combine the examples for use as a header file.
12 |
13 | https://github.com/adafruit/Adafruit-WS2801-Library
14 |
15 | This program runs on an Arduino Uno using 50pc WS2801 based RGB LEDS similar to
16 | these http://www.adafruit.com/products/322
17 |
18 | The code compiles in Eclipse when set up for Arduino following these instructions
19 | http://www.baeyens.it/eclipse/ and might compile using the Arduino IDE if renamed
20 | to .ino but this is untested and changes are probably needed.
21 |
22 | Demo 1: https://www.youtube.com/watch?v=T2C9mu11J88
23 | Demo 2: https://www.youtube.com/watch?v=4fyQAG1ji9Y
24 | Demo 3: https://www.youtube.com/watch?v=qthHU0W8SG4
25 |
26 |
27 | ========
28 | The Java app for the Raspberry pi to control the Arduino requires the Pi4J library.
29 |
30 | http://pi4j.com/
31 |
32 | The Raspberry Pi connects to the Arduino via the USB port. This is the simplest
33 | connection type available. The app requires Java which is included in newer
34 | Raspbian releases and must be run with sudo.
35 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 |
3 | build/
4 | dist/
5 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | LedTable
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.wst.jsdt.core.javascriptValidator
10 |
11 |
12 |
13 |
14 | org.eclipse.wst.common.project.facet.core.builder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 |
25 | org.eclipse.jdt.core.javanature
26 | org.eclipse.wst.common.project.facet.core.nature
27 | org.eclipse.wst.jsdt.core.jsNature
28 |
29 |
30 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Ant-Version: Apache Ant 1.10.1
3 | Created-By: 9.0.4+11 (Oracle Corporation)
4 | Built-By: mikel
5 | Main-Class: net.mdp3.java.rpi.ledtable.LedTable
6 | Class-Path: ./lib/pi4j/junit.jar ./lib/pi4j/pi4j-core-javadoc.jar
7 | ./lib/pi4j/pi4j-core-sources.jar ./lib/pi4j/pi4j-core.jar
8 | ./lib/pi4j/pi4j-device-javadoc.jar ./lib/pi4j/pi4j-device-source
9 | s.jar ./lib/pi4j/pi4j-device.jar ./lib/pi4j/pi4j-example-java
10 | doc.jar ./lib/pi4j/pi4j-example-sources.jar ./lib/pi4j/pi4j-e
11 | xample.jar ./lib/pi4j/pi4j-gpio-extension-javadoc.jar ./lib/p
12 | i4j/pi4j-gpio-extension-sources.jar ./lib/pi4j/pi4j-gpio-extensio
13 | n.jar ./lib/pi4j/pi4j-service-javadoc.jar ./lib/pi4j/pi4j-ser
14 | vice-sources.jar ./lib/pi4j/pi4j-service.jar
15 |
16 | Name: common
17 | Specification-Title: LedTable
18 | Specification-Version: 0.2.1
19 | Specification-Vendor: mdp3.net
20 | Implementation-Title: Java LedTable Controller
21 | Implementation-Version: 0.2.1 February 20 2018
22 | Implementation-Vendor: mdp3.net
23 |
24 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/README.md:
--------------------------------------------------------------------------------
1 | LedTable
2 | ========
3 |
4 | http://www.mikelduke.com
5 |
6 | Code for my LedTable, an 8x12 rgb led string based table using WS2801 chips and
7 | controlled by and Arduino using a RPi for internet connectivity and higher level
8 | functionality.
9 |
10 | The Arduino code requires the Adafruit WS2801 Library and contains modifications
11 | to the included example code to combine the examples for use as a header file.
12 |
13 | https://github.com/adafruit/Adafruit-WS2801-Library
14 |
15 | This program runs on an Arduino Uno using 50pc WS2801 based RGB LEDS similar to
16 | these http://www.adafruit.com/products/322
17 |
18 | The code compiles in Eclipse when set up for Arduino following these instructions
19 | http://www.baeyens.it/eclipse/ and might compile using the Arduino IDE if renamed
20 | to .ino but this is untested and changes are probably needed.
21 |
22 | Demo 1: https://www.youtube.com/watch?v=T2C9mu11J88
23 | Demo 2: https://www.youtube.com/watch?v=4fyQAG1ji9Y
24 | Demo 3: https://www.youtube.com/watch?v=qthHU0W8SG4
25 |
26 |
27 | ========
28 | The Java app for the Raspberry pi to control the Arduino requires the Pi4J library.
29 |
30 | http://pi4j.com/
31 |
32 | The Raspberry Pi connects to the Arduino via the USB port. This is the simplest
33 | connection type available. The app requires Java which is included in newer
34 | Raspbian releases and must be run with sudo.
35 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Build file for LedTable
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle1.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle1.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle10.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle10.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle11.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle11.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle12.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle12.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle13.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle13.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle2.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle2.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle3.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle3.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle4.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle4.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle5.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle5.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle6.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle6.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle7.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle7.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle8.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle8.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/circle_7x7/circle9.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/circle_7x7/circle9.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/square_5x5/square1.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/square_5x5/square1.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/square_5x5/square2.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/square_5x5/square2.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/effectAnimations/square_5x5/square3.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/effectAnimations/square_5x5/square3.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/junit.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/junit.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-core-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-core-javadoc.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-core-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-core-sources.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-core.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-core.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-device-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-device-javadoc.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-device-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-device-sources.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-device.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-device.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-example-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-example-javadoc.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-example-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-example-sources.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-example.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-example.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-gpio-extension-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-gpio-extension-javadoc.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-gpio-extension-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-gpio-extension-sources.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-gpio-extension.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-gpio-extension.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-service-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-service-javadoc.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-service-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-service-sources.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/lib/pi4j/pi4j-service.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/lib/pi4j/pi4j-service.jar
--------------------------------------------------------------------------------
/RPi-Java-LedTable/logging.properties:
--------------------------------------------------------------------------------
1 | # Properties file which configures the operation of the JDK
2 | # logging facility.
3 |
4 | # The system will look for this config file, first using
5 | # a System property specified at startup:
6 | #
7 | # >java -Djava.util.logging.config.file=myLoggingConfigFilePath
8 | #
9 | # If this property is not specified, then the config file is
10 | # retrieved from its default location at:
11 | #
12 | # JDK_HOME/jre/lib/logging.properties
13 |
14 | # Global logging properties.
15 | # ------------------------------------------
16 | # The set of handlers to be loaded upon startup.
17 | # Comma-separated list of class names.
18 | # (? LogManager docs say no comma here, but JDK example has comma.)
19 | handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler
20 |
21 | # Default global logging level.
22 | # Loggers and Handlers may override this level
23 | .level=INFO
24 |
25 | # Loggers
26 | # ------------------------------------------
27 | # Loggers are usually attached to packages.
28 | # Here, the level for each package is specified.
29 | # The global level is used by default, so levels
30 | # specified here simply act as an override.
31 | net.mdp3.java.rpi.ledtable.level=INFO
32 | #net.mdp3.java.jams.level=ALL
33 | #net.mdp3.java.jams.midi.level=FINEST
34 |
35 | # Handlers
36 | # -----------------------------------------
37 |
38 | # --- ConsoleHandler ---
39 | # Override of global logging level
40 | java.util.logging.ConsoleHandler.level=INFO
41 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
42 |
43 | # --- FileHandler ---
44 | # Override of global logging level
45 | java.util.logging.FileHandler.level=INFO
46 |
47 | # Naming style for the output file:
48 | # (The output file is placed in the directory
49 | # defined by the "user.home" System property.)
50 | #java.util.logging.FileHandler.pattern=%h/java%u.log
51 | java.util.logging.FileHandler.pattern=ledTable%u.log
52 |
53 | # Limiting size of output file in bytes:
54 | java.util.logging.FileHandler.limit=50000
55 |
56 | # Number of output files to cycle through, by appending an
57 | # integer to the base file name:
58 | java.util.logging.FileHandler.count=1
59 |
60 | # Style of output (Simple or XML):
61 | java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
62 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/settings.txt:
--------------------------------------------------------------------------------
1 | #LedTable Settings
2 |
3 | #Debug Mode
4 | debug: true
5 |
6 | #Test GUI Settings
7 | enableGUI: true
8 | guiW: 520
9 | guiH: 366
10 | flipY: true
11 |
12 | #Webservice Settings
13 | wsName: /ledtable
14 | wsPort: 85
15 |
16 | #Remote Webservice Connection Settings
17 | remoteWS: false
18 | remoteWSURL: http://ip:85/ledtable
19 |
20 | #Output Settings
21 | enableTableOutput: false
22 | tableMode: SPI
23 |
24 | #Serial Settings
25 | serialPort: /dev/ttyACM0
26 | serialBaud: 57600
27 |
28 | #SPI Settings
29 | spiSpeed: 1953000
30 |
31 | #File Output Settings
32 | outputFile: /dev/spidev0.0
33 |
34 | #LedTable Settings
35 | ledY: 8
36 | ledX: 12
37 | snakedLeds: true
38 |
39 | #Midi Settings
40 | midiUpdateDelay: 100
41 |
42 | #File Save Settings
43 | defaultSaveFolder: C:/mdp3/projects/LedTable/java/saves
44 | defaultFilePrefix: LedTable
45 |
46 | #Auto load and play settings
47 | autoplaySelection: false
48 | defaultSelectionFile: C:/mdp3/projects/LedTable/java/saves/selections/LedTable-20150930183017.xml
49 |
50 | autoplayPlaylist: true
51 | defaultPlaylistFile: C:/mdp3/projects/LedTable/java/saves/playlists/LedTable-20151022150223.xml
52 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/com/mikelduke/java/util/log/LogUtil.java:
--------------------------------------------------------------------------------
1 | package com.mikelduke.java.util.log;
2 |
3 | import java.util.Map;
4 | import java.util.logging.Level;
5 | import java.util.logging.Logger;
6 |
7 | public class LogUtil {
8 | private static final String CLAZZ = LogUtil.class.getName();
9 | private static final Logger LOGGER = Logger.getLogger(CLAZZ);
10 |
11 | public static void logMap(Level level, String clazz, String msg, Map map) {
12 | StringBuilder sb = new StringBuilder();
13 |
14 | if (level == null) {
15 | level = Level.FINEST;
16 | }
17 |
18 | if (clazz == null || clazz.isEmpty()) {
19 | clazz = CLAZZ;
20 | }
21 |
22 | if (msg == null || msg.isEmpty()) {
23 | msg = "Map Values";
24 | }
25 |
26 | if (map == null) {
27 | sb.append("Map is null");
28 | }
29 |
30 | if (map.isEmpty()) {
31 | sb.append("Map is empty");
32 | }
33 |
34 | for (K key : map.keySet()) {
35 | sb.append(key + ": " + map.get(key));
36 | sb.append("\n");
37 | }
38 |
39 | LOGGER.logp(level, clazz, "logMap", msg + ": " + sb.toString());
40 | }
41 |
42 | public static void logMap(Level level, String clazz, Map map) {
43 | logMap(level, clazz, "", map);
44 | }
45 |
46 | public static void logMap(Level level, Map map) {
47 | logMap(level, CLAZZ, "", map);
48 | }
49 |
50 | public static void logMap(Map map) {
51 | logMap(Level.FINEST, CLAZZ, "Map", map);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/LedTable_Settings.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable;
2 |
3 | import java.util.logging.Logger;
4 |
5 | import net.mdp3.java.util.settings.SettingsLoader;
6 |
7 | /**
8 | *
9 | * @author Mikel
10 | *
11 | * Class of static variables to hold the global settings
12 | * Has database, serial port, and table info
13 | */
14 |
15 | public class LedTable_Settings {
16 | private final static Logger LOG = Logger.getLogger(LedTable_Settings.class.getName());
17 | private final static String name = "LedTable_Settings";
18 |
19 | //Default settings if not overwritten in settings.txt
20 | public static boolean enableGUI = true;
21 | public static int guiW = 504;
22 | public static int guiH = 336;
23 | public static boolean flipY = true;
24 |
25 | public static String wsName = "/ledtable";
26 | public static int wsPort = 85;
27 |
28 | public static boolean enableTableOutput = false;
29 | public static String tableMode = "SPI";
30 | public static String serialPort = "/dev/ttyACM0";
31 | public static int serialBaud = 57600;
32 |
33 | public static int spiSpeed = 1953000;
34 |
35 | public static String outputFile = "/dev/spidev0.0";
36 |
37 | public static int ledY = 8;
38 | public static int ledX = 12;
39 | public static boolean snakedLeds = true;
40 |
41 | public static boolean debug = true;
42 |
43 | public static long midiUpdateDelay = 100;
44 |
45 | public static String defaultSaveFolder = "";
46 | public static String defaultFilePrefix = "LedTable";
47 |
48 | public static boolean remoteWS = false;
49 | public static String remoteWSURL = "";
50 |
51 | public static boolean autoplaySelection = false;
52 | public static String defaultSelectionFile = "";
53 |
54 | public static boolean autoplayPlaylist = false;
55 | public static String defaultPlaylistFile = "";
56 |
57 | /**
58 | * Loads the settings to the static variables using the mdp3_Util
59 | * Settings methods
60 | *
61 | * Currently hardcoded to use filename of settings.txt
62 | */
63 | public static void loadSettings() {
64 | loadSettings("settings.txt");
65 | }
66 |
67 | /**
68 | * Loads the settings to the static variables using the mdp3_Util
69 | * Settings methods
70 | *
71 | * @param fileName
72 | */
73 | public static void loadSettings(String fileName) {
74 | LOG.entering(name, "loadSettings", "Filename: " + fileName);
75 |
76 | SettingsLoader set = new SettingsLoader(LedTable_Settings.class, false);
77 |
78 | //URL url = SettingsTest.class.getResource("SettingsTest.txt");
79 | //File file = new File(url.getPath());
80 | set.loadSettings(fileName);
81 |
82 | checkSettings();
83 |
84 | LOG.exiting(name, "loadSettings");
85 | }
86 |
87 | /**
88 | * Method to run to bounds check variables after being loaded from file
89 | */
90 | public static void checkSettings() {
91 | //Check bounds, must have atleast 1 row of each
92 | if (ledX < 1) {
93 | LOG.warning("Error in settings: ledX < 1; changing value to ledX = 1");
94 | ledX = 1;
95 | }
96 |
97 | if (ledY < 1) {
98 | LOG.warning("Error in settings: ledY < 1; changing value to ledY = 1");
99 | ledY = 1;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/AnimationEffect.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable.effects;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
7 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
8 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
9 | import net.mdp3.java.rpi.ledtable.table.Table;
10 |
11 | public class AnimationEffect extends Effect {
12 | private final static String name = "AnimationEffect";
13 |
14 | protected File[] fileList;
15 |
16 | protected byte[][] imageAr;
17 |
18 | protected boolean fade = false;
19 | protected int numOfFrames = 10;
20 | protected int fadeDelay = 10;
21 |
22 | public AnimationEffect(Table t, LedTable_Selection s) {
23 | super(t, s);
24 |
25 | if(s.getParams().get("fade") != null) this.fade = Boolean.parseBoolean(s.getParams().get("fade"));
26 | if(s.getParams().get("numOfFrames") != null) this.numOfFrames = Integer.parseInt(s.getParams().get("numOfFrames"));
27 | if(s.getParams().get("fadeDelay") != null) this.fadeDelay = Integer.parseInt(s.getParams().get("fadeDelay"));
28 |
29 | String f = selection.getParams().get("folder");
30 | File folder;
31 | if (f != null && f != "") {
32 | folder = new File(f);
33 | fileList = folder.listFiles();
34 | loadImages();
35 | }
36 | }
37 |
38 | public void effectsLoop() {
39 | for (int i = 0; i < fileList.length; i++) {
40 | if (run) { //checked again so that when the mode changes, the thread can quit on the next frame
41 | if (i < imageAr.length) {
42 | if (!this.fade)
43 | table.write(imageAr[i]);
44 | else {
45 | try {
46 | Effect_Util.fade(this, table, imageAr[i], numOfFrames, fadeDelay);
47 | table.write(imageAr[i]);
48 | } catch (InterruptedException e) {
49 | e.printStackTrace();
50 | }
51 | }
52 | }
53 | delay();
54 | }
55 | }
56 | }
57 |
58 | public long getRuntime() {
59 | return this.delay * fileList.length;
60 | }
61 |
62 | protected byte[] loadImage(String imgPath) {
63 | LOG.entering(name, "loadImage", imgPath);
64 |
65 | byte tableAr[] = null;
66 | try {
67 | tableAr = LedTable_Util.loadImage(imgPath).clone();
68 | }
69 | catch (IOException ioe) {
70 | LOG.info("Error opening file: " + ioe);
71 | ioe.printStackTrace();
72 | }
73 |
74 | LOG.exiting(name, "loadImage", tableAr);
75 | return tableAr;
76 | }
77 |
78 | protected void loadImages() {
79 | LOG.entering(name, "loadImages");
80 |
81 | imageAr = new byte[fileList.length][];
82 |
83 | for (int i = 0; i < fileList.length; i++) {
84 | imageAr[i] = loadImage(fileList[i].getAbsolutePath());
85 | }
86 |
87 | LOG.exiting(name, "loadImages");
88 | }
89 |
90 | @Override
91 | public EffectInfo setEffectInfo() {
92 | EffectInfoParameter[] paramInfo = {
93 | new EffectInfoParameter("fade", "Toggle Fading between Images", EffectInfoParameterType.BOOL),
94 | new EffectInfoParameter("numOfFrames", "Number of Frames to fade", EffectInfoParameterType.INT, 1, 1000),
95 | new EffectInfoParameter("fadeDelay", "Time between each fade frame", EffectInfoParameterType.INT, 1, 20000),
96 | new EffectInfoParameter("folder", "Folder to select images from", EffectInfoParameterType.FOLDER)
97 | };
98 | EffectInfo ei = new EffectInfo("AnimationEffect", "Can show images in a folder", paramInfo);
99 |
100 | return ei;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/Effect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.awt.Color;
7 | import java.util.Random;
8 | import java.util.logging.Logger;
9 |
10 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
11 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
12 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
13 | import net.mdp3.java.rpi.ledtable.table.Table;
14 |
15 | /**
16 | * Effect class is abstract class meant to be extended to add new complex
17 | * threaded effects to the Led Table. It sets up the main thread and gets
18 | * called from LedTable.java to start the effect loop without hanging the
19 | * main app.
20 | *
21 | * When adding a new effect, a new mode entry should be added to
22 | * LedTable_Selection.Mode with the class name if one is needed. This will
23 | * allow the class to be loaded via Reflection in LedTable.newSelection
24 | * without having to constantly update a big switch statement.
25 | *
26 | * @author Mikel
27 | *
28 | */
29 | public abstract class Effect extends Thread {
30 | protected final static Logger LOG = Logger.getLogger(Effect.class.getName());
31 | private final static String name = "Effect";
32 |
33 | protected Table table = null;
34 | protected LedTable_Selection selection;
35 | protected Color[][] tableC = LedTable_Util.getTableColor();
36 |
37 | protected boolean run = false;
38 | protected long delay = 100;
39 | protected int minDelay = 1;
40 | protected int maxDelay = 1000;
41 |
42 | protected EffectInfo effectInfo;
43 |
44 | protected Random rnd = new Random();
45 |
46 | public Effect(Table t, LedTable_Selection s) {
47 | LOG.entering(name, "new");
48 |
49 | this.effectInfo = setEffectInfo();
50 | if (this.effectInfo == null) {
51 | LOG.warning("No Effect Info Set!");
52 | this.effectInfo = new EffectInfo("Unknown Effect", "Not Set", null);
53 | }
54 |
55 | //Common Parameters for all effects
56 | this.effectInfo.getParamInfo().add(0, new EffectInfoParameter("delay", "Main delay amount", EffectInfoParameterType.INT, this.minDelay, this.maxDelay));
57 |
58 | this.table = t;
59 | setMode(s);
60 |
61 | this.setPriority(Thread.MAX_PRIORITY);
62 |
63 | LOG.exiting(name, "new");
64 | }
65 |
66 | public Effect() {
67 | this.setPriority(Thread.MAX_PRIORITY);
68 | }
69 |
70 | public void setTable(Table t) {
71 | this.table = t;
72 | }
73 |
74 | public void setMode(LedTable_Selection s) {
75 | this.selection = s;
76 |
77 | if (s.getParams().get("delay") != null)
78 | this.setDelay(Long.parseLong(s.getParams().get("delay")));
79 | }
80 |
81 | public LedTable_Selection getSelection() {
82 | return this.selection;
83 | }
84 |
85 | public boolean isRunning() {
86 | return run;
87 | }
88 |
89 | public void setDelay(long t) {
90 | delay = t;
91 | }
92 |
93 | public long getDelay() {
94 | return delay;
95 | }
96 |
97 | public void stopEffect() {
98 | run = false;
99 | }
100 |
101 | protected void delay() {
102 | try {
103 | Thread.sleep(this.delay);
104 | } catch (InterruptedException e) {
105 | e.printStackTrace();
106 | }
107 | }
108 |
109 | public final void run() {
110 | run = true;
111 |
112 | while (run) {
113 | effectsLoop();
114 | }
115 | }
116 |
117 | /**
118 | * Main loop for the effect
119 | *
120 | * Must check variable run if looping inside of this loop to see if it
121 | * needs to be broke out of
122 | *
123 | * Should call delay in between loops
124 | */
125 | public abstract void effectsLoop();
126 |
127 | /**
128 | * Method to be implemented by subclasses. This will store data about the
129 | * effect, name, desc, parameters, etc.
130 | *
131 | * @Example Implementation:
132 | *
133 | * public EffectInfo setEffectInfo() {
134 | * EffectInfoParameter[] paramInfo = {
135 | * new EffectInfoParameter("fade", "Toggle Fading between Images", "bool"),
136 | * new EffectInfoParameter("numOfFrames", "Number of Frames to fade", "int", 1, 1000),
137 | * new EffectInfoParameter("fadeDelay", "Time between each fade frame", "int", 1, 20000)
138 | * };
139 | * EffectInfo ei = new EffectInfo("AnimationEffect", "Can show images in a folder", paramInfo);
140 | *
141 | * return ei;
142 | * }
143 | *
144 | * @return EffectInfo for the subclass
145 | */
146 | public abstract EffectInfo setEffectInfo();
147 |
148 | public EffectInfo getEffectInfo() {
149 | return this.effectInfo;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/EffectFactory.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.lang.reflect.Constructor;
7 | import java.util.logging.Logger;
8 |
9 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
10 | import net.mdp3.java.rpi.ledtable.table.Table;
11 |
12 | /**
13 | * @author Mikel
14 | *
15 | */
16 | public class EffectFactory {
17 | private final static Logger LOG = Logger.getLogger(EffectFactory.class.getName());
18 | private final static String name = "EffectFactory";
19 |
20 | public static Effect getEffect(EffectMode mode, Table table, LedTable_Selection s) throws Exception {
21 | LOG.entering(name, "getEffect", "mode: " + mode);
22 |
23 | Effect effect = null;
24 |
25 | if (mode.getEffectClass() != null) {
26 | LOG.fine("Loading Class with reflection " + mode);
27 | Class extends Effect> clazz = mode.getEffectClass();
28 | Constructor extends Effect> c = clazz.getConstructor(Table.class, LedTable_Selection.class);
29 | effect = c.newInstance(table, s);
30 | } else {
31 | LOG.warning("Warning: Possible Invalid Mode " + mode + ": Effect Class Not Set");
32 | }
33 |
34 | LOG.exiting(name, "getEffect", "Effect: " + effect);
35 |
36 | return effect;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/EffectInfo.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Arrays;
8 |
9 | import net.mdp3.java.util.xml.DomXml;
10 | import net.mdp3.java.util.xml.XmlHelper;
11 |
12 | import org.w3c.dom.Document;
13 | import org.w3c.dom.Element;
14 |
15 | /**
16 | * Data Container for Effect Info and parameter info
17 | *
18 | * @author Mikel
19 | *
20 | */
21 | public class EffectInfo implements DomXml {
22 | private String effectName;
23 | private String effectDesc;
24 |
25 | private ArrayList paramInfo = new ArrayList();
26 |
27 | public static final String NODE_NAME = "EffectInfo";
28 | public static final String NODE_EFFECT_NAME = "EffectName";
29 | public static final String NODE_EFFECT_DESC = "EffectDesc";
30 |
31 | public EffectInfo(String name, String desc, EffectInfoParameter[] paramInfo) {
32 | this.setEffectName(name);
33 | this.setEffectDesc(desc);
34 | this.setParamInfo(paramInfo);
35 | }
36 |
37 | public EffectInfoParameter[] getParamInfoAr() {
38 | return (EffectInfoParameter[]) paramInfo.toArray();
39 | }
40 |
41 | public ArrayList getParamInfo() {
42 | return this.paramInfo;
43 | }
44 |
45 | public void setParamInfo(EffectInfoParameter[] paramInfo) {
46 | if (paramInfo != null && paramInfo.length > 0)
47 | this.paramInfo.addAll(Arrays.asList(paramInfo));
48 | }
49 |
50 | public void setParamInfo(ArrayList paramInfoList) {
51 | if (paramInfoList != null)
52 | this.paramInfo = paramInfoList;
53 | }
54 |
55 | public void addParameterInfo(EffectInfoParameter newParam) {
56 | this.paramInfo.add(newParam);
57 | }
58 |
59 | public String getEffectDesc() {
60 | return effectDesc;
61 | }
62 |
63 | public void setEffectDesc(String effectDesc) {
64 | this.effectDesc = effectDesc;
65 | }
66 |
67 | public String getEffectName() {
68 | return effectName;
69 | }
70 |
71 | public void setEffectName(String effectName) {
72 | this.effectName = effectName;
73 | }
74 |
75 | public String toString() {
76 | String ret = "";
77 |
78 | ret += "Name: " + this.getEffectName();
79 | ret += "\nDesc: " + this.getEffectDesc();
80 |
81 | if (this.paramInfo.size() > 0) {
82 | ret += "\n\nParameter Info: \n";
83 |
84 | for (EffectInfoParameter eip : this.paramInfo) {
85 | ret += "\n" + eip.toString();
86 | }
87 | }
88 |
89 | return ret;
90 | }
91 |
92 | @Override
93 | public Element toXml(Document doc) {
94 | Element effectInfoE = doc.createElement(EffectInfo.NODE_NAME);
95 |
96 | effectInfoE.appendChild(XmlHelper.newTextElement(doc, EffectInfo.NODE_EFFECT_NAME, this.effectName));
97 | effectInfoE.appendChild(XmlHelper.newTextElement(doc, EffectInfo.NODE_EFFECT_DESC, this.effectDesc));
98 |
99 | Element eipListE = doc.createElement(EffectInfoParameter.NODE_NAME + "List");
100 |
101 | for (EffectInfoParameter eip : this.getParamInfo())
102 | eipListE.appendChild(eip.toXml(doc));
103 |
104 | effectInfoE.appendChild(eipListE);
105 |
106 | return effectInfoE;
107 | }
108 |
109 | @Override
110 | public void fromXml(Element e) throws Exception {
111 | //Not Used
112 | throw new Exception("Effect Info fromXml not implemented");
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/EffectInfoParameter.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable.effects;
2 |
3 | import net.mdp3.java.util.xml.DomXml;
4 | import net.mdp3.java.util.xml.XmlHelper;
5 |
6 | import org.w3c.dom.Document;
7 | import org.w3c.dom.Element;
8 |
9 | /**
10 | * Data container for Effect Parameter Info
11 | *
12 | * @author Mikel
13 | *
14 | */
15 | public class EffectInfoParameter implements DomXml {
16 | private String paramName;
17 | private String paramDesc;
18 | private EffectInfoParameterType paramDataType;
19 | private String[] paramValues;
20 |
21 | private int minValue = 0;
22 | private int maxValue = 0;
23 |
24 | public static final String NODE_NAME = "EffectInfoParameter";
25 | public static final String NODE_EIP_NAME = "Name";
26 | public static final String NODE_EIP_DESC = "Desc";
27 | public static final String NODE_EIP_DATATYPE = "DataType";
28 | public static final String NODE_EIP_MIN = "MinValue";
29 | public static final String NODE_EIP_MAX = "MaxValue";
30 | public static final String NODE_EIP_VALUE = "Value"; //TODO Implement taking an array of values
31 |
32 | public static enum EffectInfoParameterType {
33 | INT,
34 | BOOL,
35 | STRING,
36 | SELECT, //probably be used for most string eips, switches to use String Array
37 | FOLDER,
38 | FILE
39 | }
40 |
41 | //TODO Add taking in values list for String types
42 | public EffectInfoParameter(String name, String desc, EffectInfoParameterType dataType) {
43 | this(name, desc, dataType, 0, 0);
44 | }
45 |
46 | public EffectInfoParameter(String name, String desc, String[] valuesAr) {
47 | this(name, desc, EffectInfoParameterType.SELECT, 0, 0);
48 | this.setValues(valuesAr);
49 | }
50 |
51 | public EffectInfoParameter(String name, String desc, EffectInfoParameterType dataType, int min, int max) {
52 | this.setParamName(name);
53 | this.setParamDesc(desc);
54 | this.setParamDataType(dataType);
55 | this.setMinValue(min);
56 | this.setMaxValue(max);
57 | }
58 |
59 | public void setValues(String[] values) {
60 | this.paramValues = values;
61 | }
62 |
63 | public String[] getValues() {
64 | return this.paramValues;
65 | }
66 |
67 | public int getMaxValue() {
68 | return maxValue;
69 | }
70 |
71 | public void setMaxValue(int maxValue) {
72 | this.maxValue = maxValue;
73 | }
74 |
75 | public int getMinValue() {
76 | return minValue;
77 | }
78 |
79 | public void setMinValue(int minValue) {
80 | this.minValue = minValue;
81 | }
82 |
83 | public EffectInfoParameterType getParamDataType() {
84 | return paramDataType;
85 | }
86 |
87 | public void setParamDataType(EffectInfoParameterType paramDataType) {
88 | this.paramDataType = paramDataType;
89 | }
90 |
91 | public String getParamDesc() {
92 | return paramDesc;
93 | }
94 |
95 | public void setParamDesc(String paramDesc) {
96 | this.paramDesc = paramDesc;
97 | }
98 |
99 | public String getParamName() {
100 | return paramName;
101 | }
102 |
103 | public void setParamName(String paramName) {
104 | this.paramName = paramName;
105 | }
106 |
107 | public String toString() {
108 | String ret = "";
109 |
110 | ret += "Name: " + this.getParamName();
111 | ret += "\nDesc: " + this.getParamDesc();
112 | ret += "\nData Type: " + this.getParamDataType();
113 |
114 | if (this.getMinValue() != 0 || this.getMaxValue() != 0) {
115 | ret += "\nMin Value: " + this.getMinValue();
116 | ret += "\nMax Value: " + this.getMaxValue();
117 | }
118 |
119 | return ret;
120 | }
121 |
122 | @Override
123 | public Element toXml(Document doc) {
124 | Element eipE = doc.createElement(EffectInfoParameter.NODE_NAME);
125 |
126 | eipE.appendChild(XmlHelper.newTextElement(doc, EffectInfoParameter.NODE_EIP_NAME, this.paramName));
127 | eipE.appendChild(XmlHelper.newTextElement(doc, EffectInfoParameter.NODE_EIP_DESC, this.paramDesc));
128 | eipE.appendChild(XmlHelper.newTextElement(doc, EffectInfoParameter.NODE_EIP_DATATYPE, this.paramDataType.toString()));
129 |
130 | if (this.minValue != 0 || this.maxValue != 0) {
131 | eipE.appendChild(XmlHelper.newTextElement(doc, EffectInfoParameter.NODE_EIP_MIN, this.minValue));
132 | eipE.appendChild(XmlHelper.newTextElement(doc, EffectInfoParameter.NODE_EIP_MAX, this.maxValue));
133 | } else {
134 | if (this.paramValues != null && this.paramValues.length > 0) {
135 | Element eipValuesListE = doc.createElement(EffectInfoParameter.NODE_EIP_VALUE + "List");
136 |
137 | for (String value : this.paramValues) {
138 | eipValuesListE.appendChild(XmlHelper.newTextElement(doc, NODE_EIP_VALUE, value));
139 | }
140 |
141 | eipE.appendChild(eipValuesListE);
142 | }
143 | }
144 |
145 | return eipE;
146 | }
147 |
148 | @Override
149 | public void fromXml(Element e) throws Exception {
150 | //Not Used
151 | throw new Exception("fromXml for EffectInfoParameter is not used");
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/EffectMode.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import net.mdp3.java.util.xml.DomXml;
7 | import net.mdp3.java.util.xml.XmlHelper;
8 |
9 | import org.w3c.dom.Document;
10 | import org.w3c.dom.Element;
11 |
12 | /**
13 | * @author Mikel
14 | *
15 | */
16 | public enum EffectMode implements DomXml {
17 | OFF( "Off"),
18 | PULSE1(PulseEffect.class, "Pulse Effect"),
19 | //PULSE2(PulseEffect.class, "Pulse 2 Not Available"),
20 | RAW,
21 | SET_COLOR(SetColorEffect.class, "Set Color"),
22 | //PULSE_RANDOM(PulseEffect.class),
23 | IMAGE( "Set Image"),//TODO Create Set Image Effect
24 | ANIMATION(AnimationEffect.class, "Animate"),
25 | //MIDI(MidiEffect.class, "Midi Reactive Effect (NA)"),
26 | RAINBOW(RainbowEffect.class, "Rainbow Colors"),
27 | IMAGE_SCAN(ImageScanEffect.class, "Image Scan"),
28 | //ANIM_TRANS(TransparencyAnimationEffect.class, "Image with Transparency"),
29 | RANDOM_FILL(RandomFillEffect.class, "Random Fill");
30 |
31 | public static final String NODE_NAME = "EffectMode";
32 | public static final String NODE_MODE_NAME = "ModeName";
33 | public static final String NODE_MODE_DESC = "ModeDescName";
34 | public static final String NODE_MODE_CLASS = "ModeClass";
35 |
36 | Class extends Effect> effectClass;
37 | String name = "";
38 |
39 | private EffectMode() {
40 | this(null, "");
41 | }
42 |
43 | private EffectMode(String name) {
44 | this(null, name);
45 | }
46 |
47 | private EffectMode(Class extends Effect> effectClass) {
48 | this(effectClass, "");
49 | }
50 |
51 | private EffectMode(Class extends Effect> effectClass, String name) {
52 | this.effectClass = effectClass;
53 | this.name = name;
54 | }
55 |
56 | public Class extends Effect> getEffectClass() {
57 | return this.effectClass;
58 | }
59 |
60 | public String getDescName() {
61 | //if (this.name != null && this.name.length() > 0)
62 | return this.name;
63 | //else return this.name();
64 | }
65 |
66 | @Override
67 | public Element toXml(Document doc) {
68 | Element effectModeE = doc.createElement(EffectMode.NODE_NAME);
69 |
70 | effectModeE.appendChild(XmlHelper.newTextElement(doc, EffectMode.NODE_MODE_NAME, this.name()));
71 | if (this.getDescName() != null)
72 | effectModeE.appendChild(XmlHelper.newTextElement(doc, EffectMode.NODE_MODE_DESC, this.getDescName()));
73 | if (this.getEffectClass() != null)
74 | effectModeE.appendChild(XmlHelper.newTextElement(doc, EffectMode.NODE_MODE_CLASS, this.getEffectClass().getName()));
75 |
76 | return effectModeE;
77 | }
78 |
79 | @Override
80 | public void fromXml(Element e) throws Exception {
81 | //Not implemented
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/Effect_Util.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.awt.Color;
7 | import java.io.IOException;
8 | import java.lang.reflect.Field;
9 | import java.util.Arrays;
10 | import java.util.logging.Logger;
11 |
12 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
13 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
14 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
15 | import net.mdp3.java.rpi.ledtable.table.Table;
16 | import net.mdp3.java.util.string.StringUtils;
17 |
18 | /**
19 | * @author Mikel
20 | *
21 | */
22 | public class Effect_Util {
23 | private final static Logger LOG = Logger.getLogger(Effect_Util.class.getName());
24 | private final static String NAME = "Effect_Util";
25 |
26 | /**
27 | * Uses the current tableAr in LedTable_Util and fades it towards the finishAr
28 | *
29 | * @param e Reference to the Effect that object that is calling Fade, used to check if it is still running to break out of the loop. Can be null
30 | * @param t LedTable to output to
31 | * @param finishAr byte array to fade to
32 | * @param numOfFrames number of frames to fade over
33 | * @param delay time between each frame
34 | * @throws InterruptedException
35 | */
36 | public static void fade(Effect e, Table t, byte[] finishAr, int numOfFrames, int delay) throws InterruptedException {
37 | LOG.entering(NAME, "fade");
38 |
39 | if (numOfFrames < 1) return;
40 | if (delay < 1) return;
41 |
42 | byte[] lastWrite = Arrays.copyOf(t.getLastWrite(), t.getLastWrite().length);
43 | if (lastWrite == null) {
44 | LOG.warning("Last Write not Initialized");
45 | return;
46 | }
47 |
48 | if (finishAr.length != lastWrite.length) {
49 | LOG.severe("Invalid Array Lengths");
50 | return;
51 | }
52 |
53 | for (int i = 0; i < numOfFrames; i++) {
54 | //Simple change of every byte in the array by frame/numberofframes amount
55 | for (int j = 0; j < lastWrite.length; j++) {
56 | int diff = (int)(lastWrite[j] & 0xFF) - (int)(finishAr[j] & 0xFF);
57 | diff /= numOfFrames;
58 | lastWrite[j] -= diff;
59 | }
60 |
61 | t.write(lastWrite);
62 |
63 | if (e == null || e.isRunning()) {
64 | Thread.sleep(delay);
65 | } else {
66 | return;
67 | }
68 | }
69 |
70 | LOG.exiting(NAME, "fade");
71 | }
72 |
73 | /**
74 | * Changes the table to the specified color
75 | *
76 | * @param table
77 | * @param s
78 | * @throws Exception
79 | */
80 | public static void colorSelection(Table table, LedTable_Selection s) throws Exception {
81 | boolean colorsSet = false;
82 |
83 | byte r = 0;
84 | byte g = 0;
85 | byte b = 0;
86 |
87 | if (s.getParams().get("color") != null && s.getParams().get("color") != "") {
88 | String colorStr = s.getParams().get("color");
89 | final Field f = Color.class.getField(colorStr);
90 | Color color = (Color) f.get(null);
91 |
92 | if (color != null) {
93 | r = (byte)color.getRed();
94 | g = (byte)color.getGreen();
95 | b = (byte)color.getBlue();
96 |
97 | colorsSet = true;
98 | }
99 | } else if (s.getParams().get("r") != null && s.getParams().get("r") != "" &&
100 | s.getParams().get("g") != null && s.getParams().get("g") != "" &&
101 | s.getParams().get("b") != null && s.getParams().get("b") != "") {
102 |
103 | int iR = StringUtils.tryParseInt(s.getParams().get("r"));
104 | int iG = StringUtils.tryParseInt(s.getParams().get("g"));
105 | int iB = StringUtils.tryParseInt(s.getParams().get("b"));
106 |
107 | r = (byte) iR;
108 | g = (byte) iG;
109 | b = (byte) iB;
110 |
111 | colorsSet = true;
112 | } else throw new Exception("Invalid Color Selection for Mode");
113 |
114 | if (colorsSet) {
115 | table.write(LedTable_Util.getRGBArray(r, g, b));
116 | }
117 | }
118 |
119 | public static void showImage(Table table, LedTable_Selection s) {
120 | int x = 0;
121 | int y = 0;
122 | boolean scaleToFit = false;
123 |
124 | if (s.getParams().get("x") != null) x = Integer.parseInt(s.getParams().get("x"));
125 | if (s.getParams().get("y") != null) y = Integer.parseInt(s.getParams().get("y"));
126 | if (s.getParams().get("scale") != null) scaleToFit = Boolean.parseBoolean(s.getParams().get("scale"));
127 |
128 | String img = s.getParams().get("img");
129 | if (img == null || img == "") return;
130 |
131 | try {
132 | if (scaleToFit)
133 | table.write(LedTable_Util.loadImage(img, x, y, LedTable_Settings.ledX, LedTable_Settings.ledY));
134 | else
135 | table.write(LedTable_Util.loadImage(img, x, y));
136 | } catch (IOException e) {
137 | LOG.warning("Error load image: " + img + " x: " + x + " y: " + y);
138 | e.printStackTrace();
139 | }
140 | }
141 |
142 | /**
143 | * Returns a Color object created from the parameters for Selection
144 | *
145 | * @param s
146 | * @return
147 | * @throws Exception
148 | */
149 | protected static Color loadColor(LedTable_Selection s) throws Exception {
150 | int r = 0;
151 | int g = 0;
152 | int b = 0;
153 |
154 | if (s.getParams().get("color") != null && s.getParams().get("color") != "") {
155 | String colorStr = s.getParams().get("color");
156 | final Field f = Color.class.getField(colorStr);
157 | Color color = (Color) f.get(null);
158 |
159 | if (color != null) {
160 | r = color.getRed();
161 | g = color.getGreen();
162 | b = color.getBlue();
163 | }
164 | } else if (s.getParams().get("r") != null && s.getParams().get("r") != "" &&
165 | s.getParams().get("g") != null && s.getParams().get("g") != "" &&
166 | s.getParams().get("b") != null && s.getParams().get("b") != "") {
167 |
168 | r = StringUtils.tryParseInt(s.getParams().get("r"));
169 | g = StringUtils.tryParseInt(s.getParams().get("g"));
170 | b = StringUtils.tryParseInt(s.getParams().get("b"));
171 | } else throw new Exception("Invalid Color Selection");
172 |
173 | Color c = new Color(r, g, b);
174 | return c;
175 | }
176 |
177 | protected static void drawSquare(Color[][] colorAr, int startX, int startY, int w, int h, Color color, boolean fill) {
178 | if (startX < 0) return;
179 | if (startY < 0) return;
180 | if (colorAr.length < 1) return;
181 | if (startX >= colorAr[0].length) return;
182 | if (startY >= colorAr.length) return;
183 | if (w <= 0) return;
184 | if (h <= 0) return;
185 |
186 | int stopX = startX + w;
187 | int stopY = startY + h;
188 |
189 | for (int y = startY; y <= stopY; y++) {
190 | for (int x = startX; x <= stopX; x++) {
191 | if (fill) {
192 | colorAr[y][x] = color;
193 | } else {
194 | if (x == startX || y == startY || x == stopX || y == stopY) {
195 | colorAr[y][x] = color;
196 | }
197 | }
198 | }
199 | }
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/ImageScanEffect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.io.IOException;
7 | import java.util.Random;
8 |
9 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
10 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
11 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
12 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
13 | import net.mdp3.java.rpi.ledtable.table.Table;
14 |
15 | /**
16 | * @author Mikel
17 | *
18 | */
19 | public class ImageScanEffect extends Effect {
20 | private final static String name = "ImageScanEffect";
21 |
22 | private Random rnd = new Random();
23 |
24 | private String imgPath = "";
25 | private boolean imageLoaded = false;
26 | private int inc = 1;
27 | private int x = 0;
28 | private int y = 0;
29 |
30 | public ImageScanEffect(Table t, LedTable_Selection s) {
31 | super(t, s);
32 |
33 | if (s.getParams().get("img") != null) this.imgPath = s.getParams().get("img");
34 | if (s.getParams().get("inc") != null) this.inc = Integer.parseInt(s.getParams().get("inc"));
35 | if (inc < 1) inc = 1;
36 |
37 | if (imgPath != "") {
38 | try {
39 | LedTable_Util.loadImage(imgPath);
40 | imageLoaded = true;
41 | } catch (IOException e) {
42 | LOG.warning("Error loading Image: " + imgPath);
43 | e.printStackTrace();
44 | }
45 | }
46 | }
47 |
48 | @Override
49 | public EffectInfo setEffectInfo() {
50 | EffectInfoParameter[] paramInfo = {
51 | new EffectInfoParameter("img", "Path to Image File", EffectInfoParameterType.FILE),
52 | new EffectInfoParameter("inc", "Number of pixels to move by", EffectInfoParameterType.INT, 1, 100)
53 | };
54 | EffectInfo ei = new EffectInfo("ImageScanEffect",
55 | "Randomly moves around a portion of a larger image", paramInfo);
56 |
57 | return ei;
58 | }
59 |
60 | @Override
61 | public void effectsLoop() {
62 | this.scan();
63 | }
64 |
65 | private void scan() {
66 | LOG.entering(name, "scan");
67 |
68 | if (imageLoaded && run) {
69 | try {
70 | getNextCoords();
71 |
72 | LOG.finer("Displaying Image at x:" + x + ", y:" + y);
73 | table.write(LedTable_Util.getImagePart(this.x, this.y));
74 |
75 | delay();
76 | } catch (IOException e) {
77 | LOG.warning("Error Displaying Image part image: " + this.imgPath + " x:"+ this.x + ", y:" + this.y);
78 | e.printStackTrace();
79 | }
80 | }
81 |
82 | LOG.exiting(name, "scan");
83 | }
84 |
85 | private void getNextCoords() {
86 | LOG.entering(name, "getNextCoords");
87 | LOG.finer("Old Coords x:" + this.x + ", y:" + this.y + " inc: " + this.inc);
88 |
89 | int dirX = rnd.nextInt(3);
90 | int dirY = rnd.nextInt(3);
91 |
92 | switch (dirX) {
93 | case 0: this.x += this.inc;
94 | break;
95 | case 1: break;
96 | case 2: this.x -= this.inc;
97 | break;
98 | }
99 |
100 | switch (dirY) {
101 | case 0: this.y += this.inc;
102 | break;
103 | case 1: break;
104 | case 2: this.y -= this.inc;
105 | break;
106 | }
107 |
108 | //bounds check
109 | if (x < 0) x = 0;
110 | if (y < 0) y = 0;
111 | if (x > LedTable_Util.getImage().getWidth() - LedTable_Settings.ledX) x = LedTable_Util.getImage().getWidth() - LedTable_Settings.ledX;
112 | if (y > LedTable_Util.getImage().getHeight() - LedTable_Settings.ledY) y = LedTable_Util.getImage().getHeight() - LedTable_Settings.ledY;
113 |
114 | LOG.finer("New Coords x:" + this.x + ", y:" + this.y + " inc: " + this.inc);
115 | LOG.exiting(name, "getNextCoords");
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/MidiEffect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.util.LinkedList;
7 | import java.util.Random;
8 |
9 | import javax.sound.midi.MidiDevice;
10 | import javax.sound.midi.MidiMessage;
11 | import javax.sound.midi.MidiSystem;
12 | import javax.sound.midi.MidiUnavailableException;
13 | import javax.sound.midi.Receiver;
14 | import javax.sound.midi.ShortMessage;
15 | import javax.sound.midi.Transmitter;
16 |
17 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
18 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
19 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
20 | import net.mdp3.java.rpi.ledtable.table.Table;
21 |
22 | /**
23 | * @author Mikel
24 | *
25 | */
26 | public class MidiEffect extends Effect implements Receiver {
27 |
28 | private LinkedList openDevices = new LinkedList();
29 | private LinkedList transmitters = new LinkedList();
30 |
31 | private int mode = 1;
32 | private final int NOTE = 144; //0x90
33 |
34 | Random rand = new Random();
35 | private boolean devicesLoaded = false;
36 |
37 | public MidiEffect(Table t, LedTable_Selection s) {
38 | super(t, s);
39 | }
40 |
41 | @Override
42 | public EffectInfo setEffectInfo() {
43 | EffectInfoParameter[] paramInfo = {
44 | //TODO add parameter info
45 | };
46 | EffectInfo ei = new EffectInfo("MidiEffect",
47 | "Listens to midi info and does stuff", paramInfo);
48 |
49 | return ei;
50 | }
51 |
52 | public void effectsLoop() {
53 | if (!devicesLoaded) {
54 | loadInputDevices();
55 | }
56 | updateTable();
57 |
58 | if (run) {
59 | delay();
60 | } else { //extra check to close inputs cleanly
61 | close();
62 | }
63 | }
64 |
65 | public void setMode(int m) {
66 | this.mode = m;
67 | }
68 |
69 | public void stopEffect() {
70 | LOG.finer("Stopping Midi Thread!");
71 | if (run) {
72 | run = false;
73 | close();
74 | }
75 | }
76 |
77 | private boolean loadInputDevices() {
78 | MidiDevice device = null;
79 | MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
80 | boolean deviceLoaded = false;
81 |
82 | for (int i = 0; i < infos.length; i++) {
83 | System.out.println(i + ": " + infos[i].getName());
84 | try {
85 | device = MidiSystem.getMidiDevice(infos[i]);
86 | System.out.println(" " + i + " class: " + device.getClass().getName());
87 | System.out.println(" " + i + " receivers: " + device.getMaxReceivers());
88 | System.out.println(" " + i + " transmitters: " + device.getMaxTransmitters());
89 |
90 | if (device.getClass().getName().equalsIgnoreCase("com.sun.media.sound.MidiInDevice")) {
91 | System.out.println("MIDI In Found!");
92 | if (!device.isOpen() && device.getMaxTransmitters() != 0) {
93 | device.open();
94 | openDevices.addLast(device);
95 |
96 | Transmitter t = device.getTransmitter();
97 | transmitters.addLast(t);
98 | t.setReceiver(this);
99 |
100 | deviceLoaded = true;
101 | }
102 | }
103 | device = null;
104 | }
105 | catch (MidiUnavailableException e) {
106 | System.out.println("Error loading device " + i + " " + e);
107 | }
108 | }
109 |
110 | this.devicesLoaded = deviceLoaded;
111 | return deviceLoaded;
112 | }
113 |
114 | @Override
115 | public void close() {
116 | for (int i = 0; i < transmitters.size(); i++)
117 | transmitters.get(i).close();
118 | for (int i = 0; i < openDevices.size(); i++)
119 | openDevices.get(i).close();
120 | run = false;
121 | }
122 |
123 | @Override
124 | public void send(MidiMessage arg0, long arg1) {
125 | ShortMessage message = new LedTable_ShortMessage(arg0.getMessage());
126 |
127 | if (LedTable_Settings.debug)
128 | System.out.println("MIDIMessage [Channel: " + message.getChannel()
129 | + ", Command: " + message.getCommand() + ", Data1: " + message.getData1()
130 | + ", Data2: " + message.getData2() + ']');
131 |
132 | if (mode == 1) handleMidi(message.getCommand(), message.getData1(), message.getData2());
133 | }
134 |
135 | /**
136 | * handleMidi
137 | *
138 | * Midi Handler to switch modes
139 | *
140 | * @param cmd Midi Command
141 | * @param data1 Midi Data 1 (Typically Note)
142 | * @param data2 Midi Data 2 (Typically Velocity)
143 | */
144 | private void handleMidi(int cmd, int data1, int data2) {
145 | if (mode == 1) handleMidiMode1(cmd, data1, data2);
146 | }
147 |
148 | /**
149 | * handleMidiMode1
150 | *
151 | * Mode 1 for Midi Input, Controls how the table initially reacts to Midi Input
152 | *
153 | * @param cmd
154 | * @param data1
155 | * @param data2
156 | */
157 | private void handleMidiMode1(int cmd, int data1, int data2) {
158 | if (cmd == NOTE) {
159 | int scaleNote = data1 % 12;
160 | LedTable_Util.getTableAr()[0][scaleNote * 3] = (byte) rand.nextInt(255); //data2 * 2; //R
161 | LedTable_Util.getTableAr()[0][scaleNote * 3 + 1] = (byte) rand.nextInt(255); //data2 * 2; //G
162 | LedTable_Util.getTableAr()[0][scaleNote * 3 + 2] = (byte) rand.nextInt(255); //data2 * 2; //B
163 | }
164 | }
165 |
166 | /**
167 | * updateTable
168 | *
169 | * Function called from the Run method when thread is running, this
170 | * method calls different table utility update methods based on the mode.
171 | * This allows the table leds to change when there is no midi input.
172 | */
173 | private void updateTable() {
174 | if (mode == 1) {
175 | //TODO implement this
176 | }
177 | }
178 |
179 | /**
180 | * LedTable_ShortMessage
181 | * @author Mikel
182 | *
183 | * Simple class extended from javax.sound.midi.ShortMessage to be able
184 | * to use the protected new ShortMessage(byte[]) method.
185 | */
186 | private class LedTable_ShortMessage extends ShortMessage {
187 | public LedTable_ShortMessage(byte[] bAr) {
188 | super(bAr);
189 | }
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/PulseEffect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
7 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
8 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
9 | import net.mdp3.java.rpi.ledtable.table.Table;
10 | import net.mdp3.java.util.string.StringUtils;
11 |
12 | /**
13 | * @author Mikel
14 | *
15 | */
16 | public class PulseEffect extends Effect {
17 | private final static String name = "PulseEffect";
18 |
19 | private int pulseInc = 1;
20 | private PulseType pulseType = PulseType.RGB;
21 |
22 | private int oldR = 0;
23 | private int oldG = 0;
24 | private int oldB = 0;
25 |
26 | private static enum PulseType {
27 | RGB,
28 | RGB2,
29 | RANDOM,
30 | RANDOM2,
31 | RANDOM3
32 | }
33 |
34 | public PulseEffect(Table t, LedTable_Selection s) {
35 | super(t, s);
36 | delay = 1;
37 | setMode(s);
38 |
39 | table.write(LedTable_Util.getRGBArray(0, 0, 0));
40 | }
41 |
42 | @Override
43 | public EffectInfo setEffectInfo() {
44 | EffectInfoParameter[] paramInfo = {
45 | new EffectInfoParameter("inc", "Amount to change colors by", EffectInfoParameterType.INT, 1, 100),
46 | new EffectInfoParameter("pulseType", "Pulse Type Mode", StringUtils.enumToString(PulseType.class))
47 | };
48 | EffectInfo ei = new EffectInfo("PulseEffect",
49 | "Fades the table color in and out", paramInfo);
50 |
51 | return ei;
52 | }
53 |
54 | public void setMode(LedTable_Selection s) {
55 | super.setMode(s);
56 |
57 | if(s.getParams().get("inc") != null) this.pulseInc = Integer.parseInt(s.getParams().get("inc"));
58 | if(s.getParams().get("pulseType") != null) this.pulseType = PulseType.valueOf(s.getParams().get("pulseType").toUpperCase());
59 | }
60 |
61 | @Override
62 | public void effectsLoop() {
63 | if (this.pulseType == PulseType.RGB) this.rgbPulse();
64 | else if (this.pulseType == PulseType.RGB2) this.rgbPulse2();
65 | else if (this.pulseType == PulseType.RANDOM) this.randomPulse();
66 | else if (this.pulseType == PulseType.RANDOM2) this.randomPulse2();
67 | else if (this.pulseType == PulseType.RANDOM3) this.randomPulse3();
68 | }
69 |
70 | private void rgbPulse() {
71 | LOG.entering(name, "rgbPulse");
72 |
73 | for (int i = 0; i <= 255; i += pulseInc) {
74 | if (!run) return;
75 |
76 | LOG.finer("pulse RED");
77 | table.write(LedTable_Util.getRGBArray(i, 0, 0));
78 | this.delay();
79 | }
80 | for (int i = 0; i <= 255; i += pulseInc) {
81 | if (!run) return;
82 |
83 | LOG.finer("pulse GREEN");
84 | table.write(LedTable_Util.getRGBArray(0, i, 0));
85 | this.delay();
86 | }
87 | for (int i = 0; i <= 255; i += pulseInc) {
88 | if (!run) return;
89 |
90 | LOG.finer("pulse BLUE");
91 | table.write(LedTable_Util.getRGBArray(0, 0, i));
92 | this.delay();
93 | }
94 |
95 | LOG.exiting(name, "rgbPulse");
96 | }
97 |
98 | private void rgbPulse2() {
99 | LOG.entering(name, "rgbPulse2");
100 |
101 | for (int i = 0; i <= 255; i += pulseInc) {
102 | if (!run) return;
103 |
104 | table.write(LedTable_Util.getRGBArray(i, 0, 0));
105 | this.delay();
106 | }
107 | for (int i = 255; i >= 0; i -= pulseInc) {
108 | if (!run) return;
109 |
110 | table.write(LedTable_Util.getRGBArray(i, 0, 0));
111 | this.delay();
112 | }
113 | for (int i = 0; i <= 255; i += pulseInc) {
114 | if (!run) return;
115 |
116 | table.write(LedTable_Util.getRGBArray(0, i, 0));
117 | this.delay();
118 | }
119 | for (int i = 255; i >= 0; i -= pulseInc) {
120 | if (!run) return;
121 |
122 | table.write(LedTable_Util.getRGBArray(0, i, 0));
123 | this.delay();
124 | }
125 | for (int i = 0; i <= 255; i += pulseInc) {
126 | if (!run) return;
127 |
128 | table.write(LedTable_Util.getRGBArray(0, 0, i));
129 | this.delay();
130 | }
131 | for (int i = 255; i >= 0; i -= pulseInc) {
132 | if (!run) return;
133 |
134 | table.write(LedTable_Util.getRGBArray(0, 0, i));
135 | this.delay();
136 | }
137 |
138 | LOG.exiting(name, "rgbPulse");
139 | }
140 |
141 | /**
142 | * Fades to the next random color, once color type at a time R then G then B
143 | */
144 | private void randomPulse() {
145 | int newR = rnd.nextInt(256);
146 | int newG = rnd.nextInt(256);
147 | int newB = rnd.nextInt(256);
148 |
149 | while ((newR > oldR + pulseInc/2) || (newR < oldR - pulseInc/2)) {
150 | if (oldR < newR) {
151 | oldR += pulseInc;
152 | }
153 | else if (oldR > newR) {
154 | oldR -= pulseInc;
155 | }
156 |
157 | table.write(LedTable_Util.getRGBArray(oldR, oldG, oldB));
158 | if (!run) return;
159 | this.delay();
160 | }
161 | while ((newG > oldG + pulseInc/2) || (newG < oldG - pulseInc/2)) {
162 | if (oldG < newG) {
163 | oldG += pulseInc;
164 | }
165 | else if (oldG > newG) {
166 | oldG -= pulseInc;
167 | }
168 | table.write(LedTable_Util.getRGBArray(oldR, oldG, oldB));
169 | if (!run) return;
170 | this.delay();
171 | }
172 | while ((newB > oldB + pulseInc/2) || (newB < oldB - pulseInc/2)) {
173 | if (oldB < newB) {
174 | oldB += pulseInc;
175 | }
176 | else if (oldB > newB) {
177 | oldB -= pulseInc;
178 | }
179 | table.write(LedTable_Util.getRGBArray(oldR, oldG, oldB));
180 | if (!run) return;
181 | this.delay();
182 | }
183 | }
184 |
185 | /**
186 | * Different from randomPulse because it uses the fade method, which will
187 | * fade through all 3 colors at once instead of doing R then G then B
188 | */
189 | private void randomPulse2() {
190 | int newR = rnd.nextInt(256);
191 | int newG = rnd.nextInt(256);
192 | int newB = rnd.nextInt(256);
193 |
194 | byte[] newTable = LedTable_Util.getRGBArray(newR, newG, newB);
195 |
196 | try {
197 | Effect_Util.fade((Effect)this, table, newTable, pulseInc, (int)delay);
198 | delay();
199 | } catch (InterruptedException e) {
200 | e.printStackTrace();
201 | LOG.severe("Error in randomPulse2 waiting thread: " + e);
202 | }
203 |
204 | }
205 |
206 | private void randomPulse3() {
207 | int oldRed = table.getLastWrite()[0] & 0xFF;
208 | int oldGreen = table.getLastWrite()[1] & 0xFF;
209 | int oldBlue = table.getLastWrite()[2] & 0xFF;
210 |
211 | int newR;
212 | int newG;
213 | int newB;
214 |
215 | int colorToChange = rnd.nextInt(3);
216 |
217 | if (colorToChange == 0) newR = rnd.nextInt(256);
218 | else newR = oldRed;
219 |
220 | if (colorToChange == 0) newG = rnd.nextInt(256);
221 | else newG = oldGreen;
222 |
223 | if (colorToChange == 0) newB = rnd.nextInt(256);
224 | else newB = oldBlue;
225 |
226 | byte[] newTable = LedTable_Util.getRGBArray(newR, newG, newB);
227 |
228 | try {
229 | Effect_Util.fade((Effect)this, table, newTable, pulseInc, (int)delay);
230 | delay();
231 | } catch (InterruptedException e) {
232 | e.printStackTrace();
233 | LOG.severe("Error in randomPulse2 waiting thread: " + e);
234 | }
235 |
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/RainbowEffect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.awt.Color;
7 |
8 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
9 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
10 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
11 | import net.mdp3.java.rpi.ledtable.table.Table;
12 |
13 | /**
14 | * @author Mikel
15 | *
16 | */
17 | public class RainbowEffect extends Effect {
18 | private final static String name = "RainbowEffect";
19 |
20 | private int rbInc1 = 10;
21 | private int rbInc2 = 1;
22 | private int rbType = 1;
23 |
24 | public RainbowEffect(Table t, LedTable_Selection s) {
25 | super(t, s);
26 | setMode(s);
27 | }
28 |
29 | @Override
30 | public EffectInfo setEffectInfo() {
31 | EffectInfoParameter[] paramInfo = {
32 | new EffectInfoParameter("rbInc1", "Amount to change colors by", EffectInfoParameterType.INT, 1, 100),
33 | new EffectInfoParameter("rbInc2", "Other amount to change by", EffectInfoParameterType.INT, 1, 100),
34 | new EffectInfoParameter("rbType", "Rainbow Mode", EffectInfoParameterType.INT, 1, 2)
35 | };
36 | EffectInfo ei = new EffectInfo("RainbowEffect",
37 | "Changes between lots of colors", paramInfo);
38 |
39 | return ei;
40 | }
41 |
42 | public void setMode(LedTable_Selection s) {
43 | super.setMode(s);
44 |
45 | if(s.getParams().get("rbInc1") != null) this.rbInc1 = Integer.parseInt(s.getParams().get("rbInc1"));
46 | if(s.getParams().get("rbInc2") != null) this.rbInc2 = Integer.parseInt(s.getParams().get("rbInc2"));
47 | if(s.getParams().get("rbType") != null) this.rbType = Integer.parseInt(s.getParams().get("rbType"));
48 | }
49 |
50 | @Override
51 | public void effectsLoop() {
52 | if (rbType == 1) this.rainbow();
53 | else this.rainbow2();
54 | }
55 |
56 | private void rainbow() {
57 | LOG.entering(name, "rainbow");
58 |
59 | byte[] bAr = LedTable_Util.getbAr();
60 | //TODO Change to user tableAr[][] instead of byteAr[], the snake code is being passed over when ran
61 | for (int j=0; j < 256; j += rbInc1) { // 3 cycles of all 256 colors in the wheel
62 | for (int i = 0; i < LedTable_Util.getbAr().length; i += rbInc2) {
63 | Color c = wheel((i + j) % 255);
64 | bAr[i++] = (byte)c.getRed();
65 | bAr[i++] = (byte)c.getGreen();
66 | bAr[i] = (byte)c.getBlue();
67 | }
68 | table.write(bAr);
69 |
70 | if (!run) return;
71 | delay();
72 | }
73 |
74 | LOG.exiting(name, "rainbow");
75 | }
76 |
77 | private void rainbow2() {
78 | for (int j = 0; j < 256; j += rbInc1) {
79 | for (int y = 0; y < LedTable_Util.getTableAr().length; y++) {
80 | for (int x = 0; x < LedTable_Util.getTableAr()[y].length; x++) {
81 | Color c = wheel((j + rbInc2) % 255);
82 | LedTable_Util.getTableAr()[y][x] = (byte)c.getRed();
83 | LedTable_Util.getTableAr()[y][x++] = (byte)c.getGreen();
84 | LedTable_Util.getTableAr()[y][x++] = (byte)c.getBlue();
85 |
86 | table.write(LedTable_Util.tableArToByteAr());
87 |
88 | if (!run) return;
89 | delay();
90 | }
91 | }
92 | }
93 | }
94 |
95 | private Color wheel(int pos) {
96 | if (pos < 85) {
97 | return new Color(pos * 3, 255 - pos * 3, 0);
98 | } else if (pos < 170) {
99 | pos -= 85;
100 | return new Color(255 - pos * 3, 0, pos * 3);
101 | } else {
102 | pos -= 170;
103 | return new Color(0, pos * 3, 255 - pos * 3);
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/RandomFillEffect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import java.awt.Color;
7 | import java.util.Arrays;
8 | import java.util.Stack;
9 |
10 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
11 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
12 | import net.mdp3.java.rpi.ledtable.LedTable_Util;
13 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
14 | import net.mdp3.java.rpi.ledtable.table.Table;
15 | import net.mdp3.java.util.string.StringUtils;
16 |
17 | /**
18 | * @author Mikel
19 | *
20 | */
21 | public class RandomFillEffect extends Effect {
22 |
23 | private RandomMode randomType = RandomMode.FILL;
24 | private boolean enableFade = true;
25 | private boolean direction = true;
26 |
27 | private int totalNumOfPixels = LedTable_Settings.ledX * LedTable_Settings.ledY;
28 |
29 | private static enum RandomMode {
30 | FILL,
31 | RANDOM,
32 | RANDOM_TO_COLOR,
33 | SEQ,
34 | SEQ_RAND,
35 | DIRECTIONAL_FILL,
36 | SQUARES
37 | }
38 |
39 | /**
40 | * @param t
41 | * @param s
42 | */
43 | public RandomFillEffect(Table t, LedTable_Selection s) {
44 | super(t, s);
45 |
46 | setMode(s);
47 | }
48 |
49 | /* (non-Javadoc)
50 | * @see net.mdp3.java.rpi.ledtable.effects.Effect#effectsLoop()
51 | */
52 | @Override
53 | public void effectsLoop() {
54 | if (this.randomType == RandomMode.FILL) randomFill();
55 | else if (this.randomType == RandomMode.RANDOM) randomRandom();
56 | else if (this.randomType == RandomMode.RANDOM_TO_COLOR) randomToColor();
57 | else if (this.randomType == RandomMode.SEQ) randomSeq();
58 | else if (this.randomType == RandomMode.SEQ_RAND) randomSeqRandom();
59 | else if (this.randomType == RandomMode.DIRECTIONAL_FILL) randomDirectionFill();
60 | else if (this.randomType == RandomMode.SQUARES) randomRectangles();
61 | }
62 |
63 | /* (non-Javadoc)
64 | * @see net.mdp3.java.rpi.ledtable.effects.Effect#setEffectInfo()
65 | */
66 | @Override
67 | public EffectInfo setEffectInfo() {
68 | EffectInfoParameter[] paramInfo = {
69 | new EffectInfoParameter("randomType", "Random Type Mode", StringUtils.enumToString(RandomMode.class)),
70 | new EffectInfoParameter("enableFade", "Enable Fading between frames", EffectInfoParameterType.BOOL),
71 | new EffectInfoParameter("direction", "Direction to sequential fill", EffectInfoParameterType.BOOL),
72 | };
73 | EffectInfo ei = new EffectInfo("RandomFillEffect",
74 | "Sets pixels to random colors", paramInfo);
75 |
76 | return ei;
77 | }
78 |
79 | @Override
80 | public void setMode(LedTable_Selection s) {
81 | super.setMode(s);
82 |
83 | if(s.getParams().get("randomType") != null) this.randomType = RandomMode.valueOf(s.getParams().get("randomType").toUpperCase());
84 | if(s.getParams().get("enableFade") != null) this.enableFade = Boolean.parseBoolean(s.getParams().get("enableFade"));
85 | if(s.getParams().get("direction") != null) this.direction = Boolean.parseBoolean(s.getParams().get("direction"));
86 | }
87 |
88 | /**
89 | * Fill the table with all random colors
90 | */
91 | private void randomFill() {
92 | byte[] newTableAr = new byte[table.getLastWrite().length];
93 |
94 | for (int i = 0; i < newTableAr.length; i++) {
95 | newTableAr[i] = (byte) rnd.nextInt(256);
96 | }
97 |
98 | showTable(newTableAr);
99 | }
100 |
101 | /**
102 | * Changes a random amount of pixels on the table to a random color
103 | */
104 | private void randomRandom() {
105 | byte[] newTableAr = Arrays.copyOf(table.getLastWrite(), table.getLastWrite().length);
106 |
107 | int numOfPixelsToFill = rnd.nextInt(totalNumOfPixels);
108 |
109 | for (int i = 0; i < numOfPixelsToFill; i++) {
110 | int pixel = rnd.nextInt(totalNumOfPixels);
111 | pixel *= 3;
112 |
113 | newTableAr[pixel] = (byte) rnd.nextInt(256); //R
114 | newTableAr[pixel+1] = (byte) rnd.nextInt(256); //G
115 | newTableAr[pixel+2] = (byte) rnd.nextInt(256); //B
116 | }
117 |
118 | showTable(newTableAr);
119 | }
120 |
121 | /**
122 | * Randomly fills pixels on the table until it is full of the next random color
123 | */
124 | private void randomToColor() {
125 | byte[] newTableAr = Arrays.copyOf(table.getLastWrite(), table.getLastWrite().length);
126 |
127 | Color targetColor = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
128 |
129 | int numOfPixelsToFill = totalNumOfPixels;
130 | int numOfPixelsToFillAtATime = 1;
131 |
132 | Stack s = new Stack();
133 |
134 | int pixel = rnd.nextInt(totalNumOfPixels);
135 |
136 | for (int i = 0; i < numOfPixelsToFill; i++) {
137 | if (!run) return;
138 |
139 | for (int j = 0; j < numOfPixelsToFillAtATime; j++) {
140 | if (!run) return;
141 |
142 | while (s.contains(Integer.valueOf(pixel))) pixel = rnd.nextInt(totalNumOfPixels);
143 | s.push(Integer.valueOf(pixel));
144 |
145 | setPixelColor(newTableAr, pixel, targetColor);
146 | }
147 | showTable(newTableAr);
148 | }
149 | }
150 |
151 | /**
152 | * Fills the table sequentially with random colors, snake like effect if
153 | * leds are snaked
154 | */
155 | private void randomSeq() {
156 | byte[] newTableAr = Arrays.copyOf(table.getLastWrite(), table.getLastWrite().length);
157 |
158 | Color targetColor = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
159 |
160 | int numOfPixelsToFill = totalNumOfPixels;
161 |
162 | if (direction) {
163 | for (int i = 0; i < numOfPixelsToFill; i++) {
164 | if (!run) return;
165 |
166 | setPixelColor(newTableAr, i, targetColor);
167 |
168 | showTable(newTableAr);
169 | }
170 | } else {
171 | for (int i = numOfPixelsToFill-1; i >= 0; i--) {
172 | if (!run) return;
173 |
174 | setPixelColor(newTableAr, i, targetColor);
175 |
176 | showTable(newTableAr);
177 | }
178 | }
179 | }
180 |
181 | /**
182 | * Fills the table sequentially with random colors
183 | */
184 | private void randomSeqRandom() {
185 | byte[] newTableAr = Arrays.copyOf(table.getLastWrite(), table.getLastWrite().length);
186 |
187 | Color targetColor = null;
188 |
189 | int numOfPixelsToFill = totalNumOfPixels;
190 |
191 | if (direction) {
192 | for (int i = 0; i < numOfPixelsToFill; i++) {
193 | if (!run) return;
194 |
195 | targetColor = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
196 |
197 | setPixelColor(newTableAr, i, targetColor);
198 |
199 | showTable(newTableAr);
200 | }
201 | } else {
202 | for (int i = numOfPixelsToFill-1; i >= 0; i--) {
203 | if (!run) return;
204 |
205 | targetColor = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
206 |
207 | setPixelColor(newTableAr, i, targetColor);
208 |
209 | showTable(newTableAr);
210 | }
211 | }
212 | }
213 |
214 | private void randomDirectionFill() {
215 | byte[] newTableAr = Arrays.copyOf(table.getLastWrite(), table.getLastWrite().length);
216 | Color[][] colorTableAr = LedTable_Util.bArToColorAr(newTableAr);
217 |
218 | Color targetColor = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
219 |
220 |
221 | int runTime = this.totalNumOfPixels;
222 | int x = rnd.nextInt(LedTable_Settings.ledX);
223 | int y = rnd.nextInt(LedTable_Settings.ledY);
224 |
225 | for (int i = 0; i < runTime; i++) {
226 | if (!run) return;
227 |
228 | colorTableAr[y][x] = targetColor;
229 |
230 | int oldX = x;
231 | int oldY = y;
232 |
233 | int direction = rnd.nextInt(4);
234 | if (direction == 0) x--;
235 | else if (direction == 1) x++;
236 | else if (direction == 2) y--;
237 | else if (direction == 3) y++;
238 |
239 | if (y < 0) y = 0;
240 | if (y > colorTableAr.length - 1) y = colorTableAr.length - 1;
241 | if (x < 0) x = 0;
242 | if (x > colorTableAr[y].length - 1) x = colorTableAr[y].length - 1;
243 |
244 | //If the new pixel has already been filled, the go back
245 | if (colorTableAr[y][x] == colorTableAr[oldY][oldX]) {
246 | y = oldY;
247 | x = oldX;
248 | }
249 |
250 | showTable(LedTable_Util.tableColorToByteAr(colorTableAr));
251 | }
252 | }
253 |
254 | private void randomRectangles() {
255 | byte[] newTableAr = Arrays.copyOf(table.getLastWrite(), table.getLastWrite().length);
256 | Color[][] colorTableAr = LedTable_Util.bArToColorAr(newTableAr);
257 |
258 | int startX = rnd.nextInt(LedTable_Settings.ledX - 1);
259 | int startY = rnd.nextInt(LedTable_Settings.ledY - 1);
260 | int width = rnd.nextInt(LedTable_Settings.ledX - startX);
261 | int height = rnd.nextInt(LedTable_Settings.ledY - startY);
262 |
263 | if (width < 1) width = 1;
264 | if (height < 1) height = 1;
265 |
266 | Color color = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
267 |
268 | Effect_Util.drawSquare(colorTableAr, startX, startY, width, height, color, true);
269 |
270 | showTable(LedTable_Util.tableColorToByteAr(colorTableAr));
271 |
272 | delay();
273 | }
274 |
275 | private void setPixelColor(byte[] newTableAr, int pos, Color c) {
276 | newTableAr[pos*3] = (byte) c.getRed();
277 | newTableAr[pos*3+1] = (byte) c.getGreen();
278 | newTableAr[pos*3+2] = (byte) c.getBlue();
279 | }
280 |
281 | private void showTable(byte[] newTableAr) {
282 | if (enableFade) {
283 | try {
284 | Effect_Util.fade((Effect)this, table, newTableAr, 10, (int)delay);
285 | } catch (InterruptedException e) {
286 | LOG.severe("Error fading RandomFill: " + e);
287 | }
288 | } else {
289 | table.write(newTableAr);
290 | delay();
291 | }
292 | }
293 | }
294 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/SetColorEffect.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects;
5 |
6 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
7 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
8 | import net.mdp3.java.rpi.ledtable.table.Table;
9 |
10 | /**
11 | * @author Mikel
12 | *
13 | */
14 | public class SetColorEffect extends Effect {
15 |
16 | /**
17 | * @param t
18 | * @param s
19 | */
20 | public SetColorEffect(Table t, LedTable_Selection s) {
21 | super(t, s);
22 | }
23 |
24 | /* (non-Javadoc)
25 | * @see net.mdp3.java.rpi.ledtable.effects.Effect#effectsLoop()
26 | */
27 | @Override
28 | public void effectsLoop() {
29 | try {
30 | Effect_Util.colorSelection(table, selection);
31 | } catch (Exception e) {
32 | e.printStackTrace();
33 | LOG.severe("Error setting table color: " + e);
34 | }
35 |
36 | stopEffect();
37 | }
38 |
39 | /* (non-Javadoc)
40 | * @see net.mdp3.java.rpi.ledtable.effects.Effect#setEffectInfo()
41 | */
42 | @Override
43 | public EffectInfo setEffectInfo() {
44 | EffectInfoParameter[] paramInfo = {
45 | new EffectInfoParameter("color", "Name of color", EffectInfoParameterType.STRING),
46 | new EffectInfoParameter("r", "Red", EffectInfoParameterType.INT, 0, 255),
47 | new EffectInfoParameter("g", "Green", EffectInfoParameterType.INT, 0, 255),
48 | new EffectInfoParameter("b", "Blue", EffectInfoParameterType.INT, 0, 255)
49 | };
50 | EffectInfo ei = new EffectInfo("Set Color",
51 | "Sets the table to a set color", paramInfo);
52 |
53 | return ei;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/TransparencyAnimationEffect.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable.effects;
2 |
3 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
4 | import net.mdp3.java.rpi.ledtable.effects.EffectInfoParameter.EffectInfoParameterType;
5 | import net.mdp3.java.rpi.ledtable.table.Table;
6 |
7 | /**
8 | * Class extends AnimationEffect to add transparency feature for effects
9 | * Image Series for animation will be loaded, shown in random location,
10 | * and will use 1 random new color to overwrite existing colors.
11 | *
12 | * Images should be 2 color black and white, black will be used as
13 | * transparency color
14 | *
15 | * @author Mikel
16 | *
17 | */
18 | public class TransparencyAnimationEffect extends AnimationEffect {
19 | private final static String name = "TransparencyAnimationEffect";
20 |
21 | public TransparencyAnimationEffect(Table t, LedTable_Selection s) {
22 | super(t, s);
23 | }
24 |
25 | public void effectsLoop() {
26 | LOG.entering(TransparencyAnimationEffect.name, "effectsLoop");
27 |
28 | //TODO Implement new transparency effect, right now this just shows plain animations
29 | for (int i = 0; i < fileList.length; i++) {
30 | if (run) { //checked again so that when the mode changes, the thread can quit on the next frame
31 | if (i < super.imageAr.length) {
32 | if (!this.fade)
33 | super.table.write(imageAr[i]);
34 | else {
35 | try {
36 | Effect_Util.fade(this, super.table, super.imageAr[i], super.numOfFrames, super.fadeDelay);
37 | super.table.write(super.imageAr[i]);
38 | } catch (InterruptedException e) {
39 | e.printStackTrace();
40 | }
41 | }
42 | }
43 | delay();
44 | }
45 | }
46 |
47 | LOG.exiting(TransparencyAnimationEffect.name, "effectsLoop");
48 | }
49 |
50 | public long getRuntime() {
51 | return this.delay * fileList.length;
52 | }
53 |
54 | @Override
55 | public EffectInfo setEffectInfo() {
56 | EffectInfoParameter[] paramInfo = {
57 | new EffectInfoParameter("fade", "Toggle Fading between Images", EffectInfoParameterType.BOOL),
58 | new EffectInfoParameter("numOfFrames", "Number of Frames to fade", EffectInfoParameterType.INT, 1, 1000),
59 | new EffectInfoParameter("fadeDelay", "Time between each fade frame", EffectInfoParameterType.INT, 1, 20000),
60 | new EffectInfoParameter("folder", "Folder to select images from", EffectInfoParameterType.FOLDER)
61 | };
62 | EffectInfo ei = new EffectInfo("TransparencyAnimationEffect", "Can show images in a folder", paramInfo);
63 |
64 | return ei;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/playlist/PlaylistEvent.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects.playlist;
5 |
6 | /**
7 | * @author Mikel
8 | *
9 | */
10 | public class PlaylistEvent {
11 | private PlaylistEventName eventName = null;
12 | private Object eventValue = "";
13 |
14 | private Object eventSource = null;
15 |
16 | public static enum PlaylistEventName {
17 | PLAYBACK_PLAY,
18 | PLAYBACK_STOP,
19 | PLAYBACK_MODE_CHANGED,
20 | INDEX_CHANGED,
21 | ITEM_ADDED,
22 | ITEM_REMOVED,
23 | PLAYLIST_SAVED,
24 | PLAYLIST_LOADED,
25 | PLAYLIST_CLEARED
26 | }
27 |
28 | public PlaylistEvent(PlaylistEventName eventName) {
29 | this(eventName, null);
30 | }
31 |
32 | public PlaylistEvent(PlaylistEventName eventName, Object eventValue) {
33 | this(eventName, eventValue, null);
34 | }
35 |
36 | public PlaylistEvent(PlaylistEventName eventName, Object eventValue, Object source) {
37 | this.setEventName(eventName);
38 | this.setEventValue(eventValue);
39 | this.setEventSource(source);
40 | }
41 |
42 | public PlaylistEventName getEventName() {
43 | return eventName;
44 | }
45 |
46 | public void setEventName(PlaylistEventName eventName) {
47 | this.eventName = eventName;
48 | }
49 |
50 | public Object getEventValue() {
51 | return eventValue;
52 | }
53 |
54 | public void setEventValue(Object eventValue) {
55 | this.eventValue = eventValue;
56 | }
57 |
58 | public Object getEventSource() {
59 | return eventSource;
60 | }
61 |
62 | public void setEventSource(Object eventSource) {
63 | this.eventSource = eventSource;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/playlist/PlaylistEventListener.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects.playlist;
5 |
6 | /**
7 | * @author Mikel
8 | *
9 | */
10 | public interface PlaylistEventListener {
11 | public void playlistEvent(PlaylistEvent pev);
12 | }
13 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/playlist/PlaylistItem.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects.playlist;
5 |
6 | import java.util.logging.Logger;
7 |
8 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
9 | import net.mdp3.java.util.xml.DomXml;
10 | import net.mdp3.java.util.xml.XmlHelper;
11 |
12 | import org.w3c.dom.Document;
13 | import org.w3c.dom.Element;
14 | import org.w3c.dom.Node;
15 | import org.w3c.dom.NodeList;
16 |
17 | /**
18 | * @author Mikel
19 | *
20 | */
21 | public class PlaylistItem implements DomXml {
22 | private final static Logger LOG = Logger.getLogger(PlaylistItem.class.getName());
23 | private final static String name = "PlaylistItem";
24 |
25 | public final static String NODE_NAME = "playlistItem";
26 | public final static String NODE_PLAYTIME = "playTime";
27 |
28 | private int playTime = 10;
29 | public static final int DEFAULT_PLAYTIME = 10;
30 |
31 | private LedTable_Selection selection = null;
32 |
33 | public PlaylistItem() {
34 | this(new LedTable_Selection());
35 | }
36 |
37 | public PlaylistItem(LedTable_Selection selection) {
38 | this(DEFAULT_PLAYTIME, selection);
39 | }
40 |
41 | public PlaylistItem(int playTime, LedTable_Selection selection) {
42 | this.setPlayTime(playTime);
43 | this.setSelection(selection);
44 | }
45 |
46 | public int getPlayTime() {
47 | return playTime;
48 | }
49 |
50 | public void setPlayTime(int playTime) {
51 | this.playTime = playTime;
52 | }
53 |
54 | public LedTable_Selection getSelection() {
55 | return selection;
56 | }
57 |
58 | public void setSelection(LedTable_Selection selection) {
59 | this.selection = selection;
60 | }
61 |
62 | @Override
63 | public boolean equals(Object o) {
64 | if (this.getClass() != o.getClass()) return false;
65 |
66 | final PlaylistItem oItem = (PlaylistItem)o;
67 | if (this.getPlayTime() != oItem.getPlayTime()) return false;
68 |
69 | if (!this.getSelection().equals(oItem.getSelection())) return false;
70 |
71 | return true;
72 | }
73 |
74 | @Override
75 | public int hashCode() {
76 | int hash = 1;
77 | hash = 2 * hash + (this.getPlayTime());
78 | hash = 2 * hash + (this.getSelection().hashCode());
79 | return hash;
80 | }
81 |
82 | @Override
83 | public String toString() {
84 | String ret = "";
85 | ret += "PlaylistItem: ";
86 | ret += " PlayTime: " + this.getPlayTime();
87 | ret += " Selection: " + this.getSelection();
88 | return ret;
89 | }
90 |
91 | @Override
92 | public Element toXml(Document doc) {
93 | LOG.entering(name, "toXml", "doc:"+doc);
94 |
95 | Element selectionE = doc.createElement(PlaylistItem.NODE_NAME);
96 |
97 | selectionE.appendChild(XmlHelper.newTextElement(doc, PlaylistItem.NODE_PLAYTIME, this.getPlayTime()));
98 | selectionE.appendChild(this.getSelection().toXml(doc));
99 |
100 | LOG.exiting(name, "toXml");
101 | return selectionE;
102 | }
103 |
104 | @Override
105 | public void fromXml(Element e) throws Exception {
106 | LOG.entering(name, "fromXml", "e:"+e);
107 |
108 | int time = PlaylistItem.DEFAULT_PLAYTIME;
109 | LedTable_Selection s = new LedTable_Selection();
110 |
111 | NodeList nl = e.getChildNodes();
112 | for (int i = 0; i < nl.getLength(); i++) {
113 | Node n = nl.item(i);
114 |
115 | if (n.getNodeType() == Node.ELEMENT_NODE) {
116 | String key = n.getNodeName();
117 | String value = n.getTextContent();
118 |
119 | LOG.finer("fromXml Key: " + key + " Value: " + value);
120 |
121 | if (key.equals(PlaylistItem.NODE_PLAYTIME)) time = Integer.valueOf(value);
122 | else if (key.equals(LedTable_Selection.NODE_NAME)) s.fromXml((Element)n);
123 | }
124 | }
125 |
126 | this.setPlayTime(time);
127 | this.setSelection(s);
128 |
129 | LOG.exiting(name, "fromXml");
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/effects/playlist/PlaylistTimer.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.effects.playlist;
5 |
6 | /**
7 | * @author Mikel
8 | *
9 | */
10 | public class PlaylistTimer extends Thread {
11 | private long delay = 100;
12 | private long setTime = 100;
13 | private long currentTime = 0;
14 |
15 | private volatile boolean run = false;
16 | private volatile boolean isTiming = false;
17 | private Playlist pl = null;
18 |
19 | public PlaylistTimer(int seconds, Playlist pl) {
20 | this.pl = pl;
21 | setTime(seconds);
22 | }
23 |
24 | @Override
25 | public final void run() {
26 | run = true;
27 |
28 | while(run) {
29 | delay();
30 | checkTimer();
31 | }
32 | }
33 |
34 | /**
35 | * Resets the current time, sets the new time, and stops the current timer
36 | *
37 | * @param newTime
38 | */
39 | public void setTime(int newTime) {
40 | stopTimer();
41 | this.setTime = newTime * 1000;
42 | this.currentTime = 0;
43 | }
44 |
45 | private void checkTimer() {
46 | if (isTiming()) {
47 | timerTick();
48 | if (this.currentTime >= this.setTime && run) {
49 | stopTimer();
50 | pl.next();
51 | }
52 | }
53 | }
54 |
55 | public boolean isRunning() {
56 | return run;
57 | }
58 |
59 | public long getDelay() {
60 | return delay;
61 | }
62 |
63 | public void setDelay(long delay) {
64 | this.delay = delay;
65 | }
66 |
67 | public void shutdownTimer() {
68 | stopTimer();
69 | this.run = false;
70 | }
71 |
72 | private void timerTick() {
73 | //TODO change to use real time instead of just delay time
74 | this.currentTime += this.delay;
75 | }
76 |
77 | private void delay() {
78 | try {
79 | Thread.sleep(this.delay);
80 | } catch (InterruptedException e) {
81 | e.printStackTrace();
82 | }
83 | }
84 |
85 | public synchronized void startTimer() {
86 | this.isTiming = true;
87 | }
88 |
89 | public synchronized void stopTimer() {
90 | this.isTiming = false;
91 | }
92 |
93 | public synchronized boolean isTiming() {
94 | return this.isTiming;
95 | }
96 |
97 | public void resetTimer() {
98 | this.currentTime = 0;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/gui/EffectWindow.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.gui;
5 |
6 | import java.awt.BorderLayout;
7 | import java.awt.FlowLayout;
8 | import java.util.logging.Logger;
9 |
10 | import javax.swing.JDialog;
11 | import javax.swing.JPanel;
12 | import javax.swing.border.EmptyBorder;
13 |
14 | /**
15 | * @author Mikel
16 | *
17 | */
18 | public class EffectWindow extends JDialog {
19 |
20 | private final static Logger LOG = Logger.getLogger(EffectWindow.class.getName());
21 | private final static String name = "EffectWindow";
22 |
23 | private static final long serialVersionUID = -7970848848773218137L;
24 |
25 | private final JPanel contentPanel = new JPanel();
26 |
27 | public EffectWindow() {
28 | LOG.entering(name, "new");
29 |
30 | this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
31 |
32 | setBounds(100, 100, 350, 474);
33 | getContentPane().setLayout(new BorderLayout());
34 | contentPanel.setLayout(new FlowLayout());
35 | contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
36 | getContentPane().add(contentPanel, BorderLayout.CENTER);
37 |
38 |
39 |
40 | this.setVisible(true);
41 |
42 | LOG.exiting(name, "new");
43 | }
44 |
45 | public static void main(String[] args) {
46 | @SuppressWarnings("unused")
47 | EffectWindow ew = new EffectWindow();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/gui/PlaylistWindow.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.gui;
5 |
6 | import javax.swing.JFrame;
7 |
8 | /**
9 | * @author Mikel
10 | *
11 | */
12 | public class PlaylistWindow extends JFrame {
13 |
14 | /**
15 | *
16 | */
17 | private static final long serialVersionUID = -4516912803310179006L;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/gui/TablePanel.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.gui;
5 |
6 | import java.awt.Color;
7 | import java.awt.Graphics;
8 | import java.awt.Graphics2D;
9 | import java.awt.image.BufferedImage;
10 | import java.io.File;
11 | import java.io.IOException;
12 | import java.util.logging.Logger;
13 |
14 | import javax.imageio.ImageIO;
15 | import javax.swing.JPanel;
16 |
17 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
18 | import net.mdp3.java.rpi.ledtable.table.WriteListener;
19 |
20 | /**
21 | * @author Mikel
22 | *
23 | */
24 | public class TablePanel extends JPanel implements WriteListener {
25 | private final static Logger LOG = Logger.getLogger(TablePanel.class.getName());
26 | private final static String name = "TablePanel";
27 |
28 | /**
29 | *
30 | */
31 | private static final long serialVersionUID = 4720593039682897655L;
32 | private int pixelW = (LedTable_Settings.guiW - 10) / LedTable_Settings.ledX;
33 | private int pixelH = (LedTable_Settings.guiH - 70) / LedTable_Settings.ledY;
34 |
35 | private Color grid[][];
36 |
37 | public TablePanel() {
38 | LOG.finer("Pixel Size: " + pixelW + "x" + pixelH);
39 |
40 | this.setBackground(Color.BLACK);
41 |
42 | //init Color Grid
43 | grid = new Color[LedTable_Settings.ledY][];
44 | for (int y = 0; y < LedTable_Settings.ledY; y++) {
45 | grid[y] = new Color[LedTable_Settings.ledX];
46 |
47 | for (int x = 0; x < LedTable_Settings.ledX; x++) {
48 | grid[y][x] = Color.BLACK;
49 | }
50 | }
51 | }
52 |
53 | public void paintComponent(Graphics g) {
54 | super.paintComponent(g);
55 |
56 | LOG.entering(name, "paintComponent");
57 |
58 | drawTable(g);
59 | drawPixelGrid(g);
60 |
61 | LOG.exiting(name, "paintComponent");
62 | }
63 |
64 | /**
65 | * Draws the grid lines
66 | *
67 | * @param g
68 | */
69 | private void drawPixelGrid(Graphics g) {
70 | LOG.entering(name, "drawPixelGrid");
71 |
72 | g.setColor(Color.WHITE);
73 |
74 | for (int y = 0; y < LedTable_Settings.ledY + 1; y++) {
75 | g.drawLine(0, y * pixelH, this.getWidth(), y * pixelH);
76 | }
77 | for (int x = 0; x < LedTable_Settings.ledX + 1; x++) {
78 | g.drawLine(x * pixelW, 0, x * pixelW, this.getHeight());
79 | }
80 |
81 | LOG.exiting(name, "drawPixelGrid");
82 | }
83 |
84 |
85 | /**
86 | * Draws table grid to screen
87 | *
88 | * @param g
89 | */
90 | private void drawTable(Graphics g) {
91 | LOG.entering(name, "drawTable");
92 |
93 | Graphics2D g2d = (Graphics2D)g;
94 |
95 | if (LedTable_Settings.flipY) {
96 | g2d.scale(1, -1);
97 | g2d.translate(0, -getHeight());
98 | }
99 |
100 | for (int y = 0; y < LedTable_Settings.ledY; y++) {
101 | for (int x = 0; x < LedTable_Settings.ledX; x++) {
102 | g2d.setColor(grid[y][x]);
103 | g2d.fillRect(x * pixelW, y * pixelH, pixelW, pixelH);
104 | }
105 | }
106 |
107 | LOG.exiting(name, "drawTable");
108 | }
109 |
110 | /**
111 | * Converts the byte Array bAr to the Color[][] grid and calls repaint()
112 | *
113 | * @param bAr
114 | */
115 | public void drawTable(byte bAr[]) {
116 | LOG.entering(name, "drawTable");
117 |
118 | if (bAr.length != LedTable_Settings.ledX * LedTable_Settings.ledY * 3) {
119 | System.out.println("TablePanel.drawTable ERROR: bAr is wrong size!");
120 | return;
121 | }
122 |
123 | int byteCounter = 0;
124 |
125 | if (LedTable_Settings.snakedLeds) {
126 | for (int y = 0; y < LedTable_Settings.ledY; y++) {
127 | if (y % 2 == 0) {
128 | for (int x = 0; x < LedTable_Settings.ledX; x++) {
129 | int r = (int)(bAr[byteCounter++] & 0xFF);
130 | int g = (int)(bAr[byteCounter++] & 0xFF);
131 | int b = (int)(bAr[byteCounter++] & 0xFF);
132 |
133 | grid[y][x] = new Color(r, g, b);
134 | }
135 | } else {
136 | for (int x = LedTable_Settings.ledX - 1; x >= 0; x--) {
137 | int r = (int)(bAr[byteCounter++] & 0xFF);
138 | int g = (int)(bAr[byteCounter++] & 0xFF);
139 | int b = (int)(bAr[byteCounter++] & 0xFF);
140 |
141 | grid[y][x] = new Color(r, g, b);
142 | }
143 | }
144 | }
145 | } else {
146 | for (int y = 0; y < LedTable_Settings.ledY; y++) {
147 | for (int x = 0; x < LedTable_Settings.ledX; x++) {
148 | int r = (int)(bAr[byteCounter++] & 0xFF);
149 | int g = (int)(bAr[byteCounter++] & 0xFF);
150 | int b = (int)(bAr[byteCounter++] & 0xFF);
151 | grid[y][x] = new Color(r, g, b);
152 | }
153 | }
154 | }
155 |
156 | //if (LedTable_Settings.debug) dumpColorGrid();
157 |
158 | repaint();
159 | LOG.exiting(name, "drawTable");
160 | }
161 |
162 | @SuppressWarnings("unused")
163 | private void dumpColorGrid() {
164 | String gridStr = "Array: \n";
165 | for (int y = 0; y < LedTable_Settings.ledY; y++) {
166 | for (int x = 0; x < LedTable_Settings.ledX; x++) {
167 | if (x % 8 == 0) gridStr += '\n';
168 | gridStr += grid[y][x].getRed() + " ";
169 | gridStr += grid[y][x].getGreen() + " ";
170 | gridStr += grid[y][x].getBlue() + " ";
171 | }
172 | }
173 | System.out.println(gridStr);
174 | }
175 |
176 | @Override
177 | public void writeEvent(byte[] bAr) {
178 | this.drawTable(bAr);
179 | }
180 |
181 | /**
182 | * Saves the current table grid to an image file for later loading
183 | * Note: This saves exactly what is shown at the time
184 | *
185 | * @param fileName
186 | * @throws IOException
187 | */
188 | public void saveTable(String fileName) throws IOException {
189 | saveTable(new File(fileName));
190 | }
191 |
192 | /**
193 | * Saves the current table grid to an image file for later loading
194 | * Note: This saves exactly what is shown at the time
195 | *
196 | * @param file
197 | * @throws IOException
198 | */
199 | public void saveTable(File file) throws IOException {
200 | //if (!file.canWrite()) throw new IOException("Cannot write to file: " + file);
201 |
202 | BufferedImage bi = new BufferedImage(LedTable_Settings.ledX, LedTable_Settings.ledY, BufferedImage.TYPE_INT_RGB);
203 | for (int y = 0; y < grid.length; y++) {
204 | for (int x = 0; x < grid[y].length; x++) {
205 | bi.setRGB(x, y, grid[y][x].getRGB());
206 | }
207 | }
208 |
209 | ImageIO.write(bi, "bmp", file);
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/Table.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.table;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.logging.Logger;
9 |
10 | /**
11 | * @author Mikel
12 | *
13 | */
14 | public abstract class Table {
15 | protected final static Logger LOG = Logger.getLogger(Table.class.getName());
16 | private final static String name = "Table";
17 |
18 | private List listeners = new ArrayList();
19 |
20 | protected byte[] lastWrite = null;
21 |
22 | public synchronized void write(byte bAr[]) {
23 | this.lastWrite = bAr;
24 | for (WriteListener l : listeners) l.writeEvent(bAr);
25 | }
26 |
27 | public void addWriteListener(WriteListener listener) {
28 | LOG.entering(name, "addWriteListener", listener);
29 |
30 | if (!this.listeners.contains(listener))
31 | this.listeners.add(listener);
32 |
33 | LOG.exiting(name, "addWriteListener");
34 | }
35 |
36 | public byte[] getLastWrite() {
37 | return this.lastWrite;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/TableCMD.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable.table;
2 |
3 | import java.io.IOException;
4 |
5 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
6 |
7 | public class TableCMD extends Table {
8 | private final static String name = "LedTable_CMD";
9 |
10 | public synchronized void write(byte[] bAr) {
11 | LOG.entering(TableCMD.name, "write", bAr);
12 | //LOG.finest(LedTable_Util.bArToString(bAr));
13 | //long t = System.currentTimeMillis();
14 |
15 | if (LedTable_Settings.enableTableOutput) {
16 | try {
17 | String cmd = this.buildCmd(bAr);
18 | String cmdline[] = { "sh", "-c", cmd };
19 | Runtime.getRuntime().exec(cmdline);//.waitFor();
20 |
21 | Thread.sleep(10);
22 | } catch (InterruptedException | IOException e) {
23 | e.printStackTrace();
24 | }
25 | }
26 |
27 | //LOG.finest("Write Time: " + (System.currentTimeMillis() - t));
28 | LOG.exiting(TableCMD.name, "write", bAr.length + " bytes written");
29 | }
30 |
31 | private String buildCmd(byte bAr[]) {
32 | LOG.entering(name, "buildCmd");
33 |
34 | String ret = "";
35 | String bytes = "";
36 |
37 | for (int i = 0; i < bAr.length; i++) {
38 | int val = (bAr[i] & 0xFF);
39 | String hex = Integer.toHexString(val).toUpperCase();
40 | while (hex.length() < 2) hex = '0' + hex;
41 |
42 | bytes += "\\x" + hex;
43 | }
44 |
45 | ret = "echo -ne \"" + bytes + "\" > /dev/spidev0.0";
46 |
47 | LOG.info(ret);
48 | LOG.exiting(name, "buildCmd", ret);
49 | return ret;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/TableFactory.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.table;
5 |
6 | import java.io.IOException;
7 | import java.util.logging.Logger;
8 |
9 | /**
10 | * @author Mikel
11 | *
12 | */
13 | public class TableFactory {
14 | private final static Logger LOG = Logger.getLogger(TableFactory.class.getName());
15 | private final static String NAME = "TableFactory";
16 |
17 | public static enum TableOutputMode {
18 | SPI,
19 | CMD,
20 | FILE,
21 | SERIAL
22 | }
23 |
24 | public static Table getTable(TableOutputMode tableMode) throws IOException {
25 | LOG.entering(NAME, "getTable", "mode: " + tableMode);
26 |
27 | LOG.info("Creating Table to " + tableMode);
28 |
29 | Table table = null;
30 |
31 | if (tableMode == TableOutputMode.SPI) {
32 | table = new TableSPI();
33 | } else if (tableMode == TableOutputMode.CMD) {
34 | table = new TableCMD();
35 | } else if (tableMode == TableOutputMode.FILE) {
36 | table = new TableFile();
37 | } else if (tableMode == TableOutputMode.SERIAL) {
38 | table = new TableSerial();
39 | } else {
40 | LOG.info("Invalid Table Mode: " + tableMode);
41 | }
42 |
43 | LOG.exiting(NAME, "getTable", "table: " + table);
44 |
45 | return table;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/TableFile.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable.table;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 |
8 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
9 |
10 | public class TableFile extends Table {
11 | private final static String name = "LedTable_CMD";
12 |
13 | private File file = null;
14 | private FileOutputStream fos = null;
15 |
16 | public TableFile() {
17 | super();
18 |
19 | file = new File(LedTable_Settings.outputFile);
20 | try {
21 | fos = new FileOutputStream(file);
22 | } catch (FileNotFoundException e) {
23 | e.printStackTrace();
24 | }
25 | }
26 |
27 | public synchronized void write(byte[] bAr) {
28 | LOG.entering(TableFile.name, "write", bAr);
29 | //LOG.finest(LedTable_Util.bArToString(bAr));
30 | //long t = System.currentTimeMillis();
31 |
32 | if (LedTable_Settings.enableTableOutput) {
33 | try {
34 | if (fos != null) {
35 | fos.write(bAr);
36 | }
37 | Thread.sleep(10);
38 | } catch (InterruptedException | IOException e) {
39 | e.printStackTrace();
40 | }
41 | }
42 |
43 | //LOG.finest("Write Time: " + (System.currentTimeMillis() - t));
44 | LOG.exiting(TableFile.name, "write", bAr.length + " bytes written");
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/TableSPI.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.rpi.ledtable.table;
2 |
3 | import java.io.IOException;
4 |
5 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
6 |
7 | import com.pi4j.io.spi.SpiChannel;
8 | import com.pi4j.io.spi.SpiDevice;
9 | import com.pi4j.io.spi.SpiFactory;
10 | import com.pi4j.io.spi.SpiMode;
11 |
12 | public class TableSPI extends Table {
13 | private final static String name = "LedTable_SPI";
14 |
15 | private SpiDevice spi = null;
16 |
17 | public TableSPI() throws IOException {
18 | LOG.entering(TableSPI.name, "new");
19 |
20 | if (LedTable_Settings.enableTableOutput)
21 | spi = SpiFactory.getInstance(SpiChannel.CS0, LedTable_Settings.spiSpeed, SpiMode.MODE_0);
22 |
23 | LOG.exiting(TableSPI.name, "new");
24 | }
25 |
26 | public synchronized void write(byte[] bAr) {
27 | LOG.entering(TableSPI.name, "write", bAr);
28 | //LOG.finest(LedTable_Util.bArToString(bAr));
29 | //long t = System.currentTimeMillis();
30 | super.write(bAr);
31 |
32 | if (LedTable_Settings.enableTableOutput) {
33 | try {
34 | spi.write(bAr);
35 | Thread.sleep(10);
36 | } catch (IOException | InterruptedException e) {
37 | e.printStackTrace();
38 | }
39 | }
40 |
41 | //LOG.finest("Write Time: " + (System.currentTimeMillis() - t));
42 | LOG.exiting(TableSPI.name, "write", bAr.length + " bytes written");
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/TableSerial.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.table;
5 |
6 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
7 |
8 | import com.pi4j.io.serial.Serial;
9 | import com.pi4j.io.serial.SerialDataEvent;
10 | import com.pi4j.io.serial.SerialDataListener;
11 | import com.pi4j.io.serial.SerialFactory;
12 | import com.pi4j.io.serial.SerialPortException;
13 |
14 | /**
15 | * @author Mikel
16 | *
17 | */
18 | public class TableSerial extends Table {
19 | private final static String name = "TableSerial";
20 | private SerialDataListener sdl = null;
21 |
22 | public final Serial serial;
23 | private boolean connected = false;
24 | private String comPort = "";
25 | private int baud = 57600;
26 |
27 | public TableSerial() {
28 | super();
29 | serial = SerialFactory.createInstance();
30 |
31 | this.comPort = LedTable_Settings.serialPort;
32 | this.baud = LedTable_Settings.serialBaud;
33 |
34 | sdl = new SerialDataListener() {
35 | @Override
36 | public void dataReceived(SerialDataEvent event) {
37 | // print out the data received to the console
38 | LOG.info(event.getData());
39 | }
40 | };
41 |
42 | serial.addListener(sdl);
43 |
44 | this.connect();
45 | }
46 |
47 | public synchronized void write(byte[] bAr) {
48 | LOG.entering(name, "write", bAr);
49 | super.write(bAr);
50 |
51 | if (LedTable_Settings.enableTableOutput && connected) {
52 | serial.write(bAr);
53 | }
54 |
55 | //LOG.finest("Write Time: " + (System.currentTimeMillis() - t));
56 | LOG.exiting(name, "write", bAr.length + " bytes written");
57 | }
58 |
59 | /**
60 | * Returns true if the connection to the serial port is successful
61 | * Also returns true if the output is disabled so that debugging will work
62 | *
63 | * @return connected status
64 | */
65 | public boolean connect() {
66 | if (LedTable_Settings.enableTableOutput) {
67 | try {
68 | // open the default serial port provided on the GPIO header
69 | serial.open(comPort, baud);
70 | Thread.sleep(1000); //connect time
71 | connected = true;
72 | return true;
73 | }
74 | catch(InterruptedException | SerialPortException e) {
75 | System.out.println("Exception in Serial: " + e);
76 | connected = false;
77 | return false;
78 | }
79 | }
80 | return connected;
81 | }
82 |
83 | public void disconnect() {
84 | serial.close();
85 | }
86 |
87 | public boolean isConnected() {
88 | return connected;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/table/WriteListener.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.table;
5 |
6 | /**
7 | * @author Mikel
8 | *
9 | */
10 | public interface WriteListener {
11 | public void writeEvent(byte[] bAr);
12 | }
13 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/webservice/WebserviceCommands.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.webservice;
5 |
6 | import net.mdp3.java.util.xml.DomXml;
7 | import net.mdp3.java.util.xml.XmlHelper;
8 |
9 | import org.w3c.dom.Document;
10 | import org.w3c.dom.Element;
11 |
12 | /**
13 | * @author Mikel
14 | *
15 | */
16 | public class WebserviceCommands {
17 |
18 | public static final String WS_CMD = "cmd";
19 | public static enum WebserviceCommand implements DomXml {
20 | COMMAND_LIST,
21 | MODE,
22 | SAVE,
23 | CURRENT_SELECTION_INFO,
24 | EFFECT_INFO,
25 | EFFECT_LIST,
26 | PLAYLIST,
27 | PLAYLIST_INFO,
28 | FILE;
29 |
30 | public static final String NODE_NAME = "Command";
31 | public static final String NODE_CMD_NAME = "Name";
32 |
33 | @Override
34 | public Element toXml(Document doc) {
35 | Element wsCmdE = doc.createElement(WebserviceCommand.NODE_NAME);
36 |
37 | wsCmdE.appendChild(XmlHelper.newTextElement(doc, WebserviceCommand.NODE_CMD_NAME, this.name()));
38 |
39 | return wsCmdE;
40 | }
41 |
42 | @Override
43 | public void fromXml(Element e) throws Exception {
44 | //Not Implemented
45 | throw new Exception("Not Implemented");
46 | }
47 | }
48 |
49 | public static final String WS_MODE = "mode";
50 | public static final String WS_OUTPUT = "output";
51 | }
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/webservice/WebserviceFunctions.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.webservice;
5 |
6 | import java.io.File;
7 | import java.io.FileNotFoundException;
8 | import java.util.Map;
9 | import java.util.logging.Logger;
10 |
11 | import javax.xml.transform.TransformerException;
12 | import javax.xml.transform.TransformerFactoryConfigurationError;
13 |
14 | import org.w3c.dom.Document;
15 | import org.w3c.dom.Element;
16 |
17 | import net.mdp3.java.rpi.ledtable.LedTable;
18 | import net.mdp3.java.rpi.ledtable.LedTable_Selection;
19 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
20 | import net.mdp3.java.rpi.ledtable.effects.EffectMode;
21 | import net.mdp3.java.rpi.ledtable.webservice.WebserviceCommands.WebserviceCommand;
22 | import net.mdp3.java.util.file.SimpleFileIO;
23 | import net.mdp3.java.util.xml.XmlHelper;
24 |
25 | /**
26 | * @author Mikel
27 | *
28 | */
29 | public class WebserviceFunctions {
30 | private final static Logger LOG = Logger.getLogger(WebserviceFunctions.class.getName());
31 | private final static String name = "WebserviceFunctions";
32 |
33 | private static LedTable table = null;
34 |
35 | private final static String DEFAULT_WEB_FILE = "LedTable.html";
36 | private final static String WEB_FOLDER = "www";
37 |
38 | /**
39 | * Set the ledTable for the methods to use, this must be called before
40 | * running the parseParams method
41 | *
42 | * @param t
43 | */
44 | protected static void setLedTable(LedTable t) {
45 | table = t;
46 | }
47 |
48 | /**
49 | * Before calling this function, the LedTable must be set using the
50 | * setLedTable method
51 | *
52 | * @param params
53 | * @return
54 | * @throws Exception
55 | */
56 | protected static String parseParams(Map params) throws Exception {
57 | LOG.entering(name, "parseParams");
58 |
59 | if (table == null) throw new Exception("Table not Initialized");
60 |
61 | String ret = "";
62 |
63 | //read mode parameter
64 | WebserviceCommand wsCmd = loadCmd(params);
65 |
66 | if (wsCmd != null) {
67 | ret = processCmd(wsCmd, params);
68 | }
69 |
70 | LOG.exiting(name, "parseParams", "ret: " + ret);
71 | return ret;
72 | }
73 |
74 | private static WebserviceCommand loadCmd(Map params) {
75 | //read mode parameter
76 | WebserviceCommand wsCmd = null;
77 | String cmdStr = params.get(WebserviceCommands.WS_CMD);
78 | if (cmdStr != null && cmdStr.length() > 0) {
79 | try {
80 | wsCmd = WebserviceCommand.valueOf(cmdStr.toUpperCase().trim());
81 | } catch (Exception e) {
82 | LOG.severe("Error Invalid Command: " + cmdStr + " " + e);
83 |
84 | return null;
85 | }
86 | }
87 |
88 | return wsCmd;
89 | }
90 |
91 | private static String processCmd(WebserviceCommand wsCmd, Map params) {
92 | String ret = "";
93 |
94 | if (wsCmd == WebserviceCommand.MODE) {
95 | ret = processCmdMode(params);
96 | } else if (wsCmd == WebserviceCommand.SAVE) {
97 | ret = processCmdSave(params);
98 | } else if (wsCmd == WebserviceCommand.CURRENT_SELECTION_INFO) {
99 | ret = processCurSelectionInfo(params);
100 | } else if (wsCmd == WebserviceCommand.EFFECT_LIST) {
101 | ret = processCmdEffectList(params);
102 | } else if (wsCmd == WebserviceCommand.COMMAND_LIST) {
103 | ret = processCmdCommandList();
104 | } else if (wsCmd == WebserviceCommand.FILE) {
105 | ret = processCmdFile(params);
106 | } else if (wsCmd == WebserviceCommand.EFFECT_INFO) {
107 | ret = processEffectInfo(params);
108 | } else if (wsCmd == WebserviceCommand.PLAYLIST_INFO) {
109 | ret = processPlaylistInfo(params);
110 | }
111 |
112 | return ret;
113 | }
114 |
115 | private static String processCmdMode(Map params) {
116 | String ret = "";
117 |
118 | try {
119 | EffectMode mode = EffectMode.valueOf(params.get(WebserviceCommands.WS_MODE));
120 | ret += table.newSelection(new LedTable_Selection(mode, params));
121 | ret = "OK";
122 | } catch (Exception e) {
123 | e.printStackTrace();
124 | LOG.severe("Invalid Mode\n" + e.getMessage());
125 | ret = "Invalid Mode\n" + e.getMessage();
126 | }
127 |
128 | return ret;
129 | }
130 |
131 | private static String processCmdSave(Map params) {
132 | String ret = "";
133 | ret += "LedTable
\n";
134 | ret += "OK";
135 |
136 | try {
137 | table.saveSelection();
138 | ret = "Selection Saved";
139 | } catch (Exception e) {
140 | System.err.println("Error Saving Selection");
141 | ret = "Error Saving Selection\n" + e.getMessage();
142 |
143 | e.printStackTrace();
144 | }
145 |
146 | return ret;
147 | }
148 |
149 | private static String processCurSelectionInfo(Map params) {
150 | String ret = "";
151 |
152 | Document doc = XmlHelper.getNewDoc();
153 | try {
154 | ret += "\n" + XmlHelper.elementToString(table.getCurrentSelection().toXml(doc));
155 | } catch (TransformerFactoryConfigurationError
156 | | TransformerException e) {
157 | e.printStackTrace();
158 | LOG.severe("Error Converting current selection to XML: " + e);
159 | }
160 |
161 | ret = removeFormatting(ret);
162 |
163 | return ret;
164 | }
165 |
166 | private static String processEffectInfo(Map params) {
167 | String ret = "";
168 |
169 | Document doc = XmlHelper.getNewDoc();
170 | try {
171 | ret += "\n" + XmlHelper.elementToString(table.getEffect().getEffectInfo().toXml(doc));
172 | } catch (TransformerFactoryConfigurationError
173 | | TransformerException e) {
174 | e.printStackTrace();
175 | LOG.severe("Error Converting current selection to XML: " + e);
176 | }
177 |
178 | ret = removeFormatting(ret);
179 |
180 | return ret;
181 | }
182 |
183 | private static String processCmdEffectList(Map params) {
184 | String ret = "";
185 |
186 | Document doc = XmlHelper.getNewDoc();
187 | Element rootElement = doc.createElement("EffectList");
188 | doc.appendChild(rootElement);
189 |
190 | for (EffectMode em : EffectMode.values())
191 | rootElement.appendChild(em.toXml(doc));
192 |
193 | try {
194 | ret = XmlHelper.elementToString(rootElement);
195 | } catch (TransformerFactoryConfigurationError | TransformerException e) {
196 | e.printStackTrace();
197 | LOG.severe("Error Creating Effect List: " + e);
198 | }
199 |
200 | ret = removeFormatting(ret);
201 |
202 | return ret;
203 | }
204 |
205 | private static String processCmdCommandList() {
206 | String ret = "";
207 |
208 | Document doc = XmlHelper.getNewDoc();
209 | Element rootElement = doc.createElement("CommandList");
210 | doc.appendChild(rootElement);
211 |
212 | for (WebserviceCommand ws : WebserviceCommand.values())
213 | rootElement.appendChild(ws.toXml(doc));
214 |
215 | try {
216 | ret = XmlHelper.elementToString(rootElement);
217 | } catch (TransformerFactoryConfigurationError | TransformerException e) {
218 | e.printStackTrace();
219 | LOG.severe("Error Creating Command List: " + e);
220 | }
221 |
222 | return ret;
223 | }
224 |
225 | private static String processCmdFile(Map params) {
226 | String fileName = "";
227 |
228 | if (params.get("fileName") != null)
229 | fileName = params.get("fileName").toString();
230 | else if (params.get("file") != null)
231 | fileName = params.get("file").toString();
232 |
233 | return serveFiles(fileName);
234 | }
235 |
236 | protected static String serveFiles() {
237 | return serveFiles("");
238 | }
239 |
240 | protected static String serveFiles(String fileName) {
241 | String ret = "";
242 | if (fileName == null || fileName == "") {
243 | try {
244 | //TODO improve landing page, maybe change html file to just header and try to generate content
245 | File f = new File(WEB_FOLDER + "/" + DEFAULT_WEB_FILE);
246 | ret = SimpleFileIO.loadFileToString(f);
247 | } catch (FileNotFoundException e) {
248 | e.printStackTrace();
249 | }
250 | } else {
251 | if (fileName.contains("..")) return "Invalid Filename Sequence: ..";
252 | try {
253 | File f = new File(WEB_FOLDER + "/" + fileName);
254 | ret = SimpleFileIO.loadFileToString(f);
255 | } catch (FileNotFoundException e) {
256 | e.printStackTrace();
257 | LOG.severe("File Not Found: " + e);
258 |
259 | ret = "Error File Not Found";
260 | }
261 | }
262 |
263 | return ret;
264 | }
265 |
266 | private static String removeFormatting(String s) {
267 | //Remove xml formatting
268 | s = s.replaceAll("\r", "");
269 | s = s.replaceAll("\n", "");
270 | s = s.replaceAll("\t", "");
271 |
272 | return s;
273 | }
274 |
275 | private static String processPlaylistInfo(Map params) {
276 | String ret = "";
277 |
278 | if (table.getCurrentPlaylist().isPlaying()) {
279 | ret = "PLAYING";
280 | } else ret = "STOPPED";
281 |
282 | return ret;
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/rpi/ledtable/webservice/WebserviceHandler.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.rpi.ledtable.webservice;
5 |
6 | import java.io.IOException;
7 | import java.net.BindException;
8 | import java.util.Map;
9 | import java.util.logging.Logger;
10 |
11 | import net.mdp3.java.rpi.ledtable.LedTable;
12 | import net.mdp3.java.rpi.ledtable.LedTable_Settings;
13 | import net.mdp3.java.util.webservice.Webservice;
14 | import net.mdp3.java.util.webservice.WebserviceListener;
15 |
16 | /**
17 | * @author Mikel
18 | *
19 | */
20 | public class WebserviceHandler implements WebserviceListener {
21 | private final static Logger LOG = Logger.getLogger(WebserviceHandler.class.getName());
22 | private final static String name = "WebserviceHandler";
23 |
24 | Webservice ws;
25 |
26 | public WebserviceHandler(LedTable table, int port, String name) {
27 | WebserviceFunctions.setLedTable(table);
28 |
29 | boolean started = false;
30 | try {
31 | ws = new Webservice(port, name, this);
32 | started = true;
33 | } catch (BindException e) {
34 | System.out.println("Error opening port: " + port);
35 | } catch (IOException e) {
36 | System.out.println("Error starting webservice: " + e);
37 | e.printStackTrace();
38 | }
39 |
40 | if (LedTable_Settings.debug && started) System.out.println("Webservice started on port: " + port + " for Context: " + name);
41 | }
42 |
43 |
44 | @Override
45 | public String wsAccess(Map params) {
46 | LOG.entering(name, "wsAccess", "params: " + params);
47 |
48 | String returnValue = "";
49 |
50 | //Parameters are send, so send back link to homepage and process the params
51 | if (params.size() > 0) {
52 | try {
53 | returnValue += WebserviceFunctions.parseParams(params);
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | LOG.severe("Error in Webservice: " + e);
57 | }
58 | } else { //No parameters sent so send landing page
59 | returnValue += WebserviceFunctions.serveFiles();
60 | }
61 |
62 | LOG.exiting(name, "wsAccess", "returnValue: " + returnValue);
63 | return returnValue;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/console/ConsoleBatch.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.console;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Console Command Batch Process
10 | *
11 | * This class spawns a new thread to run the commands passed in to the batch
12 | * List and runs them with the specified delay in between each. This process
13 | * can be set to loop for continuous looping. Commands are not run against the
14 | * system shell, but are run against the ConsoleReader object which uses
15 | * Reflection to run methods on the object passed in.
16 | *
17 | * This class allows for an object to be set up with methods, and allows for a
18 | * text file list of methods to be run against it automatically. This can be
19 | * used to automate a configurable setup for a program and other things.
20 | *
21 | * @author Mikel
22 | *
23 | */
24 | public class ConsoleBatch extends Thread {
25 | private ConsoleReader consoleHandler;
26 | private List batch;
27 | private boolean run = false;
28 | private int commandIndex = 0;
29 | private boolean looping = false;
30 |
31 | public ConsoleBatch(ConsoleReader cr, List v) {
32 | this.consoleHandler = cr;
33 | this.batch = v;
34 | }
35 |
36 | public void run() {
37 | while(run) {
38 | if (this.commandIndex >= batch.size() && this.looping) this.commandIndex = 0;
39 | else if (this.commandIndex >= batch.size()) {
40 | run = false;
41 | return;
42 | }
43 |
44 | String command = batch.get(this.commandIndex).getCommand();
45 | System.out.println("Batch Command: " + command);
46 | try {
47 | this.consoleHandler.parseInput(command);
48 | } catch (Exception e1) {
49 | e1.printStackTrace();
50 | System.out.println("Error in command batch with command " + command + "\n" + e1);
51 | }
52 |
53 | try {
54 | Thread.sleep(batch.get(this.commandIndex).getDelay());
55 | } catch (InterruptedException e) {
56 | System.out.println("Error sleeping Command Batch " + e);
57 | e.printStackTrace();
58 | }
59 | this.commandIndex++;
60 | }
61 | }
62 |
63 | public void startBatch() {
64 | if (batch.size() > 0 && !run) {
65 | run = true;
66 | this.start();
67 | }
68 | }
69 |
70 | public void stopBatch() {
71 | run = false;
72 | }
73 |
74 | public void setLooping(boolean b) {
75 | this.looping = b;
76 | }
77 |
78 | public boolean isRunning() {
79 | return run;
80 | }
81 | }
82 |
83 | class ConsoleCommand {
84 | private String command = "";
85 | private long waitTime = 100;
86 |
87 | public ConsoleCommand(String c, long l) {
88 | this.command = c;
89 | this.waitTime = l;
90 | }
91 |
92 | public String getCommand() {
93 | return this.command;
94 | }
95 |
96 | public long getDelay() {
97 | return this.waitTime;
98 | }
99 | }
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/console/ConsoleReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.console;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.io.InputStreamReader;
10 | import java.lang.reflect.InvocationTargetException;
11 | import java.lang.reflect.Method;
12 | import java.lang.reflect.Modifier;
13 | import java.util.ArrayList;
14 | import java.util.Scanner;
15 | import java.util.SortedSet;
16 | import java.util.TreeSet;
17 |
18 | /**
19 | * ConsoleReader class easily adds a threaded BufferedInput Console reader to a
20 | * Java app, to enable simple call backs to methods on the implementing object.
21 | *
22 | * All methods used by the lookups should implement all Strings in the parameter
23 | * list and do type conversion within the callback methods.
24 | *
25 | * Example:
26 | *
27 | * For some object o with methods:
28 | *
29 | * ConsoleReader cr = new ConsoleReader("App Name", o);
30 | *
31 | * Will instantiate and start an instance of the ConsoleReader which will call
32 | * back to methods on o when the method names and parameter counts match,
33 | * parameter types are unchecked and should all be String.
34 | *
35 | * @author Mikel Duke
36 | */
37 | public class ConsoleReader extends Thread {
38 |
39 | private BufferedReader br;
40 | private boolean run = true;
41 | private String name = "";
42 | private Object o;
43 | private ConsoleBatch consoleBatch = null;
44 |
45 | /**
46 | * Creates a new console reader that can call methods in Object o and will
47 | * print name to the console before each command.
48 | *
49 | * Automatically launches console command input thread
50 | *
51 | * @param name
52 | * @param o
53 | */
54 | public ConsoleReader(String name, Object o) {
55 | this(name, o, true);
56 | }
57 |
58 | /**
59 | * Creates a new console reader that can call methods in Object o and will
60 | * print name to the console before each command.
61 | *
62 | * @param name
63 | * @param o
64 | * @param startThread true to start the console input thread
65 | */
66 | public ConsoleReader(String name, Object o, boolean startThread) {
67 | this.name = name;
68 | this.o = o;
69 | if (startThread) this.start();
70 | }
71 |
72 | /**
73 | * Run is the threaded method required when extending Thread. It outputs
74 | * the Name set in the constructor and waits for console input.
75 | */
76 | public void run() {
77 | br = new BufferedReader(new InputStreamReader(System.in));
78 |
79 | try {
80 | while (run) {
81 | System.out.print(name + ": ");
82 | parseInput(br.readLine());
83 | }
84 | }
85 | catch (Exception e) {
86 | System.out.println("Error in " + name + " Thread: " + e);
87 | e.printStackTrace();
88 | }
89 | }
90 |
91 | /**
92 | * parseInput handles the keyboard console input. It looks up the input
93 | * string to check for matching methods on object o.
94 | *
95 | * Note: Parameters should be separated by a space character, and extra
96 | * parameters are ignored.
97 | *
98 | * @param input
99 | * @throws InvocationTargetException
100 | * @throws IllegalArgumentException
101 | * @throws IllegalAccessException
102 | */
103 | protected boolean parseInput(String input) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
104 | Method methods[] = o.getClass().getMethods();
105 | Object args[] = null;
106 |
107 | String inputAr[] = input.split(" ");
108 | if (inputAr.length == 0) return false;
109 |
110 | for (int i = 0; i < methods.length; i++) {
111 | //find matching public method of same name
112 | if (methods[i].getName().equalsIgnoreCase(inputAr[0])
113 | && methods[i].getModifiers() == Modifier.PUBLIC) {
114 | Class> params[] = methods[i].getParameterTypes();
115 | if (params.length == 0) {
116 | args = null;
117 | } else if (inputAr.length >= params.length + 1) {
118 | args = new Object[params.length];
119 | for (int j = 0; j < params.length; j++) {
120 | args[j] = inputAr[j+1];
121 | }
122 | if (inputAr.length + 1 > params.length) {
123 | //combine extra params to last one
124 | for (int j = params.length; j < inputAr.length - 1; j++) {
125 | String s = ((String) args[args.length - 1]);
126 | s += " " + inputAr[j + 1];
127 | args[args.length - 1] = s;
128 | }
129 | }
130 | } else {
131 | System.out.println("Error: Not Enough Arguments");
132 | return false;
133 | }
134 | methods[i].invoke(o, args);
135 | return true;
136 | }
137 | }
138 |
139 | //default implementations for common methods, these items don't get
140 | //called if already implemented in object o
141 | if (input.equalsIgnoreCase("help")) {
142 | showDefaultHelp();
143 | return true;
144 | } else if (inputAr[0].equalsIgnoreCase("openBatch") && inputAr.length == 2) {
145 | openBatch(inputAr[1]);
146 | return true;
147 | } else if (inputAr[0].equalsIgnoreCase("startBatch")) {
148 | startBatch();
149 | return true;
150 | } else if (inputAr[0].equalsIgnoreCase("loopBatch")) {
151 | loopBatch();
152 | return true;
153 | } else if (inputAr[0].equalsIgnoreCase("stopBatch")) {
154 | stopBatch();
155 | return true;
156 | } else if (input.equalsIgnoreCase("quit") || input.equalsIgnoreCase("exit")) {
157 | quit();
158 | return true;
159 | } else {
160 | System.out.println("Invalid Command");
161 | return false;
162 | }
163 | }
164 |
165 | /**
166 | * Default quit implementation to stop the thread and close the ConsoleReader.
167 | *
168 | * If this method is implemented in o, it should call back to this method to
169 | * stop the ConsoleReader thread correctly.
170 | */
171 | public void quit() {
172 | run = false;
173 | }
174 |
175 | /**
176 | * Default help implementation. This method will not be used if a help
177 | * method is implemented in object o.
178 | *
179 | * This method will output a sorted list of public method names on object o
180 | * with the parameter count.
181 | */
182 | private void showDefaultHelp() {
183 | Method methods[] = o.getClass().getMethods();
184 | SortedSet methodNames = new TreeSet();
185 |
186 | for (int i = 0; i < methods.length; i++) {
187 | if (methods[i].getModifiers() == Modifier.PUBLIC) {
188 | Class> params[] = methods[i].getParameterTypes();
189 | String str = methods[i].getName();
190 | if (!(str.equalsIgnoreCase("toString") || str.equalsIgnoreCase("equals")))
191 | methodNames.add(str + " " + params.length);
192 | }
193 | }
194 |
195 | if (!methodNames.isEmpty()) {
196 | Object methodNamesAr[] = methodNames.toArray();
197 | for (int i = 0; i < methodNamesAr.length; i++)
198 | System.out.println((String)methodNamesAr[i]);
199 | }
200 | }
201 |
202 | /**
203 | * Opens a new command batch process using the commands in fileName
204 | *
205 | * @param fileName
206 | */
207 | public void openBatch(String fileName) {
208 | File file = new File(fileName);
209 | this.openBatch(file);
210 | }
211 |
212 | /**
213 | * Opens a new command batch process using the commands in fileName
214 | *
215 | * @param file
216 | */
217 | public void openBatch(File file) {
218 | ArrayList commandList = new ArrayList();
219 | String command = "";
220 | long delay = 100;
221 | String input = "";
222 |
223 | try {
224 | Scanner sc = new Scanner(file);
225 | while (sc.hasNext()) input += sc.nextLine() + "\n";
226 | sc.close();
227 | } catch (FileNotFoundException e) {
228 | System.out.println("Settings File Not Found");
229 | //e.printStackTrace();
230 | }
231 |
232 | if (!input.equals("")) {
233 | String line[] = input.split("\n");
234 | for (int i = 0; i < line.length; i++) {
235 | if (line[i].length() < 1) continue;
236 | if (line[i].charAt(0) == '#') {
237 | continue;
238 | } else if (line[i].toLowerCase().contains("batch")) {
239 | continue;
240 | }
241 |
242 | String parts[] = line[i].split(" ");
243 | if (parts.length < 2) {
244 | delay = 100;
245 | command = line[i];
246 | } else try {
247 | Long l = Long.parseLong(parts[parts.length - 1]);
248 | delay = l.longValue();
249 |
250 | command = "";
251 | for (int j = 0; j < parts.length - 1; j++) {
252 | command += parts[j];
253 | }
254 | } catch (NumberFormatException e) {
255 | delay = 100;
256 | command = line[i];
257 | }
258 |
259 | commandList.add(new ConsoleCommand(command, delay));
260 | }
261 | }
262 |
263 | if (commandList.size() > 0) {
264 | this.consoleBatch = new ConsoleBatch(this, commandList);
265 | } else {
266 | System.out.println("No Commands Loaded");
267 | }
268 | }
269 |
270 | /**
271 | * If a console batch process has been opened, this starts it
272 | */
273 | public void startBatch() {
274 | if (this.consoleBatch != null) {
275 | this.consoleBatch.startBatch();
276 | }
277 | }
278 |
279 | /**
280 | * Sets the batch process mode loop parameter
281 | */
282 | public void loopBatch() {
283 | if (this.consoleBatch != null) {
284 | this.consoleBatch.setLooping(true);
285 | this.consoleBatch.startBatch();
286 | }
287 | }
288 |
289 | /**
290 | * If a patch process has been opened, then stop it
291 | */
292 | public void stopBatch() {
293 | if (this.consoleBatch != null) {
294 | this.consoleBatch.stopBatch();
295 | }
296 | }
297 |
298 | /**
299 | * Returns the command batch running state
300 | * @return
301 | */
302 | public boolean isBatchRunning() {
303 | if (this.consoleBatch != null) {
304 | return this.consoleBatch.isRunning();
305 | } else {
306 | return false;
307 | }
308 | }
309 | }
310 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/console/ConsoleUtil.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.console;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.util.List;
7 |
8 | /**
9 | * Class to hold Util functions for doing things in console mode in an app
10 | *
11 | *
12 | * @author Mikel
13 | *
14 | */
15 | public class ConsoleUtil {
16 | private static Process p;
17 |
18 | /**
19 | * Runs the specified cmd string as a shell command, if wait = true, then
20 | * this method will block until the command is finished
21 | *
22 | * @param cmd
23 | * @param wait
24 | * @return
25 | * @throws IOException
26 | * @throws InterruptedException
27 | */
28 | public static String execute(String cmd, boolean wait) throws IOException, InterruptedException {
29 | return execute(new String[]{ cmd }, wait);
30 | }
31 |
32 | /**
33 | * Combines the string array into a command and runs it as a shell command,
34 | * if wait = true then this method will block
35 | *
36 | * @param cmd
37 | * @param wait
38 | * @return
39 | * @throws IOException
40 | * @throws InterruptedException
41 | */
42 | public static String execute(String cmd[], boolean wait) throws IOException, InterruptedException {
43 | StringBuffer output = new StringBuffer();
44 | p = Runtime.getRuntime().exec(cmd);
45 | if (wait) {
46 | p.waitFor();
47 |
48 | BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
49 | String line = "";
50 | while ((line = reader.readLine())!= null) {
51 | output.append(line + "\n");
52 | }
53 |
54 | return output.toString();
55 | } else return "";
56 | }
57 |
58 | /**
59 | * Returns true if any String item in the argList starts with the
60 | * argName parameter. This is useful to check for the presence of
61 | * a specific command like argument.
62 | *
63 | * @param argList
64 | * @param argName
65 | * @return
66 | */
67 | public static boolean hasArg(List argList, String argName) {
68 | return hasArg(argList, argName, "");
69 | }
70 |
71 | /**
72 | * Returns true if any String item in the argList starts with the
73 | * argName parameter. This is useful to check for the presence of
74 | * a specific command like argument. This method also allows for the
75 | * delimeter to be specified which gets appended to the argName,
76 | * ie to search for --file=blah then = is the delim.
77 | *
78 | * @param argList
79 | * @param argName
80 | * @param delim
81 | * @return
82 | */
83 | public static boolean hasArg(List argList, String argName, String delim) {
84 | for (int i = 0; i < argList.size(); i++) {
85 | if (argList.get(i).startsWith(argName + delim)) return true;
86 | }
87 |
88 | return false;
89 | }
90 |
91 | /**
92 | * Returns the first item in the argList that starts with the string
93 | * argName not including the arg.
94 | *
95 | * @param argList
96 | * @param argName
97 | * @return
98 | */
99 | public static String getArgStartsWith(List argList, String argName) {
100 | return getArgStartsWith(argList, argName, "");
101 | }
102 |
103 | /**
104 | * Returns the first item in the argList that starts with the String
105 | * argName + delim, not including the arg.
106 | *
107 | * Example: If argList contains --file=blah, then if using
108 | * argName:--file and delim:= would return blah.
109 | *
110 | * @param argList
111 | * @param argName
112 | * @param delim
113 | * @return
114 | */
115 | public static String getArgStartsWith(List argList, String argName, String delim) {
116 | String ret = "";
117 |
118 | for (int i = 0; i < argList.size(); i++) {
119 | if (argList.get(i).startsWith(argName + delim)) {
120 | String arg = argList.get(i);
121 | return arg.substring(argName.length() + delim.length(), arg.length());
122 | }
123 | }
124 |
125 | return ret;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/file/FileNameFormatter.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.file;
5 |
6 | import java.text.DateFormat;
7 | import java.text.SimpleDateFormat;
8 | import java.util.Date;
9 |
10 | /**
11 | * @author Mikel
12 | *
13 | */
14 | public class FileNameFormatter {
15 |
16 | /**
17 | * Common function to get the date string back in a format I like
18 | *
19 | * Example: 20151021153304
20 | *
21 | * @return Date/Time as yyyyMMddHHmmss
22 | */
23 | public static String getDateString() {
24 | String ret = "";
25 |
26 | DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
27 | Date date = new Date();
28 | ret += dateFormat.format(date);
29 |
30 | return ret;
31 | }
32 |
33 | /**
34 | * Returns a Dated file name using the specified prefix and extension with
35 | * the separator after the prefix and before the date
36 | *
37 | * Example: prefix-20151021132402.txt
38 | *
39 | * @param prefix
40 | * @param separator
41 | * @param extension Not including the .
42 | * @return
43 | */
44 | public static String getDatedFileName(String prefix, String separator, String extension) {
45 | String ret = "";
46 |
47 | ret += prefix;
48 | ret += separator;
49 | ret += FileNameFormatter.getDateString();
50 | ret += '.';
51 | ret += extension;
52 |
53 | return ret;
54 | }
55 |
56 | /**
57 | * Returns a Dated file name using the specified prefix and extension with
58 | * a - after the prefix and before the date
59 | *
60 | * Example: prefix-20151021132402.txt
61 | *
62 | * @param prefix
63 | * @param extension Not including the .
64 | * @return
65 | */
66 | public static String getDatedFileName(String prefix, String extension) {
67 | return FileNameFormatter.getDatedFileName(prefix, "-", extension);
68 | }
69 |
70 | public static String getExtension(String fileName) {
71 | String ret = "";
72 |
73 | int lastDot = fileName.lastIndexOf(".");
74 |
75 | if (lastDot < fileName.length())
76 | ret = fileName.substring(lastDot + 1, fileName.length());
77 |
78 | return ret;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/file/SimpleFileIO.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.file;
5 |
6 | import java.io.BufferedWriter;
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.io.FileWriter;
10 | import java.io.IOException;
11 | import java.util.Scanner;
12 |
13 | /**
14 | * @author Mikel
15 | *
16 | */
17 | public class SimpleFileIO {
18 |
19 | public static void writeStringToFile(String fileName, String s) throws IOException {
20 | writeStringToFile(new File(fileName), s);
21 | }
22 |
23 | public static void writeStringToFile(File file, String s) throws IOException {
24 | BufferedWriter bw = null;
25 |
26 | bw = new BufferedWriter(new FileWriter(file));
27 | bw.write(s);
28 | bw.close();
29 | }
30 |
31 | public static String loadFileToString(String fileName) throws FileNotFoundException {
32 | return loadFileToString(new File(fileName));
33 | }
34 |
35 | public static String loadFileToString(File file) throws FileNotFoundException {
36 | StringBuilder sb = new StringBuilder();
37 | Scanner sc = new Scanner(file);
38 |
39 | while (sc.hasNext()) {
40 | sb.append(sc.nextLine()).append("\n");
41 | }
42 | sc.close();
43 |
44 | return sb.toString();
45 | }
46 |
47 | public static void appendStringToFile(String fileName, String s) throws IOException, FileNotFoundException {
48 | appendStringToFile(new File(fileName), s);
49 | }
50 |
51 | public static void appendStringToFile(File file, String s) throws IOException, FileNotFoundException {
52 | String fileContents = loadFileToString(file);
53 |
54 | if (!fileContents.endsWith("\n")) fileContents += "\n";
55 | fileContents += s;
56 |
57 | writeStringToFile(file, fileContents);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/gui/MenuBarHelper.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.gui;
5 |
6 | import java.awt.event.ActionListener;
7 |
8 | import javax.swing.JMenu;
9 | import javax.swing.JMenuBar;
10 | import javax.swing.JMenuItem;
11 |
12 | /**
13 | * @author Mikel
14 | *
15 | * Class to help with adding Menu Items and Menu Bar options to a menu
16 | *
17 | */
18 | public class MenuBarHelper {
19 | /**
20 | * Initializes a JMenu choice and adds it to the menu bar
21 | *
22 | * @param menu
23 | * @param menuOption
24 | * @param optionName
25 | * @param optionMnemonic
26 | * @param desc
27 | */
28 | public static JMenu addNewMenuOption(JMenuBar menu, String optionName, int optionMnemonic, String desc) {
29 | JMenu menuOption = new JMenu(optionName);
30 |
31 | if (optionMnemonic != 0)
32 | menuOption.setMnemonic(optionMnemonic);
33 |
34 | if (desc != null && !desc.equals(""))
35 | menuOption.getAccessibleContext().setAccessibleDescription(desc);
36 |
37 | if (menu != null) menu.add(menuOption);
38 |
39 | return menuOption;
40 | }
41 |
42 | /**
43 | * Initializes a JMenu choice and adds it to the menu bar
44 | *
45 | * @param menu
46 | * @param optionName
47 | * @return
48 | */
49 | public static JMenu addNewMenuOption(JMenuBar menu, String optionName) {
50 | return MenuBarHelper.addNewMenuOption(menu, optionName, 0, optionName);
51 | }
52 |
53 | /**
54 | * Initializes and adds a new menu item to the menu option on the menu bar
55 | *
56 | * @param menuOption
57 | * @param newItem
58 | * @param itemName
59 | * @param itemShortcut
60 | * @param itemDesc
61 | * @param actionListener
62 | */
63 | public static JMenuItem addNewMenuItem(JMenu menuOption, String itemName, int itemShortcut, String itemDesc, ActionListener actionListener) {
64 | JMenuItem newItem = null;
65 |
66 | if (itemShortcut != 0)
67 | newItem = new JMenuItem(itemName, itemShortcut);
68 | else newItem = new JMenuItem(itemName);
69 |
70 | //quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
71 |
72 | if (itemDesc != null && !itemDesc.equals(""))
73 | newItem.getAccessibleContext().setAccessibleDescription(itemDesc);
74 |
75 | if (actionListener != null)
76 | newItem.addActionListener(actionListener);
77 |
78 | if (menuOption != null) menuOption.add(newItem);
79 |
80 | return newItem;
81 | }
82 |
83 | /**
84 | * Initializes and adds a new menu item to the menu option on the menu bar
85 | *
86 | * @param menuOption
87 | * @param itemName
88 | * @param actionListener
89 | * @return
90 | */
91 | public static JMenuItem addNewMenuItem(JMenu menuOption, String itemName, ActionListener actionListener) {
92 | return MenuBarHelper.addNewMenuItem(menuOption, itemName, 0, itemName, actionListener);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/misc/MapUtil.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.misc;
2 |
3 | import java.util.Collections;
4 | import java.util.Comparator;
5 | import java.util.LinkedHashMap;
6 | import java.util.LinkedList;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | public class MapUtil
11 | {
12 | public static > Map sortByValue( Map map )
13 | {
14 | List> list =
15 | new LinkedList>( map.entrySet() );
16 | Collections.sort( list, new Comparator>()
17 | {
18 | public int compare( Map.Entry o1, Map.Entry o2 )
19 | {
20 | return (o1.getValue()).compareTo( o2.getValue() );
21 | }
22 | } );
23 |
24 | Map result = new LinkedHashMap();
25 | for (Map.Entry entry : list)
26 | {
27 | result.put( entry.getKey(), entry.getValue() );
28 | }
29 | return result;
30 | }
31 |
32 | public static String mapToMultilineString(Map map) {
33 | if (map == null) {
34 | return "Map is null";
35 | }
36 |
37 | if (map.isEmpty()) {
38 | return "Map is empty";
39 | }
40 |
41 | StringBuilder sb = new StringBuilder();
42 |
43 | for (K key : map.keySet()) {
44 | sb.append(key + ": " + map.get(key));
45 | sb.append("\n");
46 | }
47 |
48 | return sb.toString();
49 | }
50 | }
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/misc/ObjectNotInitializedException.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.misc;
5 |
6 | /**
7 | * Custom exception to be thrown when a required object was not intialized
8 | *
9 | * @author Mikel
10 | *
11 | */
12 | public class ObjectNotInitializedException extends Exception {
13 |
14 | private static final long serialVersionUID = 2993512881656200086L;
15 |
16 | public ObjectNotInitializedException() {
17 | super();
18 | }
19 |
20 | /**
21 | * @param message
22 | */
23 | public ObjectNotInitializedException(String message) {
24 | super(message);
25 | }
26 |
27 | /**
28 | * @param cause
29 | */
30 | public ObjectNotInitializedException(Throwable cause) {
31 | super(cause);
32 | }
33 |
34 | /**
35 | * @param message
36 | * @param cause
37 | */
38 | public ObjectNotInitializedException(String message, Throwable cause) {
39 | super(message, cause);
40 | }
41 |
42 | /**
43 | * @param message
44 | * @param cause
45 | * @param enableSuppression
46 | * @param writableStackTrace
47 | */
48 | public ObjectNotInitializedException(String message, Throwable cause,
49 | boolean enableSuppression, boolean writableStackTrace) {
50 | super(message, cause, enableSuppression, writableStackTrace);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/settings/CmdLineProperties.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.settings;
2 |
3 | import java.io.IOException;
4 | import java.io.StringReader;
5 | import java.util.Properties;
6 |
7 | public class CmdLineProperties {
8 |
9 | private CmdLineProperties() { }
10 |
11 | public static Properties toProperties(String[] args) throws IOException {
12 | Properties p = new Properties();
13 |
14 | StringBuilder sb = new StringBuilder();
15 | for (String arg : args) {
16 | sb.append(arg).append("\n");
17 | }
18 |
19 | String cmdLineProps = sb.toString();
20 |
21 | p.load(new StringReader(cmdLineProps));
22 |
23 | return p;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/settings/Settings.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.settings;
5 |
6 |
7 | /**
8 | * @author Mikel
9 | *
10 | */
11 | public abstract class Settings {
12 | /**
13 | * Loads the settings to the static variables using the mdp3_Util
14 | * Settings methods
15 | *
16 | * Currently hardcoded to use filename of settings.txt
17 | */
18 | public static void loadSettings(Class> clazz) {
19 | loadSettings(clazz, "settings.txt");
20 | }
21 |
22 | /**
23 | * Loads the settings to the static variables using the mdp3_Util
24 | * Settings methods
25 | *
26 | * @param class
27 | * @param fileName
28 | */
29 | public static void loadSettings(Class> clazz, String fileName) {
30 | SettingsLoader set = new SettingsLoader(clazz, false);
31 |
32 | set.loadSettings(fileName);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/settings/SettingsLoader.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.settings;
5 |
6 | import java.io.BufferedWriter;
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.io.FileWriter;
10 | import java.io.IOException;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.Modifier;
13 | import java.util.HashMap;
14 | import java.util.Iterator;
15 | import java.util.Map;
16 | import java.util.Map.Entry;
17 | import java.util.Scanner;
18 |
19 | import net.mdp3.java.util.test.SettingsTest;
20 |
21 | /**
22 | * Settings
23 | *
24 | * Java package used to make loading various settings from a text file onto an
25 | * object easier.
26 | *
27 | * To use instantiate this Settings class using either an Object or a Class
28 | * definition, depending on whether the destination class is static or not.
29 | *
30 | * After loadSettings is called with either a File object or String file name,
31 | * the class looks up properties of the class that was passed in earlier, and
32 | * attempts to load values from the text file onto it.
33 | *
34 | * Supported property types are: int, long, double, bool, and String.
35 | *
36 | * Settings Text File usage:
37 | * # or // denotes a comment line, lines beginning with these symbols are ignored
38 | * Key Value pairs should be denoted use property name: value using either : or =
39 | * Values are trimmed of whitespace
40 | * Example:
41 | * #this is an example
42 | * enableSomeSetting: true
43 | * someSettingValue = 500
44 | *
45 | * @author Mikel
46 | * @see SettingsTest.java
47 | */
48 | public class SettingsLoader {
49 | private HashMap settingsMap = new HashMap();
50 | private Object o = null;
51 | private Class> settingsClass;
52 | @SuppressWarnings("unused")
53 | private boolean staticB = true;
54 | private boolean debug = true;
55 | private String saveDivider = ":";
56 |
57 | public SettingsLoader(Class> c) {
58 | this(c, false);
59 | }
60 |
61 | public SettingsLoader(Class> c, boolean debug) {
62 | this(null, c, debug);
63 | }
64 |
65 | public SettingsLoader(Object o, boolean debug) {
66 | this(o, o.getClass(), debug);
67 | }
68 |
69 | public SettingsLoader(Object o, Class> c, boolean debug) {
70 | this.o = o;
71 | this.settingsClass = c;
72 | this.debug = debug;
73 | if (o == null) staticB = false;
74 |
75 | if (debug) {
76 | System.out.println("c: " + c);
77 | System.out.println("getClass: " + c.getClass().getSimpleName());
78 | }
79 | }
80 |
81 | public void loadSettings(String fileName) {
82 | File file = new File(fileName);
83 | loadSettings(file);
84 | }
85 |
86 | public void loadSettings(File file) {
87 | if (debug) System.out.println("loadSettings: " + file.getName());
88 |
89 | settingsMap.clear();
90 |
91 | try {
92 | Scanner sc = new Scanner(file);
93 | String input = "";
94 |
95 | while (sc.hasNext()) input += sc.nextLine() + "\n";
96 | if (debug) System.out.println(input);
97 | sc.close();
98 |
99 | loadToHashMap(input);
100 | hashMapToObject();
101 | } catch (FileNotFoundException e) {
102 | System.out.println("Settings File Not Found: " + file.getAbsolutePath());
103 | //e.printStackTrace();
104 | }
105 | }
106 |
107 | private void loadToHashMap(String str) {
108 | String line[] = str.split("\n");
109 | for (int i = 0; i < line.length; i++) {
110 | if (line[i].length() < 1) continue; //Skip blank lines
111 | if (line[i].charAt(0) == '#') { //Skip lines starting with #
112 | if (debug) System.out.println(line[i]);
113 | continue;
114 | }
115 | if (line[i].startsWith("//")) {
116 | if (debug) System.out.println(line[i]);
117 | continue;
118 | }
119 |
120 | String sp[] = null;
121 | if (line[i].indexOf(':') > -1)
122 | sp = line[i].trim().split(":", 2);
123 | else if (line[i].indexOf('=') > -1)
124 | sp = line[i].trim().split("=", 2);
125 | else {
126 | System.out.println("Error loading line #" + i);
127 | continue;
128 | }
129 |
130 | if (sp.length < 2) continue;
131 | String key = sp[0].trim();
132 | String val = sp[1].trim();
133 | if (debug) System.out.println("Key: " + key + " Val: " + val);
134 |
135 | if (key.length() > 0 && val.length() > 0) {
136 | settingsMap.put(key, val);
137 | }
138 | }
139 | }
140 |
141 | private void hashMapToObject() {
142 | if (settingsMap.size() > 0) {
143 | Iterator> it = settingsMap.entrySet().iterator();
144 | while (it.hasNext()) {
145 | Map.Entry pairs = (Map.Entry)it.next();
146 |
147 | loadPairToObject(pairs.getKey(), pairs.getValue());
148 | }
149 | }
150 | }
151 |
152 | /**
153 | * Currently supports parsing int, long, double, bool, and string types
154 | * @param key
155 | * @param val
156 | */
157 | private void loadPairToObject(String key, String val) {
158 | try {
159 | Field f = settingsClass.getDeclaredField(key);
160 | f.setAccessible(true);
161 |
162 | if (debug) {
163 | System.out.println("Name: " + f.getName() + " FieldClass: " + f.getType());
164 | }
165 |
166 | try {
167 | if (f.getType().equals(int.class)) {
168 | if (o != null && !Modifier.isStatic(f.getModifiers())) {
169 | f.setInt(o, Integer.parseInt(val));
170 | } else if (Modifier.isStatic(f.getModifiers())) {
171 | f.setInt(null, Integer.parseInt(val));
172 | }
173 | } else if (f.getType().equals(long.class)) {
174 | if (o != null && !Modifier.isStatic(f.getModifiers())) {
175 | f.setLong(o, Long.parseLong(val));
176 | } else if (Modifier.isStatic(f.getModifiers())) {
177 | f.setLong(null, Long.parseLong(val));
178 | }
179 | } else if (f.getType().equals(double.class)) {
180 | if (o != null && !Modifier.isStatic(f.getModifiers())) {
181 | f.setDouble(o, Double.parseDouble(val));
182 | } else if (Modifier.isStatic(f.getModifiers())) {
183 | f.setDouble(null, Double.parseDouble(val));
184 | }
185 | } else if (f.getType().equals(boolean.class)) {
186 | if (o != null && !Modifier.isStatic(f.getModifiers())) {
187 | f.setBoolean(o, val.trim().equalsIgnoreCase("true"));
188 | } else if (Modifier.isStatic(f.getModifiers())) {
189 | f.setBoolean(null, val.trim().equalsIgnoreCase("true"));
190 | }
191 | } else {
192 | if (o != null && !Modifier.isStatic(f.getModifiers())) {
193 | f.set(o, val);
194 | } else if (Modifier.isStatic(f.getModifiers())) {
195 | f.set(null, val);
196 | }
197 | }
198 | } catch (IllegalArgumentException | IllegalAccessException e) {
199 | System.out.println("Access not permitted: " + e);
200 | e.printStackTrace();
201 | }
202 | } catch (NoSuchFieldException e) {
203 | /*System.out.println("Error No Such Field " + key + "; " + e);
204 | e.printStackTrace();*/
205 | } catch (SecurityException e) {
206 | System.out.println("Error: Security Exception: " + e);
207 | e.printStackTrace();
208 | }
209 | }
210 |
211 | public void saveSettings(String fileName) {
212 | saveSettings(new File(fileName));
213 | }
214 |
215 | public void saveSettings(File file) {
216 | if (debug) System.out.println("Saving Settings to " + file.getAbsolutePath());
217 |
218 | String outString = "";
219 | outString += '#' + this.settingsClass.getSimpleName() + '\n';
220 |
221 | Field fields[] = this.settingsClass.getFields();
222 | for (int i = 0; i < fields.length; i++) {
223 | String fieldStr = getSaveString(fields[i]);
224 | if (fieldStr != "") outString += fieldStr + '\n';
225 | }
226 |
227 | writeString(file, outString);
228 |
229 | if (debug) System.out.println("Done");
230 | }
231 |
232 | private void writeString(File file, String s) {
233 | BufferedWriter bw = null;
234 |
235 | try {
236 | bw = new BufferedWriter(new FileWriter(file));
237 | bw.write(s);
238 | bw.close();
239 | } catch (IOException e) {
240 | System.out.println("Error saving file: " + e);
241 | e.printStackTrace();
242 | }
243 | }
244 |
245 | private String getSaveString(Field f) {
246 | String retStr = "";
247 |
248 | if (Modifier.isPublic(f.getModifiers())) {
249 | if (Modifier.isStatic(f.getModifiers())) {
250 | try {
251 | retStr += f.getName();
252 | retStr += saveDivider + " ";
253 | retStr += f.get(this.settingsClass);
254 | } catch (IllegalArgumentException e) {
255 | System.out.println("Illegal Argument: " + e);
256 | e.printStackTrace();
257 | } catch (IllegalAccessException e) {
258 | System.out.println("Illegal Access: " + e);
259 | e.printStackTrace();
260 | }
261 | } else if (o != null) {
262 | try {
263 | retStr += f.getName();
264 | retStr += saveDivider + " ";
265 | retStr += f.get(o);
266 | } catch (IllegalArgumentException e) {
267 | System.out.println("Illegal Argument: " + e);
268 | e.printStackTrace();
269 | } catch (IllegalAccessException e) {
270 | System.out.println("Illegal Access: " + e);
271 | e.printStackTrace();
272 | }
273 | }
274 | }
275 | return retStr;
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/string/StringUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.string;
5 |
6 | /**
7 | * @author Mikel
8 | *
9 | */
10 | public class StringUtils {
11 | public static int tryParseInt(String str) throws Exception {
12 | int ret = 0;
13 |
14 | try {
15 | ret = Integer.parseInt(str);
16 | } catch (NumberFormatException nfe) {
17 | throw new Exception("Invalid String " + str);
18 | }
19 |
20 | return ret;
21 | }
22 |
23 | public static > String[] enumToString(Class enumData) {
24 | E[] enumAr = enumData.getEnumConstants();
25 | String namesAr[] = new String[enumAr.length];
26 |
27 | for (int i = 0; i < enumAr.length; i++) {
28 | namesAr[i] = enumAr[i].name();
29 | }
30 |
31 | return namesAr;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/BatchTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.test;
5 |
6 | import java.io.File;
7 | import java.net.URL;
8 |
9 | import net.mdp3.java.util.console.ConsoleReader;
10 |
11 | /**
12 | * @author Mikel
13 | *
14 | */
15 | public class BatchTest {
16 |
17 | private ConsoleReader cr;
18 |
19 | /**
20 | * Main entry point for Util package when testing.
21 | *
22 | * @param args
23 | */
24 | @SuppressWarnings("unused")
25 | public static void main(String[] args) {
26 | BatchTest b = new BatchTest();
27 | }
28 |
29 | public BatchTest() {
30 | cr = new ConsoleReader("Batch", this);
31 |
32 | URL url = getClass().getResource("BatchTest.txt");
33 | File file = new File(url.getPath());
34 | cr.openBatch(file);
35 | cr.startBatch();
36 | }
37 |
38 | public void consoleTest() {
39 | System.out.println("ConsoleTest!");
40 | }
41 |
42 | public void consoleTest2(String s) {
43 | System.out.println("ConsoleTest2: " + s);
44 | }
45 |
46 | public void quit() {
47 | cr.quit();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/BatchTest.txt:
--------------------------------------------------------------------------------
1 | help 1000
2 | asdf 100
3 | asdfdsf 1000
4 | help 500
5 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/ConsoleArgumentHandlerTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.test;
5 |
6 | import java.util.HashMap;
7 | import java.util.List;
8 |
9 | import net.mdp3.java.util.console.ConsoleArgumentHandler;
10 |
11 | /**
12 | * @author Mikel
13 | *
14 | */
15 | public class ConsoleArgumentHandlerTest {
16 |
17 | /**
18 | *
19 | */
20 | public ConsoleArgumentHandlerTest() {
21 |
22 | }
23 |
24 | public void method1() {
25 | System.out.println("run method 1");
26 | }
27 |
28 | public void method2(String value) {
29 | System.out.println("run method 2: " + value);
30 | }
31 |
32 | public void setTest1() {
33 | System.out.println("setTest1 test");
34 | }
35 |
36 | public void setTest2(String t) {
37 | System.out.println("setTest2 test " + t);
38 | }
39 |
40 | public void setATest3() {
41 | System.out.println("setATest3");
42 | }
43 |
44 | public void setTest4(Object o) {
45 | System.out.println("setTest4");
46 | }
47 |
48 | /**
49 | * @param args
50 | */
51 | public static void main(String[] args) {
52 | System.out.println("ConsoleArgumentHandler Test Start");
53 | ConsoleArgumentHandlerTest caht = new ConsoleArgumentHandlerTest();
54 | ConsoleArgumentHandler cah = new ConsoleArgumentHandler(caht, args);
55 |
56 | HashMap map = new HashMap();
57 | map.put("m", "method1");
58 | map.put("m2", "method2");
59 | cah.setShortCutMap(map);
60 |
61 | try {
62 | cah.addShortcut("m1", "method1");
63 | cah.addShortcut("m22", "method2");
64 | cah.addShortcut("m3", "method3"); //Should throw an exception
65 | } catch (NoSuchMethodException e1) {
66 | e1.printStackTrace();
67 | System.out.println("Error: Method not found or wrong param types: " + e1);
68 | }
69 |
70 | try {
71 | List failedCmds = cah.runArgs();
72 |
73 | for (String cmd : failedCmds)
74 | System.out.println("Failed: " + cmd);
75 | } catch (Exception e) {
76 | e.printStackTrace();
77 | }
78 |
79 | //Test autoshortcut
80 | cah.clearShortcuts();
81 | cah.autoCreateShortCuts();
82 | System.out.println(cah.getShortcutMap());
83 | //should have {test1=setTest1, atest3=setATest3, t=setTest1, a=setATest3, test2=setTest2}
84 | //methods that start with set, have 0 or 1 string param, and 1 letter shortcuts for the first new letter found
85 |
86 | System.out.println("ConsoleArgumentHandler Test End");
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/SettingsSaveTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.test;
5 |
6 | import java.io.File;
7 |
8 | import net.mdp3.java.util.settings.SettingsLoader;
9 |
10 | /**
11 | * @author Mikel
12 | *
13 | */
14 | public class SettingsSaveTest {
15 | public static int staticIntParm = 0;
16 | public static String staticStringParm = "STATIC";
17 | public static boolean staticBoolParm = false;
18 | public static long staticLongParm = 123456789;
19 | public static double staticDoubleParm = 1.55;
20 |
21 | public int intParm = 0;
22 | public String stringParm = "String";
23 | public boolean boolParm = false;
24 | public long longParm = 123456789;
25 | public double doubleParm = 1.55;
26 | public int newVal = 100;
27 |
28 | public static void main(String[] args) {
29 | System.out.println("Static Test");
30 | SettingsLoader set = new SettingsLoader(SettingsSaveTest.class, true);
31 |
32 | File file = new File("SettingsStaticSaveTest.txt");
33 | set.saveSettings(file);
34 |
35 | System.out.println("Object Test");
36 | @SuppressWarnings("unused")
37 | SettingsSaveTest sst = new SettingsSaveTest();
38 | }
39 |
40 | public SettingsSaveTest() {
41 | SettingsLoader set = new SettingsLoader(this, true);
42 |
43 | File file = new File("SettingsSaveTest.txt");
44 | set.saveSettings(file);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/SettingsTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.test;
5 |
6 | import java.io.File;
7 | import java.net.URL;
8 |
9 | import net.mdp3.java.util.settings.SettingsLoader;
10 |
11 | /**
12 | * @author Mikel
13 | *
14 | */
15 | public class SettingsTest {
16 |
17 | /**
18 | * @param args
19 | */
20 |
21 | public static int staticIntParm = 0;
22 | public static String staticStringParm = "STATIC";
23 | public static boolean staticBoolParm = false;
24 | public static long staticLongParm = 123456789;
25 | public static double staticDoubleParm = 1.55;
26 |
27 | public int intParm = 0;
28 | public String stringParm = "String";
29 | public boolean boolParm = false;
30 | public long longParm = 123456789;
31 | public double doubleParm = 1.55;
32 | public int newVal = 100;
33 |
34 | @SuppressWarnings("unused")
35 | public static void main(String[] args) {
36 | System.out.println("Static Test: ");
37 | SettingsLoader set = new SettingsLoader(SettingsTest.class, true);
38 |
39 | URL url = SettingsTest.class.getResource("SettingsTest.txt");
40 | File file = new File(url.getPath());
41 | set.loadSettings(file);
42 | showStaticSettings();
43 |
44 | System.out.println("\nObject Test:");
45 | SettingsTest st = new SettingsTest();
46 | }
47 |
48 | public SettingsTest() {
49 | SettingsLoader set = new SettingsLoader(this, true);
50 |
51 | URL url = SettingsTest.class.getResource("SettingsTest.txt");
52 | File file = new File(url.getPath());
53 | set.loadSettings(file);
54 | showSettings();
55 | }
56 |
57 | public static void showStaticSettings() {
58 | System.out.println("Settings after load:");
59 | System.out.println("staticIntParm: " + staticIntParm);
60 | System.out.println("staticStringParm: " + staticStringParm);
61 | System.out.println("staticBoolParm: " + staticBoolParm);
62 | System.out.println("staticLongParm: " + staticLongParm);
63 | System.out.println("staticDoubleParm: " + staticDoubleParm);
64 | }
65 |
66 | public void showSettings() {
67 | System.out.println("Settings after load:");
68 | System.out.println("intParm: " + intParm);
69 | System.out.println("stringParm: " + stringParm);
70 | System.out.println("boolParm: " + boolParm);
71 | System.out.println("longParm: " + longParm);
72 | System.out.println("doubleParm: " + doubleParm);
73 | System.out.println("newVal: " + newVal);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/SettingsTest.txt:
--------------------------------------------------------------------------------
1 | #Settings Test file
2 | intParm: 500
3 | stringParm: sgdfgdfg
4 | boolParm: true
5 | longParm: 999999999
6 | doubleParm: 3.14
7 |
8 | staticIntParm: 650
9 | staticStringParm: 123452345345
10 | staticBoolParm: true
11 | staticLongParm: 888888888
12 | staticDoubleParm: 2.255
13 |
14 | //new Comment!!
15 | newVal = 500
16 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/SimpleFileIOTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.test;
5 |
6 | import java.io.FileNotFoundException;
7 | import java.io.IOException;
8 |
9 | import net.mdp3.java.util.file.SimpleFileIO;
10 |
11 | /**
12 | * Test script for the SimpleFileIO class.
13 | *
14 | * Writes a string to a file, loads the file, then appends a string to file
15 | * and reloads the contents.
16 | *
17 | * @author Mikel
18 | *
19 | */
20 | public class SimpleFileIOTest {
21 |
22 | /**
23 | * @param args
24 | */
25 | public static void main(String[] args) {
26 | String text = "Test String!!@RWSF";
27 | try {
28 | SimpleFileIO.writeStringToFile("test.txt", text);
29 | } catch (IOException e) {
30 | e.printStackTrace();
31 | }
32 |
33 | try {
34 | System.out.println(SimpleFileIO.loadFileToString("test.txt"));
35 | } catch (FileNotFoundException e) {
36 | e.printStackTrace();
37 | }
38 |
39 | try {
40 | SimpleFileIO.appendStringToFile("test.txt", "Appending!");
41 | } catch (FileNotFoundException e) {
42 | e.printStackTrace();
43 | } catch (IOException e) {
44 | e.printStackTrace();
45 | }
46 |
47 | try {
48 | System.out.println(SimpleFileIO.loadFileToString("test.txt"));
49 | } catch (FileNotFoundException e) {
50 | e.printStackTrace();
51 | }
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/Util_Test.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.test;
2 |
3 | import net.mdp3.java.util.console.ConsoleReader;
4 |
5 | /**
6 | * util
7 | * @author Mikel
8 | *
9 | * Utils Test class
10 | */
11 | public class Util_Test {
12 |
13 | private ConsoleReader cr;
14 |
15 | /**
16 | * Main entry point for Util package when testing.
17 | *
18 | * @param args
19 | */
20 | @SuppressWarnings("unused")
21 | public static void main(String[] args) {
22 | Util_Test u = new Util_Test();
23 | }
24 |
25 | public Util_Test() {
26 | cr = new ConsoleReader("Utils", this);
27 | }
28 |
29 | public void consoleTest() {
30 | System.out.println("ConsoleTest!");
31 | }
32 |
33 | public void consoleTest2(String s) {
34 | System.out.println("ConsoleTest2: " + s);
35 | }
36 |
37 | public void quit() {
38 | cr.quit();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/test/WebserviceTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.test;
5 |
6 | import java.io.IOException;
7 | import java.net.BindException;
8 | import java.util.Iterator;
9 | import java.util.Map;
10 | import java.util.Map.Entry;
11 |
12 | import net.mdp3.java.util.webservice.Webservice;
13 | import net.mdp3.java.util.webservice.WebserviceListener;
14 |
15 | /**
16 | * Test/Example class for using the Webservice class
17 | * Creates a webserver at localhost:83/test which returns the URL parameters
18 | * to the page
19 | *
20 | * @author Mikel
21 | *
22 | */
23 | public class WebserviceTest implements WebserviceListener {
24 |
25 | Webservice ws;
26 |
27 | /**
28 | * @param args
29 | */
30 | @SuppressWarnings("unused")
31 | public static void main(String[] args) {
32 | WebserviceTest test = new WebserviceTest(83, "/test");
33 | }
34 |
35 | public WebserviceTest(int port, String name) {
36 | try {
37 | ws = new Webservice(port, name, this);
38 | } catch (BindException e) {
39 | System.out.println("Error opening port: " + port);
40 | } catch (IOException e) {
41 | System.out.println("Error starting webservice: " + e);
42 | e.printStackTrace();
43 | }
44 |
45 | }
46 |
47 |
48 | /**
49 | * wsAccess Override Required by the WebserviceListener interface
50 | *
51 | * It gets passed a HashMap containing the parameters and values used in
52 | * the Webservice URL.
53 | *
54 | * @param params HashMap containing the parameters and values used in the URL
55 | * @return String with the parameters and values from the URL
56 | */
57 | @Override
58 | public String wsAccess(Map params) {
59 | String returnValue = "";
60 |
61 | if (params.size() > 0) {
62 | returnValue = "Has Params! " + params.size() + '\n';
63 | Iterator> it = params.entrySet().iterator();
64 | while (it.hasNext()) {
65 | Map.Entry pairs = (Map.Entry)it.next();
66 | returnValue += "Key: " + pairs.getKey() + " = " + pairs.getValue() + '\n';
67 | }
68 | }
69 | else returnValue = "Invalid Params!";
70 | System.out.println("RetVal: " + returnValue);
71 |
72 | return returnValue;
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/WSResponse.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.webservice;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | public class WSResponse {
9 | private int responseCode = 200;
10 | private byte[] responseBody;
11 | private Map> headersMap = null;
12 |
13 | private static final String DEFAULT_CHARSET = "UTF-8";
14 |
15 | public WSResponse() {
16 | this(200);
17 | }
18 |
19 | public WSResponse(int responseCode) {
20 | this(responseCode, (byte[]) null);
21 | }
22 |
23 | public WSResponse(int responseCode, String responseBody) throws UnsupportedEncodingException {
24 | this(responseCode, responseBody, DEFAULT_CHARSET);
25 | }
26 |
27 | public WSResponse(int responseCode, String responseBody, String charset) throws UnsupportedEncodingException {
28 | this(responseCode, responseBody.getBytes(charset));
29 | }
30 |
31 | public WSResponse(int responseCode, byte[] responseBody) {
32 | this(responseCode, responseBody, new HashMap>());
33 | }
34 |
35 | public WSResponse(int responseCode, byte[] responseBody, Map> headersMap) {
36 | setResponseCode(responseCode);
37 | setResponseBody(responseBody);
38 | setHeadersMap(headersMap);
39 | }
40 |
41 | public int getResponseCode() {
42 | return responseCode;
43 | }
44 | public void setResponseCode(int responseCode) {
45 | this.responseCode = responseCode;
46 | }
47 | public byte[] getResponseBody() {
48 | return responseBody;
49 | }
50 | public void setResponseBody(byte[] responseBody) {
51 | this.responseBody = responseBody;
52 | }
53 | public void setResponseBody(String responseBody) throws UnsupportedEncodingException {
54 | this.responseBody = responseBody.getBytes(DEFAULT_CHARSET);
55 | }
56 | public Map> getHeadersMap() {
57 | return headersMap;
58 | }
59 | public void setHeadersMap(Map> headersMap) {
60 | this.headersMap = headersMap;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/Webservice.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.webservice;
5 |
6 | import java.io.IOException;
7 | import java.io.OutputStream;
8 | import java.net.BindException;
9 | import java.util.Map;
10 | import java.util.logging.Logger;
11 |
12 | //These imports require a sun/oracle jvm
13 | //http://stackoverflow.com/questions/9579970/can-not-use-the-com-sun-net-httpserver-httpserver
14 | import com.sun.net.httpserver.HttpExchange;
15 | import com.sun.net.httpserver.HttpHandler;
16 |
17 | /**
18 | * Webservice
19 | *
20 | * Simple Java Webservice using the Sun HTTP Server implementation. The
21 | * necessary packages may not be included in all JVMs.
22 | *
23 | * This class creates a webserver at the specified port and context, which
24 | * listens for connections, builds the access URL parameters into a HashMap
25 | * and finally calls the wsAccess callback specified by the WebserviceListener
26 | * interface. The String returned by wsAccess is returned back to the browser.
27 | *
28 | * @author Mikel
29 | * @see http://stackoverflow.com/questions/9579970/can-not-use-the-com-sun-net-httpserver-httpserver
30 | * @see http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html
31 | */
32 | @SuppressWarnings("restriction")
33 | public class Webservice extends WebserviceBase {
34 | private final static String CLAZZ = Webservice.class.getName();
35 | private final static Logger LOG = Logger.getLogger(CLAZZ);
36 |
37 | /**
38 | * Starts the SUN class webservice with service name on specified port
39 | *
40 | * @param port Port to use, must not be in use
41 | * @param name Webservice Name, this will be in the URL
42 | * @param listener Class implementing WebserviceListener for callbacks
43 | * @throws BindException
44 | * @throws IOException
45 | */
46 | public Webservice(int port, String name, WebserviceListener listener) throws BindException, IOException {
47 | super(port, name, new GetHandler(listener));
48 | }
49 |
50 | /**
51 | * called by http://ip/name/~
52 | * parses url to get user info and file to send
53 | *
54 | * @author Mikel
55 | *
56 | */
57 | static class GetHandler implements HttpHandler {
58 | //TODO Add sending files, can set file serve folder on init and serve files from it based on URL
59 | HttpExchange t;
60 | WebserviceListener wsl;
61 |
62 | public GetHandler(WebserviceListener listener) {
63 | this.wsl = listener;
64 | }
65 |
66 | /**
67 | *
68 | */
69 | public void handle(HttpExchange t) throws IOException {
70 | LOG.entering(CLAZZ, "handle", "t: " + t);
71 |
72 | this.t = t;
73 | LOG.finer("Server: Get handler Called");
74 |
75 | Map map = WebserviceUtil.getParamsMap(t);
76 |
77 | //Headers h = t.getResponseHeaders();
78 | String response = wsl.wsAccess(map);
79 | LOG.finer(response);
80 |
81 | t.sendResponseHeaders(200, response.length());
82 | OutputStream os = t.getResponseBody();
83 | os.write(response.getBytes());
84 | os.close();
85 |
86 | LOG.exiting(CLAZZ, "handle");
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/WebserviceBase.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.webservice;
2 |
3 | import java.io.IOException;
4 | import java.net.BindException;
5 | import java.net.InetSocketAddress;
6 | import java.util.logging.Logger;
7 |
8 | import com.sun.net.httpserver.HttpHandler;
9 | import com.sun.net.httpserver.HttpServer;
10 |
11 | @SuppressWarnings("restriction")
12 | public class WebserviceBase {
13 | private final static String CLAZZ = WebserviceBase.class.getName();
14 | private final static Logger LOG = Logger.getLogger(CLAZZ);
15 |
16 | //private boolean running = true;
17 | protected int port;
18 | protected String name = "ws";
19 |
20 | protected HttpServer server;
21 |
22 | protected HttpHandler handler;
23 |
24 | public WebserviceBase(int port, String name, HttpHandler listener) throws BindException, IOException {
25 | LOG.entering(CLAZZ, "Webservice", "port:" + port + " name:" + name);
26 | if (name.charAt(0) != '/') name = "/" + name; //HttpServer.createContext arg0 is required to begin with /
27 |
28 | this.port = port;
29 | this.name = name;
30 | this.handler = listener;
31 |
32 | startServer();
33 |
34 | LOG.exiting(CLAZZ, "Webservice");
35 | }
36 |
37 | public void startServer() throws BindException, IOException {
38 | LOG.entering(CLAZZ, "startServer");
39 |
40 | server = HttpServer.create(new InetSocketAddress(this.port), 0);
41 | server.createContext(this.name, handler);
42 | server.setExecutor(null);
43 | server.start();
44 |
45 | LOG.exiting(CLAZZ, "startServer");
46 | }
47 |
48 | /**
49 | * Stops the webservice
50 | *
51 | * @param delay
52 | * @throws Exception
53 | */
54 | public void stopServer(int delay) throws Exception {
55 | LOG.entering(CLAZZ, "stopServer");
56 |
57 | server.stop(delay);
58 |
59 | LOG.exiting(CLAZZ, "stopServer");
60 | }
61 |
62 | /**
63 | * Restarts the service and can change the port
64 | *
65 | * @param delay
66 | * @param newPort
67 | * @throws Exception
68 | */
69 | public void restart(int delay, int newPort) throws Exception {
70 | LOG.entering(CLAZZ, "restart");
71 |
72 | stopServer(delay);
73 | this.port = newPort;
74 | startServer();
75 |
76 | LOG.exiting(CLAZZ, "restart");
77 | }
78 |
79 | public HttpHandler getHandler() {
80 | return handler;
81 | }
82 |
83 | public void setHandler(HttpHandler handler) {
84 | this.handler = handler;
85 | }
86 |
87 | public int getPort() {
88 | return port;
89 | }
90 |
91 | public void setPort(int port) {
92 | this.port = port;
93 | }
94 |
95 | public String getName() {
96 | return name;
97 | }
98 |
99 | public void setName(String name) {
100 | this.name = name;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/WebserviceClient.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.webservice;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.DataOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStreamReader;
10 | import java.net.HttpURLConnection;
11 | import java.net.URL;
12 | import java.net.URLConnection;
13 | import java.util.logging.Logger;
14 |
15 | /**
16 | * @author Mikel
17 | *
18 | */
19 | public class WebserviceClient {
20 | private final static Logger LOG = Logger.getLogger(WebserviceClient.class.getName());
21 | private final static String NAME = "Util-WebserviceClient";
22 |
23 | /**
24 | * Opens an HTTP Connection to the specified URL and returns the result
25 | *
26 | * @param urlStr
27 | * @return
28 | * @throws IOException
29 | */
30 | public static String webserviceCall(String urlStr) throws IOException {
31 | URL url = new URL(urlStr);
32 | return webserviceCall(url);
33 | }
34 |
35 | /**
36 | * Opens an HTTP Connection to the specified URL and returns the result
37 | *
38 | * @param url
39 | * @return response from web server
40 | * @throws IOException
41 | */
42 | public static String webserviceCall(URL url) throws IOException {
43 | LOG.entering(WebserviceClient.NAME, "webserviceCall");
44 |
45 | URLConnection urlc = url.openConnection();
46 | urlc.connect();
47 |
48 | BufferedReader in = new BufferedReader(new InputStreamReader(
49 | urlc.getInputStream()));
50 |
51 | String inputLine;
52 | String resp = "";
53 | while ((inputLine = in.readLine()) != null) {
54 | resp += inputLine + '\n';
55 | }
56 | LOG.finer("Response: " + resp);
57 | in.close();
58 |
59 | LOG.exiting(WebserviceClient.NAME, "webserviceCall", "ret=" + resp);
60 | return resp;
61 | }
62 |
63 | public static String webservicePost(String urlStr, String data, boolean waitForResult) throws IOException {
64 | URL url = new URL(urlStr);
65 | return webservicePost(url, data, waitForResult);
66 | }
67 |
68 | public static String webservicePost(URL url, String data, boolean waitForResult) throws IOException {
69 | LOG.entering(WebserviceClient.NAME, "webservicePost", new Object[]
70 | {"url: " + url + "data: " + data, "waitForResult: " + waitForResult});
71 |
72 | String ret = "";
73 |
74 | HttpURLConnection con = (HttpURLConnection) url.openConnection();
75 | con.setRequestMethod("POST");
76 |
77 | con.setDoOutput(true);
78 | DataOutputStream out = new DataOutputStream(con.getOutputStream());
79 | out.writeBytes(data);
80 | out.flush();
81 | out.close();
82 |
83 | int responseCode = con.getResponseCode();
84 | LOG.fine("Response Code: " + responseCode);
85 |
86 | if (waitForResult) {
87 | BufferedReader in = new BufferedReader(
88 | new InputStreamReader(con.getInputStream()));
89 | String inputLine;
90 |
91 | while ((inputLine = in.readLine()) != null) {
92 | ret += "\n" + inputLine;
93 | }
94 | in.close();
95 | } else {
96 | ret += responseCode;
97 | }
98 |
99 | LOG.fine(ret);
100 |
101 | LOG.exiting(WebserviceClient.NAME, "webservicePost", "Response Code: " + responseCode + "ret=" + ret);
102 | return ret;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/WebserviceConstants.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.webservice;
2 |
3 | public class WebserviceConstants {
4 |
5 | public static final String HTTP_GET = "GET";
6 |
7 | public static final String HTTP_POST = "POST";
8 |
9 |
10 | public static final int HTTP_OK = 200;
11 |
12 | public static final int HTTP_NOT_FOUND = 404;
13 |
14 | public static final int HTTP_UNAUTHORIZED = 401;
15 |
16 | public static final int HTTP_INTERNAL_ERROR = 500;
17 | }
18 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/WebserviceListener.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.webservice;
5 |
6 | import java.util.Map;
7 |
8 | /**
9 | * This interface is used to define the callback for the Webservice Class.
10 | *
11 | * @author Mikel
12 | *
13 | */
14 | public interface WebserviceListener {
15 |
16 | /**
17 | * Callback for calls to the Webservice
18 | *
19 | * It gets the params in a hashmap, using the ¶m=value form and
20 | * returns the String to be sent back to the browser
21 | *
22 | * Example url: http://localhost:80/context&parm1=aaa&parm2=bbb
23 | * Would get passed a hashmap with
24 | * Key: parm1 Value: aaa
25 | * Key: parm2 Value: bbb
26 | *
27 | * @param params HashMap containing the parameters and values used in the URL
28 | * @return String to be send back to the browser
29 | */
30 | public abstract String wsAccess(Map params);
31 | }
32 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/webservice/WebserviceUtil.java:
--------------------------------------------------------------------------------
1 | package net.mdp3.java.util.webservice;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.logging.Logger;
9 |
10 | import com.sun.net.httpserver.HttpExchange;
11 |
12 | @SuppressWarnings("restriction")
13 | public class WebserviceUtil {
14 | private final static String CLAZZ = WebserviceUtil.class.getName();
15 | private final static Logger LOG = Logger.getLogger(CLAZZ);
16 |
17 | private WebserviceUtil() { }
18 |
19 | /**
20 | * Splits the requestURI to a hashmap after the ? by splitting on =
21 | *
22 | * @param t
23 | * @return
24 | */
25 | public static Map getParamsMap(HttpExchange t) {
26 | LOG.fine("Method: " + t.getRequestMethod());
27 |
28 | Map map = new HashMap();
29 |
30 | //get request url /get/command info
31 | String command = t.getRequestURI().toString();
32 | LOG.fine("Command: " + command);
33 |
34 | String params = command.substring(command.indexOf("?") + 1);
35 |
36 | if (params.length() > 0) {
37 | String[] vars = params.split("&");
38 | for (int i = 0; i < vars.length; i++) {
39 | LOG.finer("var " + i + ": " + vars[i]);
40 |
41 | String[] parmPair = vars[i].split("=");
42 | if (parmPair.length == 2) {
43 | LOG.finer("Key: " + parmPair[0] + " Value: " + parmPair[1]);
44 |
45 | map.put(parmPair[0], parmPair[1]);
46 | }
47 | }
48 | }
49 |
50 | return map;
51 | }
52 |
53 | /**
54 | * Util method to write the WSResponse object, headers, code, and body to a httpExchange
55 | *
56 | * @param httpExchange
57 | * @param response
58 | * @throws IOException
59 | */
60 | public static void writeResponse(HttpExchange httpExchange, WSResponse response) throws IOException {
61 | Map> headers = response.getHeadersMap();
62 | for (String header: headers.keySet()) {
63 | for (String value: headers.get(header)) {
64 | httpExchange.getResponseHeaders().add(header, value);
65 | }
66 | }
67 |
68 | httpExchange.sendResponseHeaders(response.getResponseCode(), response.getResponseBody().length);
69 |
70 | OutputStream os = httpExchange.getResponseBody();
71 | os.write(response.getResponseBody());
72 |
73 | os.close();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/xml/DomXml.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.xml;
5 |
6 | import org.w3c.dom.Document;
7 | import org.w3c.dom.Element;
8 |
9 | /**
10 | * @author Mikel
11 | *
12 | */
13 | public interface DomXml {
14 | public Element toXml(Document doc);
15 | public void fromXml(Element e) throws Exception;
16 | }
17 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/src/net/mdp3/java/util/xml/XmlHelper.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package net.mdp3.java.util.xml;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.io.StringWriter;
9 |
10 | import javax.xml.parsers.DocumentBuilder;
11 | import javax.xml.parsers.DocumentBuilderFactory;
12 | import javax.xml.parsers.ParserConfigurationException;
13 | import javax.xml.transform.OutputKeys;
14 | import javax.xml.transform.Transformer;
15 | import javax.xml.transform.TransformerException;
16 | import javax.xml.transform.TransformerFactory;
17 | import javax.xml.transform.TransformerFactoryConfigurationError;
18 | import javax.xml.transform.dom.DOMSource;
19 | import javax.xml.transform.stream.StreamResult;
20 |
21 | import org.w3c.dom.Document;
22 | import org.w3c.dom.Element;
23 | import org.xml.sax.SAXException;
24 |
25 | /**
26 | * @author Mikel
27 | *
28 | */
29 | public class XmlHelper {
30 |
31 | /**
32 | * Method to make adding repetitive text nodes to an element easier.
33 | *
34 | * @param doc Java DOM Doc which is the items get added to
35 | * @param name Name of the new element
36 | * @param val Text Value of the new element
37 | * @return Element containing a value ready to append to another Element
38 | */
39 | public static Element newTextElement(Document doc, String name, Object val) {
40 | Element e = doc.createElement(name);
41 | e.appendChild(doc.createTextNode(val.toString()));
42 | return e;
43 | }
44 |
45 | /**
46 | * Converts a Java DOM Xml Element to a String for simple output to
47 | * console, logs, or files.
48 | *
49 | * @param e Element to convert
50 | * @return String representation of element
51 | * @throws TransformerFactoryConfigurationError
52 | * @throws TransformerException
53 | */
54 | public static String elementToString(Element e) throws TransformerFactoryConfigurationError, TransformerException {
55 | String ret = "";
56 | Transformer transformer;
57 |
58 | transformer = TransformerFactory.newInstance().newTransformer();
59 | transformer.setOutputProperty(OutputKeys.INDENT, "yes");
60 |
61 | StreamResult result = new StreamResult(new StringWriter());
62 | DOMSource source = new DOMSource(e);
63 | transformer.transform(source, result);
64 |
65 | ret = result.getWriter().toString();
66 |
67 | return ret;
68 | }
69 |
70 | /**
71 | * Returns a new Java DOM Doc object for use with elements. This doc should
72 | * not be used for saving it is just used for internal copy/move/load type
73 | * functions.
74 | *
75 | * @return
76 | */
77 | public static Document getNewDoc() {
78 | DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
79 | DocumentBuilder docBuilder;
80 |
81 | try {
82 | docBuilder = docFactory.newDocumentBuilder();
83 |
84 | // root elements
85 | Document doc = docBuilder.newDocument();
86 | //Element rootElement = doc.createElement(rootElementName);
87 | //doc.appendChild(rootElement);
88 |
89 | return doc;
90 | } catch (ParserConfigurationException e) {
91 | e.printStackTrace();
92 | }
93 |
94 | return null;
95 | }
96 |
97 | public static void saveDocument(Document doc, File file) throws TransformerException {
98 | TransformerFactory transformerFactory = TransformerFactory.newInstance();
99 | Transformer transformer = transformerFactory.newTransformer();
100 | DOMSource source = new DOMSource(doc);
101 | StreamResult result = new StreamResult(file);
102 |
103 | transformer.transform(source, result);
104 | }
105 |
106 | /**
107 | * Reads in an xml file and returns the root element
108 | *
109 | * @param fileLocation
110 | * @return
111 | * @throws ParserConfigurationException
112 | * @throws SAXException
113 | * @throws IOException
114 | */
115 | public static Element readXmlFile(String fileLocation) throws ParserConfigurationException, SAXException, IOException {
116 | File f = new File(fileLocation);
117 | return XmlHelper.readXmlFile(f);
118 | }
119 |
120 | /**
121 | * Reads in an xml file and returns the root Element
122 | *
123 | * @param f
124 | * @return
125 | * @throws ParserConfigurationException
126 | * @throws SAXException
127 | * @throws IOException
128 | */
129 | public static Element readXmlFile(File f) throws ParserConfigurationException, SAXException, IOException {
130 | Element retE = null;
131 |
132 | DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
133 | DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
134 | Document doc = dBuilder.parse(f);
135 |
136 | doc.getDocumentElement().normalize();
137 |
138 | retE = doc.getDocumentElement();
139 |
140 | return retE;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testAnimation/001.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testAnimation/001.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testAnimation/002.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testAnimation/002.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testAnimation/003.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testAnimation/003.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testAnimation/004.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testAnimation/004.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testAnimation2/ChristmasTree.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testAnimation2/ChristmasTree.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testAnimation2/HOHOHO.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testAnimation2/HOHOHO.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testImages/ChristmasTree.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testImages/ChristmasTree.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testImages/HI.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testImages/HI.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testImages/HOHOHO.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testImages/HOHOHO.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testImages/test.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testImages/test.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testImages/testScale1.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testImages/testScale1.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/testImages/test_vert.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelduke/LedTable/849ee4259652a0a1783444375f882bcd718a8ea9/RPi-Java-LedTable/testImages/test_vert.bmp
--------------------------------------------------------------------------------
/RPi-Java-LedTable/www/LedTable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Led Table Controller
4 |
5 |
6 |
7 | Led Table Controller
8 | WS Version 1
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------