I am having issues with Processing 3.3. I am just starting on a type of nebula simulator, meant to simulate the birth and life cycle of a star from a nebula to red giant. I have created two classes so far: Gas, for each individual gas particle, and Nebula, referring to the collection of particles. I have typed in the following code to the editor with the same result each time: 'Class "Nebula" does not exist.' My code, drastically simplified, is as follows:
Gas:
class Gas {
/* variables, constructor, etc. */
void applyGravity(Nebula n) {
/* code to apply force of gravity of
the nebula to the particle */
}
}
Nebula:
class Nebula {
ArrayList<Gas> particles; // array of particles
/* variables, constructor, etc. */
}
Oddly enough, I don't get the error that 'Class "Gas" does not exist' in the Nebula class, but I do get the error 'Class "Nebula" does not exist' in the Gas class.
I have tried exiting and reopening the files, as well as reinstalling Processing. Any help would be greatly appreciated.
Basically, the Processing editor can handle two types of code. The first type is a basic list of function calls, like this:
size(500, 200);
background(0);
fill(255, 0, 0);
ellipse(width/2, height/2, width, height);
With this type of code, Processing simply runs the commands one at a time.
The second type of code is a "real" program with function definitions, like this:
void setup(){
size(500, 200);
}
void draw(){
background(0);
fill(255, 0, 0);
ellipse(width/2, height/2, width, height);
}
With this type of code, Processing calls the setup() function once at the beginning, and then calls the draw() function 60 times per second.
But note that you can't have code that mixes the two types:
size(500, 200);
void draw(){
background(0);
fill(255, 0, 0);
ellipse(width/2, height/2, width, height);
}
This will give you a compiler error, because the size() function is not inside a function!
What's going on with your code is Processing sees that you haven't defined any sketch-level functions, so it tries to treat it as the first type of code. But then it sees class definitions, which are only valid in the second type of code. That's why you're getting an error.
To fix your problem, just define a setup() and/or draw() function in your code, so Processing knows it's a "real" program.
Related
I took the application1 from examples in Gtk source
and modified GtkApplicationWindow subclass as to save some window state in the "destroy" signal handler. The problem with my code is that the save_some_state() is called twice. Why? How can I fix it?
static void
example_app_activate (GApplication *app) {
ExampleAppWindow *win;
win = example_app_window_new (EXAMPLE_APP (app));
gtk_window_present (GTK_WINDOW (win));
}
........
static void
on_app_window_destroy (GtkWidget* widget)
{
ExampleAppWindow* win = EXAMPLE_APP_WINDOW(widget);
save_some_state(win);
GTK_WIDGET_CLASS(example_app_window_parent_class)->destroy (widget);
}
static void
example_app_window_class_init (ExampleAppWindowClass *klass)
{
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
widget_class->destroy = on_app_window_destroy;
}
Well, it definitely looks like you are destroying it twice by calling
GTK_WIDGET_CLASS(example_app_window_parent_class)->destroy (widget);
in the on_app_window_destroy callback
Where are you storing example_app_window_parent_class? Is this derived from the widget? As GtkNerd says it may duplicate things if it is not chained right.
I am not entirely confident of the internals. For Gtk2, destroy is a GtkObject signal not a GtkWidget signal so you would cast as GTK_OBJECT_CLASS in that case, though that is likely irrelevant - For Gtk3 it is fine as is. I am not sure about the internals but the destroy signal might get called multiple times due to reference counting. A safer option is to override finalize as it should only get called the once irrespective.
I'm trying to create a custom scrollable text area. I created a DrawingArea and a ScrollBar inside a Grid. I have attached the draw event of DrawingArea to this.on_draw method which simply looks at ScrollBar's value and moves the Cairo.Context appropriately before drawing the Pango.Layout.
The first problem is that this.on_draw is getting invoked whenever the ScrollBar is touched even though I have not registered any events with ScrollBar. How do I prevent this, or check this?
The second problem is that even though this.on_draw is invoked, the changes made to the Context is not displayed unless the ScrollBar value is near 0 or 100 (100 is the upper value of Adjustment). Why is this happening?
I did find out that if I connect the value_changed event of ScrollBar to a method that calls queue_redraw of DrawingArea, it would invoke this.on_draw and display it properly after it. But due to the second problem, I think this.on_draw is getting invoked too many times unnecessarily. So, what is the "proper" way of accomplishing this?
using Cairo;
using Gdk;
using Gtk;
using Pango;
public class Texter : Gtk.Window {
private Gtk.DrawingArea darea;
private Gtk.Scrollbar scroll;
private string text = "Hello\nWorld!";
public Texter () {
GLib.Object (type: Gtk.WindowType.TOPLEVEL);
Gtk.Grid grid = new Gtk.Grid();
this.add (grid);
var drawing_area = new Gtk.DrawingArea ();
drawing_area.set_size_request (200, 200);
drawing_area.expand = true;
drawing_area.draw.connect (this.on_draw);
grid.attach (drawing_area, 0, 0);
var scrollbar = new Gtk.Scrollbar (Gtk.Orientation.VERTICAL,
new Gtk.Adjustment(0, 0, 100, 0, 0, 1));
grid.attach (scrollbar, 1, 0);
this.darea = drawing_area;
this.scroll = scrollbar;
this.destroy.connect (Gtk.main_quit);
}
private bool on_draw (Gtk.Widget sender, Cairo.Context ctx) {
ctx.set_source_rgb (0.9, 0.9, 0.9);
ctx.paint ();
var y_offset = this.scroll.get_value();
stdout.printf("%f\n", y_offset);
ctx.set_source_rgb (0.25, 0.25, 0.25);
ctx.move_to(0, 100 - y_offset);
var layout = Pango.cairo_create_layout(ctx);
layout.set_font_description(Pango.FontDescription.from_string("Sans 12"));
layout.set_auto_dir(false);
layout.set_text(this.text, this.text.length);
Pango.cairo_show_layout(ctx, layout);
return false;
}
static int main (string[] args) {
Gtk.init (ref args);
var window = new Texter ();
window.show_all ();
Gtk.main ();
return 0;
}
}
Also, please point out any (possibly unrelated) mistake if you find one in the above code.
The part that you are missing is that a draw signal does not mean "redraw everything". Instead, GTK+ sets the clip region of the cairo context to the part that needs to be redrawn, so everything else you do doesn't have any effect. The cairo function cairo_clip_extents() will tell you what that region is. The queue_draw_area() method on GtkWidget will allow you to explicitly mark a certain area for drawing, instead of the entire widget.
But your approach to scrollbars is wrong anyway: you're trying to build the entire infrastructure from scratch! Consider using a GtkScrolledWindow instead. This automatically takes care of all the details of scrolling for you, and will give you the overlay scrollbars I mentioned. All you need to do is set the size of the GtkDrawingArea to the size you want it to be, and GtkScrolledWindow will do the rest. The best way to do this is to subclass GtkDrawingArea and override the get_preferred_height() and/or get_preferred_width() virtual functions (being sure to set both minimum and natural sizes to the sizes you want for that particular dimension). If you ever need to change this size later, call the queue_resize() method of GtkWidget. (You probably could get away with just using set_size_request(), but what I described is the preferred way of doing this.) Doing this also gives you the advantage of not having to worry about transforming your cairo coordinates; GtkScrolledWindow does this for you.
The exercise is as follows:
Rewrite programming exercise 3 from lecture 6 by
creating a class called Button to replace the arrays.
a) Create the class and define class variables that
hold information about position, dimensions and
color. In addition a class variable should be made,
which contains the title of the particular button.
Use the constructor to set the initial values of the
class variables.
So basically, I have to convert a previous exercise I have done into a class.
This is how I made the previous exercise in case you need it: http://pastebin.com/RqM6hj6K
So I tried to convert it into class, but apparently it gives me an error and I cannot see how to fix it.
My teached also said that I don't have to keep it as an array, and could instead make many variables instead of the data in the array.
The language is processing and gives error code NullPointerException
class Button
{
int[] nums;
Button(int n1, int n2, int n3, int n4)
{
nums[0] = n1;
nums[1] = n2;
nums[2] = n3;
nums[3] = n4;
}
void display()
{
fill(255, 0, 0);
rect(nums[0], nums[1], nums[2], nums[3]);
}
};
void setup()
{
size(800, 800);
Button butt = new Button(75, 250, 200, 200);
butt.display();
}
You're only declared nums, but not initialized it.
This results in a NullPointerException: in the constructor you're accessing nums[0], but nums doesn't have a length yet. Try this:
class Button
{
//remember to initialize/allocate the array
int[] nums = new int[4];
Button(int n1, int n2, int n3, int n4)
{
nums[0] = n1;
nums[1] = n2;
nums[2] = n3;
nums[3] = n4;
}
void display()
{
fill(255, 0, 0);
rect(nums[0], nums[1], nums[2], nums[3]);
}
};
void setup()
{
size(800, 800);
Button butt = new Button(75, 250, 200, 200);
butt.display();
}
In the future, always make sure the variables you try to access properties of(arrays/objects) are initialized/allocated first(otherwise you'll get the NullPointerException again and it's no fun)
As #v.k. so nicely points out, it's better to have readable code and remove some of the redundancy.
Before the x,y,width and height of your button were stored in an array. That is all the array could do: store data and that's it! Your class however can not only store the same data as individual easy to read properties, but can also do more: functions! (e.g. display())
So, the more readable version:
class Button
{
//remember to initialize/allocate the array
int x,y,width,height;
Button(int x,int y,int width,int height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
void display()
{
fill(255, 0, 0);
rect(x,y,width,height);//why don't we use this.here or everywhere ?
}
};
void setup()
{
size(800, 800);
Button butt = new Button(75, 250, 200, 200);
butt.display();
}
Yeah, it's sorta easier to read, but what's the deal with this you may ask ?
Well, it's a keyword that allows you to gain access to the object's instance (which ever that may be in the future when you choose to instantiate) and therefore it's properties (classes version of variables) and methods (classes version of functions). There's quite a lot of neat things to learn in terms of OOP in Java, but you can take one step at a time with a nice and visual approach in Processing.
If you haven't already, check out Daniel Shiffman's Objects tutorial
Best of luck learning OOP in Processing!
I've been working on switching my applications from Swing to JavaFX. I've been working on a room escape game which displays a description of the item on which the user clicks. In Swing, I'd subclass JComponent and override the paintComponent(Graphics) method. I could draw the text there, knowing that the method is constantly called to update the screen. However, using the JavaFX Canvas, there is no method that is called constantly, which makes this task harder. I attempted save()ing the GraphicsContext after I drew the images and called restore() when I wanted to remove the text, but to no avail. Here's the important code:
package me.nrubin29.jescape;
import javafx.application.Platform;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.shape.Rectangle;
import java.util.Timer;
import java.util.TimerTask;
public class RoomPane extends Canvas {
private Room room;
private Toast toast;
public RoomPane() {
super(640, 480);
setOnMouseClicked(e -> {
for (JObject o : room.getObjects()) {
if (o.getBounds().contains(e.getX(), e.getY())) {
toast = new Toast(o.getDescription());
}
}
});
new Timer().schedule(new TimerTask() {
#Override
public void run() {
if (toast == null) {
return;
}
if (toast.decrement()) { // Decrements the internal counter. If the count is 0, this method returns true.
toast = null;
Platform.runLater(() -> getGraphicsContext2D().restore());
}
else {
Platform.runLater(() -> getGraphicsContext2D().strokeText(toast.getText(), 300, 100));
}
}
}, 0, 1000);
}
public void changeRoom(Room room) {
this.room = room;
GraphicsContext g = getGraphicsContext2D();
g.drawImage(room.getBackground(), 0, 0);
for (JObject o : room.getObjects()) {
g.drawImage(o.getImage(), getCenterX(o.getBounds()), getCenterY(o.getBounds()));
}
g.save();
}
}
I attempted save()ing the GraphicsContext after I drew the images and called restore() when I wanted to remove the text, but to no avail.
save and restore have nothing to with removing things like text, what they do is save in a stack the state of various settings like a stroke or fill to use to draw shapes and allow them to be popped off the stack for application later. Those routines don't effect the pixels drawn on the canvas at all.
To remove something from a GraphicsContext, you can either draw over the of it, or clear it. For your code, what you could do is snapshot the canvas node where you are trying to save it, then draw your snapshot image onto the canvas where you are trying to restore it. It is probably not the most efficient way of handling drawing (a smarter routine which just draws only damaged area where the text is would be better, but probably not required for your simple game).
However, using the JavaFX Canvas, there is no method that is called constantly
Rather than using a timer to trigger canvas calls, use a AnimationTimer or a Timeline. The AnimationTimer has a callback method which is invoked every pulse (60 times a second, or as fast as JavaFX can render frames, whichever is the lesser), so it gives you an efficient hook into the JavaFX pulse based rendering system. The Timeline can have keyframes which are invoked at user specified durations and each keyframe can have an event handler callback which is invoked at that duration.
Using the built-in JavaFX animation framework, you don't have to worry about multi-threading issues and doing things like Platform.runLater which overly complicate your code and can easily lead to subtle and serious errors.
On a kind of unrelated note, for a simple game like this, IMO you are probably better off recoding it completely to use the JavaFX scene graph rather than a canvas. That way you will be working at a higher level of abstraction rather than clip areas and repainting damaged paint components.
Ok, I'm writing a method that creates an entire panel and it's containing contents and adds it to the form. The panels are stored in an array.
Here's the basic idea.
void vscale1Event(GtkWidget *widget, int *vscale_id)
{
int value = gtk_range_get_value(GTK_RANGE(vscale_struct[*vscale_id]->vscale1));
do stuff with this value;
}
void add_vscale_panel(int vscale_id)
{
vscale_struct[vscale_id]->vscale1 = ..... ;
vscale_struct[vscale_id]->vscale2 = ..... ;
add buttons to form;
gtk_signal_connect(GTK_OBJECT(vscale_struct[button_id]), "value_changed", (GtkSignalFunc)vscale1Event, &vscale_id);
gtk_signal_connect(GTK_OBJECT(vscale_struct[button_id]), "value_changed", (GtkSignalFunc)vscale2Event, &vscale_id);
}
int main()
{
for (i = 0; i<n; i++)
{
add_vscale_panel(i);
}
}
The problem I'm having, is that &vscale_id that I'm passing in, later becomes junk (it's value is a junk number around 32000) when I move the scale.
But - the gtk_signal_connect is only being called that once.
Ok, I get that it's probably something to do with the call stack, that bit of memory no longer being reserved.
But I did this same thing earlier for another panel, and it's working fine.
what I've changed - is trying to make things a bit tidier.
The previous version I had all the panels and widgets each in seperate arrays.
eg
GtkWidget **outerPanel;
GtkWidget **innerPanel1;
GtkWidget **vscale1;
whereas this one I'm doing it:
typedef struct
{
GtkWidget **vscale1;
Gtkwidget **vscale2;
} V_Panel;
V_Panel **vscale_struct;
Not bothering putting the panels into arrays or structs - because I figure I don't need to access them later? ( I found that you can 'recycle' labels so I figure panels (h and vboxes), are the same.
Also - an interesting clue - when I run valgrind - it works fine. Some how valgrind changes the way the program uses it's memory.
Any help here?
If you can perhaps explain what's happening when you call gtk_signal_connect. -
Here's my actual code: http://pastebin.com/MGfUihjM
relevant lines are
45, 145, 274, 308, 391
The problem is that your taking the address of a variable on the stack - in this case the parameter to the function. That address in memory is definitely not guaranteed to continue to hold the value you expect it to since it is just part of the stack frame
The correct way to pack your integer value_id into the callback userdata pointer is to use GINT_TO_POINTER and to reverse it using GPOINTER_TO_INT.
So your signal connection would be:
gtk_signal_connect(GTK_OBJECT(vscale_struct[button_id]),
"value_changed",
(GtkSignalFunc)vscale1Event,
GINT_TO_POINTER(value_id));
And in your signal handler would look like:
void vscale1Event(GtkWidget *widget, gpointer userdata)
{
int vscale_id = GPOINTER_TO_INT (userdata);
int value = gtk_range_get_value(GTK_RANGE(vscale_struct[vscale_id]->vscale1));
do stuff with this value;
}