Very basic AChartEngine XY - achartengine

I've been trying for hours to get something as simple as displaying a line chart based on 2 dots that I supply manually and all I get is a crash. I've tried to understand how everything works based on the demo code but it's too complex. I'm not even concerned about writing nice code with onResume() etc, I just want something to display the first time I open the activity. Once I know how to do that I'll be able to adapt and learn what I need. Here's the code I came up with:
public class StatsActivity extends Activity {
private XYMultipleSeriesDataset StatsDataset = new XYMultipleSeriesDataset();
private XYMultipleSeriesRenderer StatsRenderer = new XYMultipleSeriesRenderer();
private XYSeries StatsCurrentSeries;
private GraphicalView StatsChartView;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.stats);
LinearLayout layout = (LinearLayout) findViewById(R.id.Statschart);
StatsRenderer.setAxesColor(Color.YELLOW);
String seriesTitle = "Rank";
XYSeries series = new XYSeries(seriesTitle);
series.add(5, 7); //1st series I want to add
StatsDataset.addSeries(series);
series.add(9, 1); //the 2nd one
StatsDataset.addSeries(series);
StatsCurrentSeries = series;
System.out.println(series);
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.RED);
StatsRenderer.addSeriesRenderer(renderer);
StatsChartView = ChartFactory.getLineChartView(this, StatsDataset,StatsRenderer);
layout.addView(StatsChartView);
}
}
I've been reading the docs to determine what each function does but in the end I still can't get anything to display.
Thanks!

The big thing that I struggled with is that you need a renderer for each XYSeries. You have two series here, but just one renderer - I just create/add renderers when I input data. Also, Android is mostly pass-by-reference, so you've passed the same data set in twice (i.e. your second update to the data will be mirrored "in" the MultipleSeriesDataset).

Related

GTK4 Vala - show FileChooserDialog

I am playing around with Vala and GTK4.
FileChooserDialog is not working for me
using Gtk;
int main (string[] argv) {
// Create a new application
var app = new Gtk.Application ("com.example.GtkApplication",
GLib.ApplicationFlags.FLAGS_NONE);
app.activate.connect (() => {
// Create a new window
var window = new Gtk.ApplicationWindow (app);
window.title = "File chooser";
window.set_default_size (350, 70);
window.resizable = false;
// Create a new button
var file_choose_button = new Gtk.Button.with_label ("...");
file_choose_button.clicked.connect (() => {
var fileChooser = new FileChooserDialog(
"Select File",
window,
FileChooserAction.OPEN,
"Cancel",
ResponseType.CANCEL,
"Open",
ResponseType.ACCEPT,
null);
fileChooser.response.connect(()=> {
stdout.printf("File selectd!");
});
// WHAT TO DO IN ORDER TO SHOW FILE CHOOSER?
});
window.set_child (file_choose_button);
// Show
window.present ();
});
return app.run (argv);
}
I am missing some important piece of code, that will cause the FileChooserDialog to "appear".
In previous Versions of GTK there is "dialog.run" - which is missing in GTK4.
The C-Example on https://docs.gtk.org/gtk4/class.FileChooserDialog.html uses makro(?) "gtk_widget_show(xxx)" for which I was not able to find an representation in Vala.
Any help appreciated!
Best Regards
Emil
After some struggle the solution was found (and is pretty simple).
As stated in the Vala Documentaion Site - File Chooser Dialog
It inherits from couple of classes one of which is GTK.Window.
So it is as simple as calling the present() method.
Thus the missing command above is:
fileChooser.present();
One should not forget to use the close() method once file was selected or selection was canceled.
Important note:
"gtk_widget_show()" representation in Vala is GTK.Widget.show() BUT
I was not clever enough to find out how to prepare the parameter.
It expects pointer (GtkWidget*) and simply passing the "fileChooser" causes all kinds of compiler exceptions.
May be someone can throw more light on this (as I am using Vala to avoid the use of C - I am clearly not the expert in this area)

Vaadin 21 flow. How to migrate CustomLayout used to have a panel with border

