I'm planning to use (Handwritten Number Recognition by Yan Cheng, Cheok) for a project I'm working on it,I should use their database for number recognition but the files are not on their website, I should use a file called "LRTBHVtrainingdata.txtI=96H=200LR=0.9M=0.1C=2000.snet" as they say in their tutorial,But what I found on their website (http://yann.lecun.com/exdb/mnist/) is four files and I don't know how to use them ? so any help on where to get their database or where or the files to use them ?
The files you're looking at are the correct files. They are normalized grey-scale images (0-white, 255-black) centered in a 20x20 box. The page explains the structure of the files (just scroll down towards the bottom).
Here's some code I wrote a while back in Java, that reads in the MNIST image and label files:
import net.vivin.digit.DigitImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: vivin
* Date: 11/11/11
* Time: 10:07 AM
*/
public class DigitImageLoadingService {
private String labelFileName;
private String imageFileName;
/** the following constants are defined as per the values described at http://yann.lecun.com/exdb/mnist/ **/
private static final int MAGIC_OFFSET = 0;
private static final int OFFSET_SIZE = 4; //in bytes
private static final int LABEL_MAGIC = 2049;
private static final int IMAGE_MAGIC = 2051;
private static final int NUMBER_ITEMS_OFFSET = 4;
private static final int ITEMS_SIZE = 4;
private static final int NUMBER_OF_ROWS_OFFSET = 8;
private static final int ROWS_SIZE = 4;
public static final int ROWS = 28;
private static final int NUMBER_OF_COLUMNS_OFFSET = 12;
private static final int COLUMNS_SIZE = 4;
public static final int COLUMNS = 28;
private static final int IMAGE_OFFSET = 16;
private static final int IMAGE_SIZE = ROWS * COLUMNS;
public DigitImageLoadingService(String labelFileName, String imageFileName) {
this.labelFileName = labelFileName;
this.imageFileName = imageFileName;
}
public List<DigitImage> loadDigitImages() throws IOException {
List<DigitImage> images = new ArrayList<DigitImage>();
ByteArrayOutputStream labelBuffer = new ByteArrayOutputStream();
ByteArrayOutputStream imageBuffer = new ByteArrayOutputStream();
InputStream labelInputStream = this.getClass().getResourceAsStream(labelFileName);
InputStream imageInputStream = this.getClass().getResourceAsStream(imageFileName);
int read;
byte[] buffer = new byte[16384];
while((read = labelInputStream.read(buffer, 0, buffer.length)) != -1) {
labelBuffer.write(buffer, 0, read);
}
labelBuffer.flush();
while((read = imageInputStream.read(buffer, 0, buffer.length)) != -1) {
imageBuffer.write(buffer, 0, read);
}
imageBuffer.flush();
byte[] labelBytes = labelBuffer.toByteArray();
byte[] imageBytes = imageBuffer.toByteArray();
byte[] labelMagic = Arrays.copyOfRange(labelBytes, 0, OFFSET_SIZE);
byte[] imageMagic = Arrays.copyOfRange(imageBytes, 0, OFFSET_SIZE);
if(ByteBuffer.wrap(labelMagic).getInt() != LABEL_MAGIC) {
throw new IOException("Bad magic number in label file!");
}
if(ByteBuffer.wrap(imageMagic).getInt() != IMAGE_MAGIC) {
throw new IOException("Bad magic number in image file!");
}
int numberOfLabels = ByteBuffer.wrap(Arrays.copyOfRange(labelBytes, NUMBER_ITEMS_OFFSET, NUMBER_ITEMS_OFFSET + ITEMS_SIZE)).getInt();
int numberOfImages = ByteBuffer.wrap(Arrays.copyOfRange(imageBytes, NUMBER_ITEMS_OFFSET, NUMBER_ITEMS_OFFSET + ITEMS_SIZE)).getInt();
if(numberOfImages != numberOfLabels) {
throw new IOException("The number of labels and images do not match!");
}
int numRows = ByteBuffer.wrap(Arrays.copyOfRange(imageBytes, NUMBER_OF_ROWS_OFFSET, NUMBER_OF_ROWS_OFFSET + ROWS_SIZE)).getInt();
int numCols = ByteBuffer.wrap(Arrays.copyOfRange(imageBytes, NUMBER_OF_COLUMNS_OFFSET, NUMBER_OF_COLUMNS_OFFSET + COLUMNS_SIZE)).getInt();
if(numRows != ROWS && numRows != COLUMNS) {
throw new IOException("Bad image. Rows and columns do not equal " + ROWS + "x" + COLUMNS);
}
for(int i = 0; i < numberOfLabels; i++) {
int label = labelBytes[OFFSET_SIZE + ITEMS_SIZE + i];
byte[] imageData = Arrays.copyOfRange(imageBytes, (i * IMAGE_SIZE) + IMAGE_OFFSET, (i * IMAGE_SIZE) + IMAGE_OFFSET + IMAGE_SIZE);
images.add(new DigitImage(label, imageData));
}
return images;
}
}
Related
\I want to make a socket application that will run on Linux and provide multiple messaging and file transfer. Can you share sample code? Can you help me i am a second year computer engineering student?
I found a similar code in my research, but I cannot connect to my linux server from different computers.I learned this code from github #HondaPL.
This is client codes
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using MessengerLogic;
using System.IO;
namespace Messenger
{
public class Connection
{
public static int BufferSize = 1024;
public static string nick;
public static IPAddress ip = IPAddress.Parse("-.-.-.-");
public static int port = 1234;
public static TcpClient client = new TcpClient();
public static List<string> users = new List<string>();
public static bool isEnd = false;
public static string[] fromServer = new string[30];
public void Connect(string nickname)
{
nick = nickname;
client.Connect(ip, port);
nickname += "$Welcome$";
byte[] buffer = Encoding.ASCII.GetBytes(nickname);
NetworkStream ns = client.GetStream();
Console.WriteLine(nickname);
ns.Write(buffer, 0, buffer.Length);
Thread thread = new Thread(o => ReceiveData((TcpClient)o));
thread.Start(client);
}
static void ReceiveData(TcpClient client)
{
NetworkStream ns = client.GetStream();
byte[] receivedBytes = new byte[1024];
int byte_count;
StringParser parser = new StringParser();
while ((byte_count = ns.Read(receivedBytes, 0, receivedBytes.Length)) > 0)
{
fromServer = new string[30];
users.Clear();
string message = Encoding.ASCII.GetString(receivedBytes, 0, byte_count);
fromServer = parser.Parser(message);
if (fromServer[0] == "List")
{
for (int i = 1; i < fromServer.Length; i++)
{
users.Add(fromServer[i]);
}
isEnd = true;
}
else
{
Console.WriteLine(message);
Console.WriteLine(fromServer[0]);
Console.WriteLine(fromServer[1]);
FrmOnlineUsers.frm.AssignValues(fromServer[0], fromServer[1]);
FrmOnlineUsers.frm.MessageFromClient();
}
}
}
public List<string> Refresh()
{
NetworkStream ns = client.GetStream();
string temp = nick;
temp += "$List$";
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(temp);
ns.Write(buffer, 0, buffer.Length);
while (!isEnd)
{
}
isEnd = false;
return users;
}
public void SendMessage(string who, string msg)
{
NetworkStream ns = client.GetStream();
string temp = $"{who}$Message${msg}$";
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(temp);
ns.Write(buffer, 0, buffer.Length);
}
public void FileSend(string filepath, string nick, string fileName)
{
NetworkStream ns = client.GetStream();
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
byte[] bytesToSend = new byte[fs.Length];
int numBytesRead = fs.Read(bytesToSend, 0, bytesToSend.Length);
int totalBytes = 0;
//Tutaj trzeba dodać, aby pobierał nazwę pliku
string temp = $"{nick}$File${fileName}${fs.Length}";
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(temp);
ns.Write(buffer, 0, buffer.Length);
Thread.Sleep(1000);
for (int i = 0; i <= fs.Length / BufferSize; i++)
{
if (fs.Length - (i * BufferSize) > BufferSize)
{
ns.Write(bytesToSend, i * BufferSize,
BufferSize);
totalBytes += BufferSize;
}
else
{
ns.Write(bytesToSend, i * BufferSize,
(int)fs.Length - (i * BufferSize));
totalBytes += (int)fs.Length - (i * BufferSize);
}
}
fs.Close();
}
}
}
Is there a way using the Java API to access an edge index in OrientDB to determine whether a edge with a given label exists in between two known vertices?
Afaik tinkergraph is not exposing any methods for this?
I believe that Neo4j is providing an API like this:
graphDatabaseService.index().forRelationships("HAS_USER").get(key, valueOrNull, startNodeOrNull, endNodeOrNull)
You can call getEdges() from your vertex. Example:
v1.getEdges(v2, Direction.BOTH, "HAS_USER");
This is the JavaDoc:
/**
* (Blueprints Extension) Returns all the edges from the current Vertex to another one.
*
* #param iDestination
* The target vertex
* #param iDirection
* The direction between OUT, IN or BOTH
* #param iLabels
* Optional labels as Strings to consider
* #return
*/
public Iterable<Edge> getEdges(final OrientVertex iDestination, final Direction iDirection, final String... iLabels)
Another way is to use OrientGraph.getEdges()
It is important to create an index first via:
cmd.setText("create index edge.HAS_ITEM on E (out,in) unique");
g.command(cmd).execute();
or via pure Java:
OrientEdgeType e = g.getEdgeType("E");
e.createProperty("in", OType.LINK);
e.createProperty("out", OType.LINK);
e.createIndex("edge.has_item", OClass.INDEX_TYPE.UNIQUE_HASH_INDEX, "out", "in");
After this the index can be queried using:
Iterable<Edge> edges = g.getEdges("edge.has_item", new OCompositeKey(root.getId(), randomDocument.getId()));
Small pittfall: It is important to lowercase the index type when referencing it in the getEdges method. Otherwise orientdb will not be able to retrieve it.
A complete example which shows four ways of finding a specific edge in between two vertices is listed below.
In the example 14k vertices (items) are created which are connected to a single root node.
Creating {14000} items.
[graph.getEdges] Duration: 38
[graph.getEdges] Duration per lookup: 0.0095
[root.getEdges] Duration: 59439
[root.getEdges] Duration per lookup: 14.85975
[root.getEdges - iterating] Duration: 56710
[root.getEdges - iterating] Duration per lookup: 14.1775
[query] Duration: 817
[query] Duration per lookup: 0.20425
Example:
package de.jotschi.orientdb;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import com.orientechnologies.orient.core.index.OCompositeKey;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientEdgeType;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;
import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;
import com.tinkerpop.blueprints.impls.orient.OrientVertexType;
public class EdgeIndexPerformanceTest {
private static OrientGraphFactory factory = new OrientGraphFactory("memory:tinkerpop");
private final static int nDocuments = 14000;
private final static int nChecks = 4000;
private static List<OrientVertex> items;
private static OrientVertex root;
#BeforeClass
public static void setupDatabase() {
setupTypesAndIndices(factory);
root = createRoot(factory);
items = createData(root, factory, nDocuments);
}
private static void setupTypesAndIndices(OrientGraphFactory factory2) {
OrientGraphNoTx g = factory.getNoTx();
try {
OCommandSQL cmd = new OCommandSQL();
cmd.setText("alter database custom useLightweightEdges=false");
g.command(cmd).execute();
cmd.setText("alter database custom useVertexFieldsForEdgeLabels=false");
g.command(cmd).execute();
OrientEdgeType e = g.getEdgeType("E");
e.createProperty("in", OType.LINK);
e.createProperty("out", OType.LINK);
OrientVertexType v = g.createVertexType("root", "V");
v.createProperty("name", OType.STRING);
v = g.createVertexType("item", "V");
v.createProperty("name", OType.STRING);
cmd.setText("create index edge.HAS_ITEM on E (out,in) unique");
g.command(cmd).execute();
} finally {
g.shutdown();
}
}
private static List<OrientVertex> createData(OrientVertex root, OrientGraphFactory factory, int count) {
OrientGraphNoTx g = factory.getNoTx();
try {
System.out.println("Creating {" + count + "} items.");
List<OrientVertex> items = new ArrayList<>();
for (int i = 0; i < count; i++) {
OrientVertex item = g.addVertex("class:item");
item.setProperty("name", "item_" + i);
items.add(item);
root.addEdge("HAS_ITEM", item, "class:E");
}
return items;
} finally {
g.shutdown();
}
}
private static OrientVertex createRoot(OrientGraphFactory factory) {
OrientGraphNoTx g = factory.getNoTx();
try {
OrientVertex root = g.addVertex("class:root");
root.setProperty("name", "root vertex");
return root;
} finally {
g.shutdown();
}
}
#Test
public void testEdgeIndexViaRootGetEdgesWithoutTarget() throws Exception {
OrientGraphNoTx g = factory.getNoTx();
try {
long start = System.currentTimeMillis();
for (int i = 0; i < nChecks; i++) {
OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
Iterable<Edge> edges = root.getEdges(Direction.OUT, "HAS_ITEM");
boolean found = false;
for (Edge edge : edges) {
if (edge.getVertex(Direction.IN).equals(randomDocument)) {
found = true;
break;
}
}
assertTrue(found);
}
long dur = System.currentTimeMillis() - start;
System.out.println("[root.getEdges - iterating] Duration: " + dur);
System.out.println("[root.getEdges - iterating] Duration per lookup: " + ((double) dur / (double) nChecks));
} finally {
g.shutdown();
}
}
#Test
public void testEdgeIndexViaRootGetEdges() throws Exception {
OrientGraphNoTx g = factory.getNoTx();
try {
long start = System.currentTimeMillis();
for (int i = 0; i < nChecks; i++) {
OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
Iterable<Edge> edges = root.getEdges(randomDocument, Direction.OUT, "HAS_ITEM");
assertTrue(edges.iterator().hasNext());
}
long dur = System.currentTimeMillis() - start;
System.out.println("[root.getEdges] Duration: " + dur);
System.out.println("[root.getEdges] Duration per lookup: " + ((double) dur / (double) nChecks));
} finally {
g.shutdown();
}
}
#Test
public void testEdgeIndexViaGraphGetEdges() throws Exception {
OrientGraphNoTx g = factory.getNoTx();
try {
long start = System.currentTimeMillis();
for (int i = 0; i < nChecks; i++) {
OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
Iterable<Edge> edges = g.getEdges("edge.has_item", new OCompositeKey(root.getId(), randomDocument.getId()));
assertTrue(edges.iterator().hasNext());
}
long dur = System.currentTimeMillis() - start;
System.out.println("[graph.getEdges] Duration: " + dur);
System.out.println("[graph.getEdges] Duration per lookup: " + ((double) dur / (double) nChecks));
} finally {
g.shutdown();
}
}
#Test
public void testEdgeIndexViaQuery() throws Exception {
OrientGraphNoTx g = factory.getNoTx();
try {
System.out.println("Checking edge");
long start = System.currentTimeMillis();
for (int i = 0; i < nChecks; i++) {
OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
OCommandSQL cmd = new OCommandSQL("select from index:edge.has_item where key=?");
OCompositeKey key = new OCompositeKey(root.getId(), randomDocument.getId());
assertTrue(((Iterable<Vertex>) g.command(cmd).execute(key)).iterator().hasNext());
}
long dur = System.currentTimeMillis() - start;
System.out.println("[query] Duration: " + dur);
System.out.println("[query] Duration per lookup: " + ((double) dur / (double) nChecks));
} finally {
g.shutdown();
}
}
}
I have a problem again with the JavaFX Chart : D
Context :
I had Popup/Label on my chart to display the value on hover : JavaFX LineChart Hover Values (Jewelsea answer)
Problem :
But when the point are near the edges of chart, the popup is hidden by them.
The chart with problem, I highlighted the edges of chart.
This is a problem, because my popup is bigger and display more informations (x value, y value and the data serie)
Possible solutions :
May I can check where the edges are, and if the popup is hide. In this case, I should shift the popup. But when I look doc, I didn't found the right method :
XYChart
XYChart.Data#nodeProperty
May I can put the popup above the chart. Like z-index in CSS.
The code :
import javafx.application.Application;
import javafx.collections.*;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.chart.*;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Displays a LineChart which displays the value of a plotted Node when you hover over the Node.
* #author original, jewelsea https://gist.github.com/jewelsea
*/
public class LineChartWithHover extends Application {
#SuppressWarnings("unchecked")
#Override public void start(Stage stage) {
final LineChart lineChart = new LineChart(
new NumberAxis(), new NumberAxis(),
FXCollections.observableArrayList(
new XYChart.Series(
"My portfolio",
FXCollections.observableArrayList(
plot(0, 14, 15, 24, 34, 36, 22, 55, 43, 17, 29, 25)
)
)
)
);
lineChart.setCursor(Cursor.CROSSHAIR);
lineChart.setTitle("Stock Monitoring, 2013");
stage.setScene(new Scene(lineChart, 500, 400));
stage.show();
System.out.println("test 1 = "+lineChart.getProperties());
}
/** #return plotted y values for monotonically increasing integer x values, starting from x=1 */
public ObservableList<XYChart.Data<Integer, Integer>> plot(int... y) {
final ObservableList<XYChart.Data<Integer, Integer>> dataset = FXCollections.observableArrayList();
int i = 0;
while (i < y.length) {
final XYChart.Data<Integer, Integer> data = new XYChart.Data<>(i + 1, y[i]);
data.setNode(
new HoveredThresholdNode(
(i == 0) ? 0 : y[i-1],
y[i]
)
);
dataset.add(data);
i++;
}
return dataset;
}
/** a node which displays a value on hover, but is otherwise empty */
class HoveredThresholdNode extends StackPane {
HoveredThresholdNode(int priorValue, int value) {
setPrefSize(15, 15);
final Label label = createDataThresholdLabel(priorValue, value);
setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
getChildren().setAll(label);
setCursor(Cursor.NONE);
toFront();
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
getChildren().clear();
setCursor(Cursor.CROSSHAIR);
}
});
}
private Label createDataThresholdLabel(int priorValue, int value) {
final Label label = new Label(value + "");
label.getStyleClass().addAll("default-color0", "chart-line-symbol", "chart-series-line");
label.setStyle("-fx-font-size: 20; -fx-font-weight: bold;");
if (priorValue == 0) {
label.setTextFill(Color.DARKGRAY);
} else if (value > priorValue) {
label.setTextFill(Color.FORESTGREEN);
} else {
label.setTextFill(Color.FIREBRICK);
}
label.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
return label;
}
}
public static void main(String[] args) { launch(args); }
}
Thank you in advance ! And my apologies about my english, still learning !
I have been looking on the JavaFX CSS reference guide and I could'nt find anything to simply solve your problem.
A possible solution is to translate your symbol depending on how near it is to the max or min value.
I wrote something like this, based on your code :
/**
* Displays a LineChart which displays the value of a plotted Node when you hover over the Node.
* #author original, jewelsea https://gist.github.com/jewelsea
*/
public class LineChartWithHover extends Application {
#SuppressWarnings("unchecked")
#Override public void start(Stage stage) {
final LineChart lineChart = new LineChart(
new NumberAxis(), new NumberAxis(),
FXCollections.observableArrayList(
new XYChart.Series(
"My portfolio",
FXCollections.observableArrayList(
plot(0, 14, 15, 24, 34, 36, 22, 55, 43, 17, 29, 25)
)
)
)
);
lineChart.setCursor(Cursor.CROSSHAIR);
lineChart.setTitle("Stock Monitoring, 2013");
stage.setScene(new Scene(lineChart, 500, 400));
stage.show();
System.out.println("test 1 = "+lineChart.getProperties());
}
/** #return plotted y values for monotonically increasing integer x values, starting from x=1 */
public ObservableList<XYChart.Data<Integer, Integer>> plot(Integer... y) {
final ObservableList<XYChart.Data<Integer, Integer>> dataset = FXCollections.observableArrayList();
int i = 0;
List<Integer> list = Arrays.asList(y);
int min = Collections.min(list);
int max = Collections.max(list);
int minThreshold = 5;
int maxThreshold = 5;
while (i < y.length) {
final XYChart.Data<Integer, Integer> data = new XYChart.Data<>(i + 1, y[i]);
int topMargin = 0;
if(y[i] <= min + minThreshold) {
topMargin = -50;
} else if (y[i] >= max - maxThreshold) {
topMargin = 50;
}
StackPane stackPane = new HoveredThresholdNode(
(i == 0) ? 0 : y[i-1],
y[i],
topMargin
);
data.setNode(stackPane);
dataset.add(data);
i++;
}
return dataset;
}
/** a node which displays a value on hover, but is otherwise empty */
class HoveredThresholdNode extends StackPane {
HoveredThresholdNode(int priorValue, int value, int topMargin) {
setPrefSize(15, 15);
final Label label = createDataThresholdLabel(priorValue, value);
setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
getChildren().setAll(label);
setCursor(Cursor.NONE);
toFront();
setMargin(label, new Insets(topMargin,0,0,0));
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
getChildren().clear();
setCursor(Cursor.CROSSHAIR);
}
});
}
private Label createDataThresholdLabel(int priorValue, int value) {
final Label label = new Label(value + "");
label.getStyleClass().addAll("default-color0", "chart-line-symbol", "chart-series-line");
label.setStyle("-fx-font-size: 20; -fx-font-weight: bold;");
if (priorValue == 0) {
label.setTextFill(Color.DARKGRAY);
} else if (value > priorValue) {
label.setTextFill(Color.FORESTGREEN);
} else {
label.setTextFill(Color.FIREBRICK);
}
label.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
return label;
}
}
public static void main(String[] args) { launch(args); }
}
Basically, I am just saying that all values <= min+5 and >= max-5 must be translated.
The +/- 5 is arbitrary and should be calculated from the ticks gap and plot scale to have a perfect repositioning. Anyway, without performing any maths, it is still quite satisfying.
Based on Mr Kwoinkwoin solution, I wrote my own.
Im not sure if its possible to optimize it or improve it. But seems to be working for me so far.
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.NumberAxis.DefaultFormatter;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import static javafx.scene.layout.StackPane.setMargin;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class StockLineChartApp extends Application {
private LineChart<Number, Number> chart;
private Series<Number, Number> series;
private NumberAxis xAxis;
private ZonedDateTime time;
public StockLineChartApp() {
time = ZonedDateTime.of(LocalDateTime.of(LocalDate.of(2000, Month.JANUARY, 1), LocalTime.NOON), ZoneId.systemDefault());
}
public Parent createContent() {
xAxis = new NumberAxis();
xAxis.setLabel("Date/Time");
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(true);
xAxis.setTickLabelFormatter(new StringConverter<Number>() {
#Override
public String toString(Number t) {
long longValue = t.longValue();
ZonedDateTime zd = convertLongToZonedDateTime(longValue);
String formatDate = formatDate(zd, "dd/MM/yyyy");
return formatDate;
}
#Override
public Number fromString(String string) {
ZonedDateTime dl = ZonedDateTime.parse(string, DateTimeFormatter.ofPattern("dd/MM/yyyy"));
long toEpochMilli = dl.toEpochSecond();
//DateTimeFormatter.ofPattern(string).p
return toEpochMilli;
}
});
final NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
chart = new LineChart<>(xAxis, yAxis);
chart.setCursor(Cursor.CROSSHAIR);
chart.setAlternativeRowFillVisible(true);
chart.setAlternativeColumnFillVisible(true);
// setup chart
//final String stockLineChartCss= getClass().getResource("StockLineChart.css").toExternalForm();
//chart.getStylesheets().add(stockLineChartCss);
chart.setCreateSymbols(true);
chart.setAnimated(true);
chart.setLegendVisible(true);
chart.setTitle("ACME Company Stock");
yAxis.setLabel("Share Price");
yAxis.setTickLabelFormatter(new DefaultFormatter(yAxis, "$", null));
// add starting data
series = new Series<>();
series.setName("Data por Peça");
for (double m = 0; m < (10); m++) {
long data = nextTime();
addData(data, (long) (Math.random() * 10));
System.out.println(data);
}
//chart.
chart.getData().add(series);
//chart.getData().add(hourDataSeries);
return chart;
}
private void addData(long x, long y) {
Data<Number, Number> data = new Data<Number, Number>(x, y);
series.getData().add(data);
ZonedDateTime zd = convertLongToZonedDateTime(x);
String formatDate = formatDate(zd, "dd/MM/yyyy");
//String text = "(" + formatDate + ";" + y + ")";
String text = y + "";
if (text.length() > 4) {
text = text.substring(0, 4);
}
String t = formatDate + "\nValor: " + text;
data.setNode(new HoveredThresholdNode(t, data));
}
public static long convertZonedDateTimeToLong(ZonedDateTime zonedDateTime) {
long e = zonedDateTime.toInstant().toEpochMilli();
return e;
}
private long nextTime() {
time = time.plusYears(10);
return convertZonedDateTimeToLong(time);
}
#Override
public void start(Stage primaryStage) throws Exception {
Parent createContent = createContent();
//
final StackPane pane = new StackPane();
pane.getChildren().add(createContent);
final Scene scene = new Scene(pane, 500, 400);
//new ZoomManager(pane, chart, series);
//
primaryStage.setScene(scene);
primaryStage.show();
}
public static String formatDate(ZonedDateTime ts, String format) {
try {
if (ts == null) {
return "";
}
String format1 = ts.format(DateTimeFormatter.ofPattern(format));
return format1;
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}
public static ZonedDateTime convertLongToZonedDateTime(long e) {
Instant i = Instant.ofEpochMilli(e);
ZonedDateTime ofInstant = ZonedDateTime.ofInstant(i, ZoneId.systemDefault());
return ofInstant;
}
/**
* Java main for when running without JavaFX launcher
*/
public static void main(String[] args) {
launch(args);
}
public class HoveredThresholdNode extends StackPane {
//Reference
private Data<Number, Number> data;
private Label label;
private String value;
public HoveredThresholdNode(String value, Data<Number, Number> data) {
this.data = data;
this.value = value;
this.label = new Label(value);
this.label.getStyleClass().clear();
this.getStyleClass().clear();
this.label.setStyle("-fx-font-size: 12; fx-text-fill: black;");
this.label.getStyleClass().addAll("default-color0", "chart-line-symbol", "chart-series-line");
this.label.setWrapText(true);
this.label.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
getChildren().setAll(label);
toFront();
boolean close_top = false, close_right = false, close_bottom = false, close_left = false;
long min_x = Long.MAX_VALUE;
long max_x = Long.MIN_VALUE;
long min_y = Long.MAX_VALUE;
long max_y = Long.MIN_VALUE;
ObservableList<Series<Number, Number>> chartSeries = chart.getData();
for (Series<Number, Number> s : chartSeries) {
ObservableList<Data<Number, Number>> chartData = s.getData();
for (Data<Number, Number> d : chartData) {
Number xValue = d.getXValue();
Number yValue = d.getYValue();
long kx = xValue.longValue();
long ky = yValue.longValue();
if (kx < min_x) {
min_x = kx;
}
if (kx > max_x) {
max_x = kx;
}
if (ky < min_y) {
min_y = ky;
}
if (ky > max_y) {
max_y = ky;
}
}
}
if (data.getXValue().longValue() - max_x == 0) {
close_right = true;
}
if (data.getXValue().longValue() - min_x == 0) {
close_left = true;
}
if (data.getYValue().longValue() - min_y == 0) {
close_bottom = true;
}
if (data.getYValue().longValue() - max_y == 0) {
close_top = true;
}
// System.out.println("\n");
// System.out.println(" close_right " + close_right);
// System.out.println(" close_left " + close_left);
// System.out.println(" close_bottom " + close_bottom);
// System.out.println(" close_top " + close_top);
double top = 0;
double right = 0;
double bottom = 0;
double left = 0;
if (close_top) {
top = 50;
}
if (close_bottom) {
bottom = 50;
}
if (close_right) {
right = 50;
}
if (close_left) {
left = 50;
}
setMargin(label, new Insets(top, right, bottom, left));
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
getChildren().clear();
}
});
}
public HoveredThresholdNode copy() {
HoveredThresholdNode copy = new HoveredThresholdNode(value, data);
return copy;
}
}
}
I need to encode and decode BER data. .NET has the class System.DirectoryServices.Protocols.BerConverter
The static method requires me to enter a string in the first parameter as shown below
byte[] oid = { 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 }; // Object ID for RSA
var result2 = System.DirectoryServices.Protocols.BerConverter.Decoding("?what goes here?", oid);
BER encoding is used in LDAP, Certificates, and is commonplace in many other formats.
I'll be happy with information telling me how to Encode or Decode on this class. There is nothing on Stack Overflow or the first few pages of Google (or Bing) regarding this.
Question
How do I convert the byte array above to the corresponding OID using BER decoding?
How can I parse (or attempt to parse) SubjectPublicKeyInfo ASN.1 data in DER or BER format?
It seems the DER encoding\decoding classes are internal to the .NET framework. If so, where are they? (I'd like to ask connect.microsoft.com to make these members public)
How do I convert the byte array above to the corresponding OID using BER decoding?
After you have extracted the OID byte array, you can convert it to an OID string using OidByteArrayToString(). I have included the code below, since I couldn't find a similar function in the .NET libraries.
How can I parse (or attempt to parse) SubjectPublicKeyInfo ASN.1 data in DER or BER format?
I was not able to find a TLV parser in the .NET SDK either. Below is an implementation of a BER TLV parser, BerTlv. Since DER is a subset of BER, parsing will work the same way. Given a BER-TLV byte[] array, it will return a list of BerTlv objects that support access of sub TLVs.
It seems the DER encoding\decoding classes are internal to the .NET framework. If so, where are they? (I'd like to ask connect.microsoft.com to make these members public)
Maybe somebody else can answer this question.
Summary
Here is an example of how you can use the code provided below. I have used the public key data you provided in your previous post. The BerTlv should probably be augmented to support querying like BerTlv.getValue(rootTlvs, '/30/30/06');.
public static void Main(string[] args)
{
string pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB";
byte[] pubkeyByteArray = Convert.FromBase64String(pubkey);
List<BerTlv> rootTlvs = BerTlv.parseTlv(pubkeyByteArray);
BerTlv firstTlv = rootTlvs.Where(tlv => tlv.Tag == 0x30).First();//first sequence (tag 30)
BerTlv secondTlv = firstTlv.SubTlv.Where(tlv => tlv.Tag == 0x30).First();//second sequence (tag 30)
BerTlv oid = secondTlv.SubTlv.Where(tlv => tlv.Tag == 0x06).First();//OID tag (tag 30)
string strOid = OidByteArrayToString(oid.Value);
Console.WriteLine(strOid);
}
Output:
1.2.840.113549.1.1.1
OID Encode/Decode
public static byte[] OidStringToByteArray(string oid)
{
string[] split = oid.Split('.');
List<byte> retVal = new List<byte>();
//root arc
if (split.Length > 0)
retVal.Add((byte)(Convert.ToInt32(split[0])*40));
//first arc
if (split.Length > 1)
retVal[0] += Convert.ToByte(split[1]);
//subsequent arcs
for (int i = 2; i < split.Length; i++)
{
int arc_value = Convert.ToInt32(split[i]);
Stack<byte> bytes = new Stack<byte>();
while (arc_value != 0)
{
byte val = (byte) ((arc_value & 0x7F) | (bytes.Count == 0 ? 0x0:0x80));
arc_value >>= 7;
bytes.Push(val);
}
retVal.AddRange(bytes);
}
return retVal.ToArray();
}
public static string OidByteArrayToString(byte[] oid)
{
StringBuilder retVal = new StringBuilder();
//first byte
if (oid.Length > 0)
retVal.Append(String.Format("{0}.{1}", oid[0] / 40, oid[0] % 40));
// subsequent bytes
int current_arc = 0;
for (int i = 1; i < oid.Length; i++)
{
current_arc = (current_arc <<= 7) | oid[i] & 0x7F;
//check if last byte of arc value
if ((oid[i] & 0x80) == 0)
{
retVal.Append('.');
retVal.Append(Convert.ToString(current_arc));
current_arc = 0;
}
}
return retVal.ToString();
}
BER-TLV Parser
class BerTlv
{
private int tag;
private int length;
private int valueOffset;
private byte[] rawData;
private List<BerTlv> subTlv;
private BerTlv(int tag, int length, int valueOffset, byte[] rawData)
{
this.tag = tag;
this.length = length;
this.valueOffset = valueOffset;
this.rawData = rawData;
this.subTlv = new List<BerTlv>();
}
public int Tag
{
get { return tag; }
}
public byte[] RawData
{
get { return rawData; }
}
public byte[] Value
{
get
{
byte[] result = new byte[length];
Array.Copy(rawData, valueOffset, result, 0, length);
return result;
}
}
public List<BerTlv> SubTlv
{
get { return subTlv; }
}
public static List<BerTlv> parseTlv(byte[] rawTlv)
{
List<BerTlv> result = new List<BerTlv>();
parseTlv(rawTlv, result);
return result;
}
private static void parseTlv(byte[] rawTlv, List<BerTlv> result)
{
for (int i = 0, start=0; i < rawTlv.Length; start=i)
{
//parse Tag
bool constructed_tlv = (rawTlv[i] & 0x20) != 0;
bool more_bytes = (rawTlv[i] & 0x1F) == 0x1F;
while (more_bytes && (rawTlv[++i] & 0x80) != 0) ;
i++;
int tag = Util.getInt(rawTlv, start, i-start);
//parse Length
bool multiByte_Length = (rawTlv[i] & 0x80) != 0;
int length = multiByte_Length ? Util.getInt(rawTlv, i+1, rawTlv[i] & 0x1F) : rawTlv[i];
i = multiByte_Length ? i + (rawTlv[i] & 0x1F) + 1: i + 1;
i += length;
byte[] rawData = new byte[i - start];
Array.Copy(rawTlv, start, rawData, 0, i - start);
BerTlv tlv = new BerTlv(tag, length, i - length, rawData);
result.Add(tlv);
if (constructed_tlv)
parseTlv(tlv.Value, tlv.subTlv);
}
}
}
Here is a utility class that contains some functions used in the class above. It is included for the sake of clarity how it works.
class Util
{
public static string getHexString(byte[] arr)
{
StringBuilder sb = new StringBuilder(arr.Length * 2);
foreach (byte b in arr)
{
sb.AppendFormat("{0:X2}", b);
}
return sb.ToString();
}
public static byte[] getBytes(String str)
{
byte[] result = new byte[str.Length >> 1];
for (int i = 0; i < result.Length; i++)
{
result[i] = (byte)Convert.ToInt32(str.Substring(i * 2, 2), 16);
}
return result;
}
public static int getInt(byte[] data, int offset, int length)
{
int result = 0;
for (int i = 0; i < length; i++)
{
result = (result << 8) | data[offset + i];
}
return result;
}
}
Ok. so I'm writing a grocery checkout system code and on the right side of the frame, I'm displaying a Jpanel with Labels. Every time I click the 'Scan' button, I add a new label into the JPanel so that everytime I click, it displays the output. However, I can only fit so many entries in my window, how do I incorporate a scroll bar so that I can scroll through the groceries?
I tried inputting a scroll bar EAST with a BorderLayout and all the labels CENTER, however, everytime I click the button, it only reprints it at the same exact spot instead of top/down so that I can scroll. (Please, bare in mind that this is a very very rough draft. I'll be incorporating the logic beneath the code once I get the nitty-gritty with the GUI)
Here's my code:
public class Checkout extends JFrame implements ActionListener
{
private int numOfItems = 21;
private Integer[] itemCode = new Integer[numOfItems];
private StringBuffer[] itemDesc = new StringBuffer[numOfItems];
private Double[] unitPrice = new Double[numOfItems];
private Integer[] taxCode = new Integer[numOfItems];
private Integer[] quantity = new Integer[numOfItems];
private Integer[] reorderLevel = new Integer[numOfItems];
private double subTotal, tax, grandTotal;
private JButton scan = new JButton("Scan");
private JButton pay = new JButton("Finish & Pay");
private JButton readFile = new JButton("Read from File");
private JTextField itemNumber = new JTextField(4);
private JTextField itemQuantity = new JTextField(4);
private JLabel displayReceipt = new JLabel();
private JPanel p4;
public Checkout()
{
setValues();
JPanel p2 = new JPanel(new FlowLayout());
p2.add(scan);
p2.add(pay);
p2.add(readFile);
JPanel p1 = new JPanel(new FlowLayout());
p1.add(new JLabel("Item Number:"));
p1.add(itemNumber);
p1.add(new JLabel("Item Quantity:"));
p1.add(itemQuantity);
p1.setBorder(new TitledBorder("Scan Items First. Then Hit 'Finish and Pay'"));
JPanel p3 = new JPanel(new BorderLayout(5, 5));
p3.add(p1, BorderLayout.NORTH);
p3.add(p2, BorderLayout.CENTER);
p4 = new JPanel(new GridLayout(0, 1, 0, 0));
JScrollPane scroll = new JScrollPane(p4);
add(p3, BorderLayout.WEST);
add(p4, BorderLayout.CENTER);
scan.addActionListener(this);
pay.addActionListener(this);
readFile.addActionListener(this);
}
public void setValues()
{
String[] tokens = new String[6];
String[][] multi = new String[numOfItems][6];
try{BufferedReader textReader = new BufferedReader(new FileReader("inventory.txt"));
for(int i = 0; i < numOfItems; i++) // Split the file
{
tokens = textReader.readLine().split("\t");
for(int j = 0; j < tokens.length; j++)
{
multi[i][j] = tokens[j];
}
}
for(int i = 0; i < numOfItems; i++)
{
itemCode[i] = (Integer.parseInt(multi[i][0]));
itemDesc[i] = new StringBuffer(multi[i][1]);
unitPrice[i] = (Double.parseDouble(multi[i][2]));
taxCode[i] = (Integer.parseInt(multi[i][3]));
quantity[i] = (Integer.parseInt(multi[i][4]));
reorderLevel[i] = (Integer.parseInt(multi[i][5]));
}}
catch(Exception e){}
}
public void setQuantity(int item, int itemCount)
{
for(int i = 0; i < numOfItems; i++)
{
if(itemCode[i].equals(item))
{
quantity[i] = quantity[i] - itemCount;
subTotal = itemCount * unitPrice[i];
if(quantity[i] < reorderLevel[i])
itemDesc[i] = itemDesc[i].append("**MARKED FOR REORDER**\t");
}
}
}
public String toString()
{
System.out.println("CUST TICKET");
//for(int i = 0; i < numOfItems; i++)
//return (itemCode[i] + "\t" + itemDesc[i] + "\t" + unitPrice[i] + "\t" + taxCode[i] + "\t" + quantity[i] + "\t" + reorderLevel[i]);
System.out.println("SUBTOTAL\t" + subTotal);
System.out.println("TAX\t\t" + tax);
System.out.println("GRAND TOTAL\t" + grandTotal);
return "";
}
public static void main(String[] args) throws Exception
{
Checkout frame = new Checkout(); // Frame layout
frame.setSize(600, 135);
frame.setTitle("Computer Science 202: Final Project - Supermarket Checkout System");
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
/*Scanner input = new Scanner(System.in);
System.out.print("Please enter item number: ");
Integer itemNumber = Integer.parseInt(input.nextLine());
System.out.print("Please enter quantity: ");
Integer quantity = Integer.parseInt(input.nextLine());
System.out.println(frame.stockCheck(itemNumber, quantity));*/
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == scan)
{
try
{
Integer quantityOrdered = 1;
Integer item = Integer.parseInt(itemNumber.getText());
quantityOrdered = Integer.parseInt(itemQuantity.getText());
for(int i = 0; i < numOfItems; i++)
{
if(itemCode[i].equals(item))
{
if(quantityOrdered > 1)
{
p4.add(new JLabel(itemDesc[i] + "" + unitPrice[i]));
p4.add(new JLabel(quantityOrdered + " # " + unitPrice[i]));
p4.revalidate();
p4.repaint();
}
else
{
p4.add(new JLabel(itemDesc[i] + "\t" + unitPrice[i]));
p4.revalidate();
p4.repaint();
}
}
}
setQuantity(item, quantityOrdered);
}
catch(Exception ex){}
}
else if(e.getSource() == pay)
{
displayReceipt.setText(toString());
}
else if(e.getSource() == readFile)
{
System.out.println("READ FILE");
}
}
}