I'm getting a list of data from Binance that returns a response, how do I access the values of the response body?
private Closeable candleStick(){
BinanceApiWebSocketClient client = BinanceApiClientFactory.newInstance().newWebSocketClient();
return client.onCandlestickEvent("btcusdt", CandlestickInterval.FIVE_MINUTES, new BinanceApiCallback<com.binance.api.client.domain.event.CandlestickEvent>() {
#Override
public void onResponse(com.binance.api.client.domain.event.CandlestickEvent response) {
System.out.println(response);
}
});
}
The response has values like response.getHigh(), response.getLow(), etc. How do I access these values in another method. It
private String show() throws IOException {
Double high = candleStick().getHigh() //didn't work as the method returns a closeable object.
}
It's a callback based API, so instead of your System.out.println(...) you should update some data structure in your app to add/show the new values.
Just a simple example:
public class CandleStickDataSource {
private final BinanceApiWebSocketClient client;
private final Closeable socket;
private final List<Double> highs = new ArrayList<>();
private final List<Double> lows = new ArrayList<>();
private Double lastHigh;
private Double lastLow;
public CandleStickDataSource(String ticker, CandlestickInterval interval) {
this.client = BinanceApiClientFactory.newInstance().newWebSocketClient();
this.socket = client.onCandlestickEvent(ticker, interval, new BinanceApiCallback<CandlestickEvent>() {
#Override
public void onResponse(CandlestickEvent response) {
lastHigh = Double.valueOf(response.getHigh());
lastLow = Double.valueOf(response.getLow());
highs.add(lastHigh);
lows.add(lastLow);
}
}); // don't forget to call close() on this somewhere when you're done with this class
}
public List<Double> getHighs() { return highs; }
public List<Double> getLows() { return lows; }
public Double getLastHigh() { return lastHigh; }
public Double getLastLow() { return lastLow; }
}
So somewhere else in your app where you want to get access to the data:
CandleStickDataSource data = new CandleStickDataSource("btcusdt", CandlestickInterval.FIVE_MINUTES); // Create this first. This is now reusable for any ticker and any interval
and then whenever you want to see the data
data.getHighs(); // history
data.getLows();
data.getLastHigh(); // or getLastLow() for latest values
Related
Hi
In the game Minecraft you have to send data between the client and the server in order to sync stuff, one of the things that need to be synced in particular circumstances is TileEntities with a render. The data is stored on the server and sent to the client which is thereafter used for render.
You create a class that contains the data that needs to be synced and attach it to a channel creation API called "SimpleImpl". My Network object and a Message Object:
public class IntercraftPacketHandler
{
private static int index = 1;
private static final ResourceLocation CHANNEL_NAME = new ResourceLocation(Reference.MODID,"network");
private static final String PROTOCOL_VERSION = new ResourceLocation(Reference.MODID,"1").toString();
public static SimpleChannel getNetworkChannel()
{
final SimpleChannel channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME)
.clientAcceptedVersions(version -> true)
.serverAcceptedVersions(version -> true)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.simpleChannel();
// Sync Capability Identity Hidden data message.
channel.messageBuilder(MessageIdentityHidden.class,index)
.encoder(MessageIdentityHidden::encode)
.decoder(MessageIdentityHidden::decode)
.consumer(MessageIdentityHidden::handle)
.add(); index++;
// Send TreeTapTileEntity data to client.
channel.messageBuilder(MessageTreeTap.class,index)
.encoder(MessageTreeTap::encode)
.decoder(MessageTreeTap::decode)
.consumer(MessageTreeTap::handle)
.add(); index++;
// Send ChunkLoaderTileEntity data to client.
channel.messageBuilder(MessageChunkLoader.class,index)
.encoder(MessageChunkLoader::encode)
.decoder(MessageChunkLoader::decode)
.consumer(MessageChunkLoader::handle)
.add(); index++;
return channel;
}
}
public class MessageChunkLoader
{
private BlockPos pos;
private boolean canLoad;
public MessageChunkLoader(BlockPos pos,boolean canLoad)
{
this.pos = pos;
this.canLoad = canLoad;
}
public void handle(Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
try {
ChunkLoaderBaseTileEntity tile = (ChunkLoaderBaseTileEntity) Minecraft.getInstance().world.getTileEntity(pos);
tile.canLoad = canLoad;
} catch (NullPointerException err) {
System.out.println(String.format("Could not find ChunkLoaderTileEntity at %s %s %s!",pos.getX(),pos.getY(),pos.getZ()));
}
});
}
public static void encode(MessageChunkLoader message, PacketBuffer buffer)
{
buffer.writeBlockPos(message.pos);
buffer.writeBoolean(message.canLoad);
}
public static MessageChunkLoader decode(final PacketBuffer buffer)
{
return new MessageChunkLoader(buffer.readBlockPos(),buffer.readBoolean());
}
}
I then initialize it in my main mod class used by objects in my mod project.
#Mod(Reference.MODID)
public class IntercraftCore
{
public static final SimpleChannel NETWORK = IntercraftPacketHandler.getNetworkChannel();
...
The problem and this post's question; right now I create a new message class from the formula I follow in MessageChunkLoader (public static encode & decode method and a handle method). I would like to create a more generic class for creating message classes for TileEntities, but I'm having problems with that. Here's the current class:
public abstract class MessageTileEntity<T extends TileEntity>
{
protected final BlockPos pos;
protected final Class<T> clazz;
public MessageTileEntity(BlockPos pos, Class<T> clazz)
{
this.pos = pos;
this.clazz = clazz;
}
public abstract void handle(Supplier<NetworkEvent.Context> ctx);
protected T getTileEntity()
{
try {
return clazz.cast(Minecraft.getInstance().world.getTileEntity(pos));
} catch (NullPointerException e) {
System.out.println(String.format("Could not find %s at [%d %d %d]!",clazz.getSimpleName(),pos.getX(),pos.getY(),pos.getZ()));
throw e;
} catch (ClassCastException e) {
System.out.println(String.format("TileEntity at [%d %d %d] is not %s!",pos.getX(),pos.getY(),pos.getZ(),clazz.getSimpleName()));
throw e;
}
}
public static void encode(MessageTileEntity message, PacketBuffer buffer)
{
}
public static MessageTileEntity decode(final PacketBuffer buffer)
{
return null;
}
}
The main problem is I lack the proper Java skills to make it like I want it to function. The method handle is easy as it's non-static and needs to be custom to every TileEntity message, but the methods encode and decode which needs to be static gives me problems. I have no idea what I'm trying to achieve is possible, asking won't hurt. Maybe the solution is easier than I think.
I have created a class named "Global Services" which I use to save my data globally and access them in a different activity. But when I am calling the set() method, instead of overview the existing data instead it is appending that data. Below is my code.
I have even tried to remove the instance but still, it is appending the new data instead of overwriting.
import java.util.ArrayList;
import java.util.List;
public class GlobalServices {
private static GlobalServices instance;
String partner, leadsResponse;
List<Leads> assignedList = new ArrayList<>();
List<Leads> unAssignedList = new ArrayList<>();
List<Inventory> listInventory = new ArrayList<>();
private GlobalServices() {}
public static GlobalServices getInstance() {
if (instance == null) {
instance = new GlobalServices();
}
return instance;
}
public static void destory() {
instance = null;
}
public String getPartner() {
return partner;
}
public String getLeadsResponse() {
return leadsResponse;
}
public List<Leads> getAssignedList() {
return assignedList;
}
public List<Leads> getUnAssignedList() {
return unAssignedList;
}
public List<Inventory> getListInventory() {
return listInventory;
}
public void setPartner(String partner) {
this.partner = partner;
}
public void setLeadsResponse(String leadsResponse) {
this.leadsResponse = leadsResponse;
}
public void setAssignedList(List<Leads> assignedList) {
this.assignedList = assignedList;
}
public void setUnAssignedList(List<Leads> unAssignedList) {
this.unAssignedList = unAssignedList;
}
public void setListInventory(List<Inventory> listInventory) {
this.listInventory = listInventory;
}
}
The problem is that you're just assigning new references to your lists in GlobalServices but not creating new lists. This means as soon as you modify this reference from another place in your code, it will be reflected in the GlobalServices list as well. All you have to do is:
public void setAssignedList(List<Leads> assignedList) {
this.assignedList = new ArrayList<>(assignedList);
}
public void setUnAssignedList(List<Leads> unAssignedList) {
this.unAssignedList = new ArrayList<>(unAssignedList);
}
public void setListInventory(List<Inventory> listInventory) {
this.listInventory = new ArrayList<>(listInventory);
}
This way a new copy will be created in memory for each list and the data will be overwritten.
Sorry if I was wrong, but your code here is not a problem.
The problem might come from other part of your application.
The data you set might be the data that extend your current data.
Example you have
GlobalServices instance = GlobalServices.getInstance()
List<Inventory> listInventory1 = new ArrayList<>();
listInventory1.add(new Inventory());
instance.setListInventory(listInventory1); // now your inventory have one item
// In some where else in your project
List<Inventory> listInventory2 = instance.getListInventory(); // lisInventorys.size() equals 1
// Then you add more data to listInventory2 by mistake
listInventory2.add(new Inventory()); // listInventory2.size() equals 2
// Then you set back listInventory2 to your global service
instance.setListInventory(listInventory2); // now your inventory have two item
So, the data had been actually overwrite, it data just been extended by accident.
I have some code that:
1- Received some data through a REST call (POST);
2- Performed some logic according to that data;
3- Returned the result.
For the sake of this question let's pretend it was a simple calculator webapi that allowed its clients to perform additions and subtractions. It looked like this:
#Path("/calculator")
public class Calculator {
#POST
#Path("addition")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response add(String request){
//Getting A and B from request
...
//Calculating result
int res = a + b;
//Creating response payload
JSONObject res = new JSONObject.put("result",res);
return Response.status(Response.Status.OK).entity(res.toString()).build();
}
#POST
#Path("subtract")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response sub(String request){
//Getting A and B from request
...
//Calculating result
int res = a - b;
//Creating response payload
JSONObject res = new JSONObject.put("result",res);
return Response.status(Response.Status.OK).entity(res.toString()).build();
}
}
Everything was fine until i realized that i couldn't perform more that one calculation in parallel because all the requests accessed a unique resource that can only be used by one of them at a time.
So, for the sake of this example, let's pretend we have a single calculator and that all requests' computations must be performed by that same calculator processor.
In my mind i think i would need something like a "CalculatorProcessor" that received requests from all the calculator webapi clients that:
1- Receives request;
2- Queues request;
3- Dequeues request;
4- Performs calculation;
5- Returns result using callback.
This is something that is kinda trivial for me in native Java, but i don't have a single clue on how i should this in a Java Jersey's context.
For instance...
How can i get back to the Calculator.add() and Calculator.sub() methods so i can send the http request response?
Can someone please enlighten me please?
Here's my java implementation for such a component:
import java.util.concurrent.ConcurrentLinkedQueue;
//IMPLEMENTS SINGLETON PATTERN
public class Calculator {
private static Calculator instance = null;
private ConcurrentLinkedQueue<Request> queue = null;
private Runnable processor = null;
//PRIVATE CONSTRUCTOR
private Calculator() {
queue = new ConcurrentLinkedQueue<>();
}
//GET CALCULATOR INSTANCE
static public Calculator getInstance() {
if (instance == null) {
instance = new Calculator();
}
return instance;
}
//REQUEST COMPUTATION
public synchronized void requestComputation(CalculatorCallback c, SupportedOperations o, int a, int b) {
//Adds request to queue
queue.add(new Request(c, o, a, b));
//Checks if there's an active processor
if (processor == null) {
//Launches a new processor if there isn't
Runnable p = new CalculatorProcessor(queue);
new Thread(p).start();
}
}
//CALLBACK INTERFACE
public interface CalculatorCallback {
void computationReady(int result);
}
//SUPPORTED OPERATIONS ENUMERATION
protected enum SupportedOperations {
ADDITION, SUBTRACTION;
}
//CLASS THAT REPRESENTS A REQUEST
private class Request {
final SupportedOperations operation;
final CalculatorCallback callback;
final int a;
final int b;
public Request(CalculatorCallback c, SupportedOperations operation, int a, int b) {
this.callback = c;
this.operation = operation;
this.a = a;
this.b = b;
}
}
//CALCULATOR PROCESSOR THREAD
class CalculatorProcessor implements Runnable {
final private ConcurrentLinkedQueue<Calculator.Request> queue;
public CalculatorProcessor(ConcurrentLinkedQueue<Calculator.Request> queue) {
this.queue = queue;
}
#Override
public void run() {
Calculator.Request current;
int result;
while (!queue.isEmpty()) {
//Gets head
current = queue.poll();
if (current.operation == Calculator.SupportedOperations.ADDITION) {
result = current.a + current.b;
} else if (current.operation == Calculator.SupportedOperations.SUBTRACTION) {
result = current.a - current.b;
} else {
throw new UnsupportedOperationException();
}
//Calls back the requester
current.callback.computationReady(result);
}
}
}
}
Here's the CalculatorClient code:
public class CalculatorClient implements Calculator.CalculatorCallback {
public static void main(String[] args) {
CalculatorClient client = new CalculatorClient();
Random random = new Random();
int a, b;
for (int i = 0; i < 1000; i++) {
a = random.nextInt(Integer.MAX_VALUE/2);
b = random.nextInt(Integer.MAX_VALUE/2);
System.out.println("Requesting "+a+" + "+b+"...");
Calculator.getInstance().requestComputation(client, Calculator.SupportedOperations.ADDITION,a,b);
}
}
#Override
public void computationReady(int result) {
System.out.println("Result is: "+result);
}
}
If you are using Jersey 2, you can use its Asynchronous processing feature. You can just pass the AsyncResponse to the calculating task, and the task will just resume the response when it is finished with the processing.
#POST
public void add(#Suspended AysncResponse response, String body) {
Calculator.getInstance().requestComputation(
client,
Calculator.SupportedOperations.ADDITION,
a,b,
response);
// you don't need to return anything from the resource method
// calling `response.resume(someResponse)` (from inside the task)
// is enough. That is why this method just returns `void`
}
The good thing about using the async feature is that if the processing takes a long time, you wouldn't be blocking the server threads as you would be if you were to try using some block mechanism like a CountDownLatch or blocking queue, or something to that effect. The server threads are immediately returned to the server so that it can handle more requests.
I am trying to take data from one class, put it in a singleton, and then proceed to access that data in another class.
Here is my singleton:
public class DataTransferrer {
private static DataTransferrer instance = null;
private ArrayList<Transients> transientList;
private DataTransferrer(){
transientList = new ArrayList<>();
}
public static synchronized DataTransferrer getInstance(){
if(instance == null) {instance = new DataTransferrer();}
return instance;
}
public ArrayList<Transients> getTransients(){return this.transientList;}
public void setTransients(ArrayList<Transients> t){transientList = t;}
public void printAll(){
for(Transients t : transientList){
Log.d("DEBUG DA",t.getDa().toString());
}
}
}
Here is my method that adds data to an arrayList which is then set to the arrayList within the singleton to then be used elsewhere:
public class JSONParser {
// URL to get contacts JSON
private static String url = "http://pi.cs.oswego.edu/~lpatmore/getAllTransients.php";
ArrayList<Transients> transientList;
private Transients t;
public JSONParser(){
transientList = new ArrayList<>();
}
public void execute(){
new GetTransients().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetTransients extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.d(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
Log.d(TAG, "NOT NULL DEBUG");
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray transients = jsonObj.getJSONArray("result");
// looping through All Transients
for (int i = 0; i < transients.length(); i++) {
JSONObject c = transients.getJSONObject(i);
String author = c.getString("author");
String transientId = c.getString("transientId");
String dateAlerted = c.getString("dateAlerted");
String datePublished = c.getString("datePublished");
float right_asencsion = (float) c.getDouble("right_asencsion");
float declination = (float) c.getDouble("declination");
t = new Transients(author, transientId, dateAlerted, datePublished, right_asencsion, declination);
// adding trans to trans list
transientList.add(t);
}
DataTransferrer.getInstance().setTransients(transientList);
DataTransferrer.getInstance().printAll();
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}
} else {
Log.e(TAG, "Couldn't get json from server.");
}
return null;
}
}
}
And I try to access it in another class like:
for(int i = 0; i < DataTransferrer.getInstance().getTransients().size(); i++){
System.out.println("DEBUG ADDED TRANSIENT");
Float ra = DataTransferrer.getInstance().getTransients().get(i).getR();
Float dec = DataTransferrer.getInstance().getTransients().get(i).getD();
transients.add(new Transient("Transient", names[i], GeocentricCoordinates.getInstance(ra, dec)));
}
Whenever I debug it checking to see in the other class, I am trying to access the arraylist, but in the other class it's like there was never an array list added to getTransients() method.
I tested this exact setup in Eclipse and it works perfectly but not in Android Studio.
I tested this exact setup in Eclipse and it works perfectly but not in
Android Studio.
Basically, you have got multithreading issue i.e., your DataTransferrer class is NOT threadsafe which is causing the issue i.e., there is a race condition between multiple threads and your singleton instance is NOT actually singleton (multiple objects are being created for DataTransferrer class).
So when you calling setTransients() from one thread, it is actually storing the Transients in one instance of DataTransferrer and then when you are trying retrieve the Transients from a different thread it is using different instance (object) of DataTransferrer.
You can create threadsafe singleton instance for your DataTransferrer class as shown below:
public class DataTransferrer {
private static final DataTransferrer instance = new DataTransferrer();
private ArrayList<Transients> transientList = new ArrayList<>();
//private constructor, so instantiation NOT allowed
private DataTransferrer() {}
public static synchronized DataTransferrer getInstance(){
return instance;
}
public ArrayList<Transients> getTransients(){
return this.transientList;
}
public void setTransients(ArrayList<Transients> t){
transientList = t;
}
public void printAll(){
for(Transients t : transientList){
Log.d("DEBUG DA",t.getDa().toString());
}
}
}
Also, note that in the above code, the instance will be created eagerly during the startup (initializing) time and when you call setTransients and getTransients that same instance (singleton) will be used. Instead of eager creation, if you need to create the instance lazily, you can look here.
I'm trying to fill a jComboBox with objects. I have it working in one class, but in this class it's giving a NullPointerException but the code is almost the same. What am I missing here?
The code I'm using to fill the comboboxes:
I have translated every variable to English and removed some unnescessary stuff. I hope it's more clear for you guys now:
package unive.billing.boundary.clientmanager.frames;
import unive.billing.control.ClientsManager;
import unive.billing.control.InsuranceManager;
/**
*
* #author Forza
*/
public class ClientFrame extends javax.swing.JFrame {
/**
* Creates new form AddClientGUI
*/
private ClientsManager clientmanager;
private InsuranceManager insurancemanager;
public ClientFrame() {
initComponents();
clientmanager = new ClientsManager();
clientmanager.printList();
updateComboBoxCompany();
updateComboBoxInsurance();
}
private ClientsManager clientmanager;
private InsuranceManager insurancemanager;
public ClientFrame() {
initComponents();
clientmanager = new ClientsManager();
clientmanager.printList();
updateComboBoxCompany();
updateComboBoxInsurance();
}
public void updateComboBoxCompany()
{
for (Object object : insurancemanager.getCompanyNames())
{
companyComboBox.addItem(object);
}
}
public void updateComboBoxInsurance()
{
for (Object object : insurancemanager.getPolicyNames())
{
insuranceComboBox.addItem(object);
}
}
Here are the methods used:
public Object[] getCompanyNames()
{
ArrayList<String> cnames = new ArrayList<String>();
for (InsurancesCompany company : insurancecompanyList)
{
cnames.add(company.getCompanyName());
}
return cnames.toArray();
}
public Object[] getPolicyNames()
{
ArrayList<String> vnames = new ArrayList<String>();
for (Insurance insurance : insuranceList)
{
vnames.add(insurance.getPolicyName());
}
return vnames.toArray();
}
This is how my lists are initialized:
public class InsuranceManager {
private String insurancePath;
private String insurancecompanyenPath;
private static List<InsurancesCompany> insurancecompanyList;
private static List<Insurance> insuranceList;
private Insurance currentInsurance;
public InsuranceManager() {
insurancecompanyenPath = "Files/company.txt";
insurancePath = "Files/insurance.txt";
insuranceList = new List<>();
}
public void createNewList()
{
insurancecompanyList = new List<>();
System.out.println("Creates list");
}
public Object[] getCompanyNames()
{
ArrayList<String> cnames = new ArrayList<String>();
for (InsurancesCompany company : insurancecompanyList)
{
cnames.add(company.getCompanyName());
}
return cnames.toArray();
}
public Object[] getPolicyNames()
{
ArrayList<String> vnames = new ArrayList<String>();
for (Insurance insurance : insuranceList)
{
vnames.add(insurance.getPolicyName());
}
return vnames.toArray();
}
Edit: Here's the MainGUI which calls createNewList (maakLijstAan)
private ClientsManager clientsmanager;
private BillingManager billingmanager;
private InsuranceManager insurancemanager;
public MainGUI() {
clientsmanager = new ClientsManager();
clientsmanager.CreateNewList();
insurancemanager = new InsuranceManager();
insurancemanager.CreateNewList();
insurancemanager.loadInsuranceCompanyList();
initComponents();
jMenuItem1.setText("Save clients");
jMenuItem2.setText("Load clients");
jMenuItem3.setText("Exit");
}
You never initialize verzekeringBeheer, therefore you get a NullPointerException when you try to invoke methods on that variable.
You should have somewhere in your constructor, something like this:
verzekeringbeheer = new VerzekeringBeheer();
Also, try to avoid making your code coupled with other parts of your code. For example:
public VerzekeringBeheer() {
...
//verzekeringmaatschappijLijst is never initialized!!!
}
public void maakLijstAan()
{
verzekeringmaatschappijLijst = new Lijst<>();
System.out.println("Maak lijst aan");
}
public Object[] getMaatschappijNamen()
{
ArrayList<String> mnamen = new ArrayList<String>();
// Here you use verzekeringmaatschappijLijst without checking that is not null!!!
for (VerzekeringsMaatschappij maatschappij : verzekeringmaatschappijLijst)
{
mnamen.add(maatschappij.getMaatschappijNaam());
}
return mnamen.toArray();
}
If nobody calls maakLijstAan, you will get a NullPointerException in getMaatschappijNamen. Try to avoid code that is so dependent of external code, in order to run without problems.
all data for JComboBox are stored in ComboBoxModel
set ComboBoxModel for proper Objects type (String, Integer, Icon or simple Object), Java7 implements Generics, there are significant differiences in compare with Java6
all updates (to the JComboBox or its Model) must be done on Event Dispatch Thread
I only see you useing variables but for me they are nit initialized. So they are null and you get a NPE.
So how are verzekeringmaatschappijLijst and verzekeringLijst initialized?