with vaadin 7 ( we are trying to migrate to v21, very, very, hard) we have this
CustomLayout cl1 = new CustomLayout(new ByteArrayInputStream("<fieldset><legend location='legend'></legend><div location='content'></div></fieldset>".getBytes()));
cl1.setSizeUndefined();
cl1.add(new Label(title), "legend");
cl1.add( panel, "content");
Basically is a panel with border and title-border
How we can do this in vaadin flow v21
Thanks in advance
There's a Cookbook recipe that provides an alternative for CustomLayout: https://cookbook.vaadin.com/custom-layout
Essentially, the CustomLayout replacement class extends Html in a fairly straightforward way. The add method has most of the logic:
public class CustomLayout extends Html {
private Map<String, Component> locations = new HashMap<>();
public CustomLayout(String template) {
super(template);
}
public CustomLayout(InputStream stream) {
super(stream);
}
public void add(Component child, String location) {
remove(location);
locations.put(location, child);
// Establish parent-child relationship, but leave DOM attaching to us
getElement().appendVirtualChild(child.getElement());
// Attach to the specified location in the actual DOM
getElement().executeJs("this.querySelector('[location=\"'+$0+'\"]').appendChild($1)", location,
child.getElement());
// Ensure the element is removed from the DOM when it's detached
child.addDetachListener(detachEvent -> {
detachEvent.unregisterListener();
getElement().executeJs("this.querySelector && this.querySelector('[location=\"'+$0+'\"]').lastChild.remove()", location);
// Also clear the bookkeeping
locations.remove(location, child);
});
}
public void remove(String location) {
Component oldChild = locations.remove(location);
if (oldChild != null) {
remove(oldChild);
}
}
public void remove(Component child) {
getElement().removeVirtualChild(child.getElement());
}
}
Note that it's important to do the bookkeeping with the locations Map so that client-side elements get removed too after the parent is detached.
Vaadin 10+ defines "elements" for most commonly used HTML tags, and has higher level abstractions for components built on top of those elements. It does not include an element or a component for <fieldset>. I'm not familiar with Vaadin 7, but it looks like it didn't come with it either.
There are a couple of ways to do what you want with Vaadin 10+. Here's a quick example based on extending the Component class:
#Tag("fieldset")
public class FieldSet extends Component {
private final Div enclosedComponents;
public FieldSet(String label) {
Element legend = new Element("legend").setText(label);
getElement().appendChild(legend);
enclosedComponents = new Div();
getElement().appendChild(enclosedComponents.getElement());
}
public void add(Component ... components) {
enclosedComponents.add(components);
}
}
I did not include a robust API. It would be more useful with a full compliment of add and remove methods, as well as a means to update the label.
As a point of learning 10+, know that the nature of fieldset makes this one more complicated. If this did not have to include the <legend> tag it could be far simpler, because you could simply extend Div or one of the several Layout classes and inherit a robust API.
There is a section of the documentation that outlines the various ways to solve these types of problems. I found it invaluable when I first started using Vaadin. It's not always clear when to use each of the approaches, but you'll get the feel for it.

Custom List with lazy loading

I have successfully implemented like this for lazy loading in custom list
and the code I used for this is here:Custom List With Images in Blackberry
In the linked question, I position the y coordinate of heart icon and I resolved the problemm of linked Question.
if (logoThumbnailImage != null
&& logoThumbnailImage.length > index
&& logoThumbnailImage[index] != null) {
EncodedImage img = logoThumbnailImage[index];
graphics.drawImage(0, y + 10, Display.getWidth(),
Display.getHeight() - 100, img, 0, 0, 0);
graphics.drawImage(300,
y+400,
heart.getWidth(), heart.getHeight(), heart,
0, 0, 0);
Now I want to handle click event for both; that is, for list row click and on heart click
For that I saw a post written by #Nate here Custom List Field click event. But in that code the images are not loading from server and they are static Images. I want to implement #Nate's code with my code (That is lazy loading ).
If you have any Idea please suggest how can I do that. Thanks in Advance
Assuming you start with the code I posted in this answer, and use the code you show in this question to download images from a list of URLs, then you should be able to achieve lazy image loading with the following changes:
Create a listener interface that gets notified when downloads complete:
public interface DownloadListener {
// invokes if download success
public void downloadSuccess(Bitmap bitmap);
// invokes if download failed
public void errorOccured();
}
Then, the Manager subclass that represents one list row, CustomListRow, is modified to implement this interface, and update the _thumb image when the download completes:
public class CustomListRow extends Manager implements DownloadListener, FieldChangeListener {
public void downloadSuccess(final Bitmap img) {
_data.setThumb(img);
// make sure bitmap is updated on the UI / main thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_thumb.setBitmap(img);
}
});
}
public void errorOccured() {
// TODO: handle error
}
Then, you'll need to add some code to create all your threads to download images in the background, and notify the DownloadListeners when the image downloads complete. You can decide where to do this. In my example, I will do this in my ListScreen class, where I instantiate the ListRander data objects and the CustomListField:
for (int i = 0; i < numberOfItem; i++) {
ListRander lr = new ListRander("Product Name " + i, icon); // icon is placeholder for thumbnail image
data.addElement(lr);
}
final CustomListField list = new CustomListField(data);
add(list);
list.setChangeListener(this);
pool = new ThreadPool(3); // 3 concurrent download threads
for (int i = 0; i < numberOfItem; i++) {
final int row = i;
// create a new runnable to download the next image, and resize it:
pool.assign(new Runnable() {
public void run() {
try {
String text=object[row].getJSONArray("UrlArray").getString(0).toString();
EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), quality); //connectserverForImage load Images from server
EncodedImage logoThumbnail = sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
list.getRow(row).downloadSuccess(logoThumbnail.getBitmap());
} catch (Exception e) {
e.printStackTrace();
list.getRow(row).errorOccured();
}
}
}
});
}
You could do this in the ListScreen constructor, or whenever you have your object[] array of URLs.
You'll need to add a new method to CustomListField:
public CustomListRow getRow(int row) {
return (CustomListRow)getField(row);
}
The code above also needs a member variable added (in ListScreen) to create a thread pool:
private ThreadPool pool;
This thread pool implementation is based on this tutorial here, with very minor modifications, simply to change ArrayList (not available on BlackBerry Java) to Vector ... and removing the calls to Thread#destroy(). You'll need to copy that tutorial's ThreadPool, WorkerThread, and Done classes to your project. The above example I show creates a thread pool of 3 threads. On a single CPU smartphone, 2 or 3 threads is probably fine for your needs. Read more here if you want to get the perfect number of threads for your application.
Note: if possible, you can usually improve performance if you download images that are exactly the right size for your application, instead of burdening the network with larger images, and then resizing them inside your app. However, I realize that this depends on having some control over the images' web server, which you may not have. Just a thought for later optimization.
I am sure that I seen a good answer to this question on my travels, but can't find it now. I do recommend reviewing the BB forums here:
http://supportforums.blackberry.com/t5/Java-Development/bd-p/java_dev
as there are similar questions there.
For now, just the highlights of what you need to do:
Create an image downloading runnable to process the download - you have pretty much already done this in your previous code.
Use the Observer pattern (search the internet for this), so that the BitmapField is the Observer for the completion of your image downloading. So when the image has been downloaded, the Runnable invokes the observer, which can then update the Bitmap.
Use a Thread pool with a limited number of Threads (I would say 3), so that you do not start a whole load of image downloads at the same time. Search the internet for information on Thread Pool for help implementing this. You had not done this step in your previous example, and you can get away with running all the downloads, but I expect at some stage that this will fail.
Put these together and you have your solution. Not trivial I know. Good luck.

Actionscript, objects and event listeners

Say I have an object
var my_obj = new Object();
my_obj['key'] = value;
Is there a way to add an event listener to the value, like
my_obj['key'].addEventListener(Blah Blah);
I have a long(ish) list of buttons on the timeline (the layout is so different from section to section that just makes more sense to do on the timeline rather than trying to build the layouts via actionscript).
button1 = plays "frame label 1"
button2 = plays "frame label 2"
and so on....so I was just thinking of storing everything in an array
obj["button1"] = "framelabel1"
arr.push(obj);
Then I could just have one event handler for all of the buttons and use target to get the frame label value...
Yes, you can do exactly what you're asking in the exact way you've mentioned, here's an example:
var value:Sprite = new Sprite();
var my_obj = new Object();
my_obj['key'] = value;
So calling:
my_obj['key'].addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
is exactly the same as calling:
value.addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
If the value is an IEventDispatcher or extends EventDispatcher you can add a listener to it.
The question is rather obscure to me. My guess is that you need something triggered every time a value is set. If this is the case, then you have to create a custom class, and declare a getter-setter property there.
For instance:
package
{
import flash.display.Sprite;
public class TestAccessor extends Sprite
{
private var someVarValue:uint = 0;
public function TestAccessor()
{
super();
}
public function get someVar():uint
{
return someVarValue;
}
public function set someVar(value:uint):*
{
someVarValue = value;
// this is the place where someVar is set.
// do whatever else you like here,
// you may choose to dispatch an event from here if you need.
}
}
}
Back in AS1-AS2 era we had watch() and addProperty() for that purpose, but these times are long since gone. For good. :)

XNA 4.0 - What happens when the window is minimized?

I'm learning F#, and decided to try making simple XNA games for windows using F# (pure enthusiasm) , and got a window with some images showing up.
Here's the code:
(*Methods*)
member self.DrawSprites() =
_spriteBatch.Begin()
for i = 0 to _list.Length-1 do
let spentity = _list.List.ElementAt(i)
_spriteBatch.Draw(spentity.ImageTexture,new Rectangle(100,100,(int)spentity.Width,(int)spentity.Height),Color.White)
_spriteBatch.End()
(*Overriding*)
override self.Initialize() =
ChangeGraphicsProfile()
_graphicsDevice <- _graphics.GraphicsDevice
_list.AddSprite(0,"NagatoYuki",992.0,990.0)
base.Initialize()
override self.LoadContent() =
_spriteBatch <- new SpriteBatch(_graphicsDevice)
base.LoadContent()
override self.Draw(gameTime : GameTime) =
base.Draw(gameTime)
_graphics.GraphicsDevice.Clear(Color.CornflowerBlue)
self.DrawSprites()
And the AddSprite Method:
member self.AddSprite(ID : int,imageTexture : string , width : float, height : float) =
let texture = content.Load<Texture2D>(imageTexture)
list <- list # [new SpriteEntity(ID,list.Length, texture,Vector2.Zero,width,height)]
The _list object has a ContentManager, here's the constructor:
type SpriteList(_content : ContentManager byref) =
let mutable content = _content
let mutable list = []
But I can't minimize the window, since when it regains its focus, i get this error:
ObjectDisposedException
Cannot access a disposed object.
Object name: 'GraphicsDevice'.
What is happening?
Well after struggling for some time I got it to work. But it doesn't seem "right"
(thinking that way, using XNA and F# doesn't seem right either, but it's fun.)
(*Methods*)
member self.DrawSprites() =
_spriteBatch.Begin()
for i = 0 to _list.Length-1 do
let spentity = _list.List.ElementAt(i)
if spentity.ImageTexture.IsDisposed then
spentity.ImageTexture <- _list.Content.Load<Texture2D>(spentity.Name)
_spriteBatch.Draw(spentity.ImageTexture,new Rectangle(100,100,(int)spentity.Width,(int)spentity.Height),Color.White)
_spriteBatch.End()
(*Overriding*)
override self.Initialize() =
ChangeGraphicsProfile()
_list.AddSprite(0,"NagatoYuki",992.0,990.0)
base.Initialize()
override self.LoadContent() =
ChangeGraphicsProfile()
_graphicsDevice <- _graphics.GraphicsDevice
_spriteBatch <- new SpriteBatch(_graphicsDevice)
base.LoadContent()
I adjust the graphicsDevice whenever my game needs to LoadContent, and in the DrawSprites() method I check if the texture is disposed, if it is, load it up again.
But this thing bugs me. I didn't know I had to Load all Content again everytime the window is minimized.
(And the code makes it look like Initialize() loads Content, and LoadContent() initializes, but oh well)
What you are observing is normal behaviour, it's by the way not specific to F#. See http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.loadcontent.aspx
This method is called by Initialize. Also, it is called any time the game content needs to be reloaded, such as when the DeviceReset event occurs.
Are you loading all of your content in Game.LoadContent? If you do, you should not be getting these errors.

Resources