I have a custom class (MyBox) that extend devDept.Eyeshot.Entities.Solid and I want to add it to the ViewportLayout like this:
MyBox box = new MyBox(10, 20, 30); // length, width, height
EyeViewportLayout.Entities.Add(box);
EyeViewportLayout.ZoomFit();
EyeViewportLayout.Invalidate();
I notice that to visualize my class I need to call Solid.CreateBox(length, width, height) which return a new Solid. How can I do the same work of CreateBox inside my custom class MyBox so when I add it to ViewportLayout.Entities it get displayed ?
If you solid is really only a box or anything in this list there is a simple way :
Box
Cone
Cylinder
Sphere
Spring
Torus
I'll assume it's really a box. Then create your class deriving from solid
public class MyBox : Solid
{
public double Length {get; private set;} = 0d;
public double Width {get; private set;} = 0d;
public double Height {get; private set;} = 0d;
public MyBox() { }
public MyBox Create(double length, double width, double height)
{
var myBox = Solid.CreateBox<MyBox>(length, width, height);
myBox.Length = length;
myBox.Width = width;
myBox.Height = height;
return myBox;
}
}
If you use any other shape of solid you will need to manually create each faces.
Related
I am printing objects from an array outputting 8 image objects using a for loop, the code works without draw() method, but when I include it, only the background image is shown.
How do I call the draw method in the setup method to work?
public class FishPAppletTest {
private static PApplet processing; // PApplet object that represents the graphic interface of the JunglePark application
private static PImage backgroundImage; // PImage object that represents the background image
private static Fish[] fishes; // fishes object, reference to perfect size array storing fish objects in the fish tank. These fish can be of different species.
private static Random randGen; // Type random constructor when new, Generator of random numbers
public static void main(String[] args) {
Utility.startApplication();
System.out.println(fishes[0]); //null because it is not stored?
}
/**
* Defines the initial environment properties of this application
* #param processingObj a reference to the graphic display window of this application
*/
public static void setup(PApplet processing) { // PApplet is kept, processing is the variable as input
backgroundImage = processing.loadImage("images/background.png"); // loads image in background
fishes = new Fish[8];
processing.image(backgroundImage, processing.width / 2, processing.height /2); // draw background image
}
/**
* Draws and updates the application display window.
* This callback method called in an infinite loop.
*/
public static void draw() { // called by utility class
for (int i = 0; i < fishes.length; i++) {
fishes[i] = new Fish(processing, processing.width / 2, processing.height / 2);
randGen = new Random(); // WORKS UP
int x = randGen.nextInt(processing.width);
int y = randGen.nextInt(processing.height);
fishes[i] = new Fish(processing, x, y);
fishes[i].draw();
}
}
}
Without seeing what Utility and Fish do, it's hard to guess what the exact behaviour is.
If you're seing the background and not the fish it's likely setup() get's called, but not draw() for some reason.
Ideally you'd initialise the Fish instances once in setup() then re-use in draw() (otherwise you're instantiating multiple times per second).
I would try something simpler.
public class FishPAppletTest extends PApplet{
private PImage backgroundImage; // PImage object that represents the background image
private Fish[] fishes;
// fishes object, reference to perfect size array storing fish objects in the fish tank. These fish can be of different species.
public void setup() {
// wild guess about sketch dimensions
size(600, 600);
backgroundImage = loadImage("images/background.png");
//loads image in background
fishes = new Fish[8];
for (int i = 0; i < fishes.length; i++) {
fishes[i] = new Fish(this, width / 2, height / 2);
}
}
/**
* Draws and updates the application display window.
* This callback method called in an infinite loop.
*/
public void draw() {
image(backgroundImage, width / 2, height /2);
for (int i = 0; i < fishes.length; i++) {
// hopefully Fish has public x,y properties ?
fishes[i].x = (int)random(width);
fishes[i].y = (int)random(height);
fishes[i].draw();
}
}
// initialise PApplet (kicks off setup/draw Processing sketch lifecycle)
public static void main(String[] args) {
PApplet.main(FishPAppletTest.class.getCanonicalName());
}
}
and this is a placeholder class mimicking your structure a bit:
public class Fish{
private PAppet parent;
public float x, y;
public Fish(PApplet parent, float x, float y){
this.parent = parent;
this.x = x;
this.y = y;
}
public void draw(){
parent.ellipse(x, y, 20, 10);
}
}
Hopefully this helps restructure the program ?
The ingredients are there, the order was a bit off.
FWIW, this is the sketch version you can simply paste and run in the Processing IDE:
// PImage object that represents the background image
private PImage backgroundImage;
// fishes reference to perfect size array storing fish objects in the fish tank. These fish can be of different species.
private Fish[] fishes;
public void setup() {
size(600, 600);
//loads image in background
backgroundImage = loadImage("images/background.png");
fishes = new Fish[8];
// instantiate Fish once
for (int i = 0; i < fishes.length; i++) {
fishes[i] = new Fish(this, width / 2, height / 2);
}
}
/**
* Draws and updates the application display window.
* This callback method called in an infinite loop.
*/
public void draw() {
image(backgroundImage, 0, 0);
// reuse Fish instances
for (int i = 0; i < fishes.length; i++) {
// hopefully Fish has public x,y properties ?
fishes[i].x = (int)random(width);
fishes[i].y = (int)random(height);
fishes[i].draw();
}
}
public class Fish{
private PApplet parent;
public float x, y;
public Fish(PApplet parent, float x, float y){
this.parent = parent;
this.x = x;
this.y = y;
}
public void draw(){
parent.ellipse(x, y, 20, 10);
}
}
I've written a small proxy class so that I can use ObjectAnimator to animate a view's margin. After checking that this worked and everything animated properly, I wanted to adjust the view's size before the animation, but after I set the width, my animation fails with the ClassCastException. I haven't a clue why.
private class handleClickListener implements View.OnClickListener {
private static final int LEFT_MARGIN_VISIBLE = 0;
private static final int LEFT_MARGIN_HIDDEN = -196;
public void onClick(View view) {
LinearLayout row = (LinearLayout) view.getParent().getParent();
RelativeLayout options = (RelativeLayout) row.findViewById(R.id.options);
LayoutProxy layoutProxy = new LayoutProxy(options);
// First make sure the options are the right width to fill the screen with the handle
int rowWidth = row.getWidth();
int handleWidth = view.getWidth();
layoutProxy.setWidth(rowWidth - handleWidth);
ObjectAnimator animation;
if (layoutProxy.getLeftMargin() == Util.dipsToPixels(options, LEFT_MARGIN_VISIBLE)) {
animation = ObjectAnimator.ofInt(layoutProxy, "leftMargin", Util.dipsToPixels(view, LEFT_MARGIN_VISIBLE), Util.dipsToPixels(view, LEFT_MARGIN_HIDDEN));
} else {
animation = ObjectAnimator.ofInt(layoutProxy, "leftMargin", Util.dipsToPixels(view, LEFT_MARGIN_HIDDEN), Util.dipsToPixels(view, LEFT_MARGIN_VISIBLE));
}
animation.setDuration(200);
animation.start();
}
/**
* Allows an ObjectAnimator to set/get margins and dimensions of a view
*/
private class LayoutProxy {
private ViewGroup mView;
public LayoutProxy(View view) {
mView = (ViewGroup) view;
}
public int getWidth() {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
return lp.width;
}
public void setWidth(int width) {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
mView.setLayoutParams(new ViewGroup.LayoutParams(width, lp.height));
}
public int getHeight() {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
return lp.height;
}
public void setHeight(int height) {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
mView.setLayoutParams(new ViewGroup.LayoutParams(lp.width, height));
}
public int getLeftMargin() {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
return lp.leftMargin;
}
public void setLeftMargin(int margin) {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
lp.setMargins(margin, lp.topMargin, lp.rightMargin, lp.bottomMargin);
mView.requestLayout();
}
public int getTopMargin() {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
return lp.topMargin;
}
public void setTopMargin(int margin) {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
lp.setMargins(lp.leftMargin, margin, lp.rightMargin, lp.bottomMargin);
mView.requestLayout();
}
public int getRightMargin() {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
return lp.rightMargin;
}
public void setRightMargin(int margin) {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
lp.setMargins(lp.leftMargin, lp.topMargin, margin, lp.bottomMargin);
mView.requestLayout();
}
public int getBottomMargin() {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
return lp.bottomMargin;
}
public void setBottomMargin(int margin) {
MarginLayoutParams lp = (MarginLayoutParams) mView.getLayoutParams();
lp.setMargins(lp.leftMargin, lp.topMargin, lp.rightMargin, margin);
mView.requestLayout();
}
}
}
And the error:
FATAL EXCEPTION: main
java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
at com.test.data.ContactListCursorAdapter$handleClickListener$LayoutProxy.getLeftMargin(ContactListCursorAdapter.java:135)
at com.test.data.ContactListCursorAdapter$handleClickListener.onClick(ContactListCursorAdapter.java:94)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
I have similar problem
At first I was using:
LayoutParams viewFlowLayout = new LayoutParams(originalWidth, newHeight);
viewFlow.setLayoutParams(flowViewLayout);
And I have the same error message as yours:
java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
which I have no idea why as i didn't use MarginLayoutParams.
Then I try and change it to this
LayoutParams viewFlowLayout = viewFlow.getLayoutParams();
viewFlowLayout.height = newheight;
viewFlow.setLayoutParams(flowViewLayout);
And the error disappear...
I guess you have multiple use case for the above code.
For example: Change this
public void setHeight(int height) {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
mView.setLayoutParams(new ViewGroup.LayoutParams(lp.width, height));
}
to
public void setHeight(int height) {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
lp.height = height //width will remain and height will be change to the newHeight
mView.setLayoutParams(lp);
}
Hope that it will be helpful to you and many people out there...
I just want to know the reason why you are casting LayoutParams to MarginLayoutParams. Is there a specific reason? Because i think the problem lies there.
I am trying to paint only one part of Image. The image human is 159x22 length.
In that image there is 8 human bodies (2 left, 2 right and etc.). If i try to set the Frame to humanSprite.setFrame(1); I will get an error since I specified in the Sprite constructor the size of an Image so there is only one frame.
Well I have tried to divide it by 8 and Ill getjava.lang.IllegalArgumentException`.
Here is the class :
package org.pack.rhynn;
import java.io.IOException;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import java.util.Random;
public class play extends GameCanvas implements Runnable{
int sleep = 30;
private Image map;
private Sprite mapSprite;
private Image human;
private Sprite humanSprite;
private int humanX = getWidth() /2;
private int humanY = getHeight() /2;
public play(){
super(false);
}
public void start(){
try {
map = Image.createImage("/mapas.png");
human = Image.createImage("/human.PNG");
} catch (IOException ioex) {
System.out.println(ioex);
}
mapSprite = new Sprite(map);
mapSprite.defineReferencePixel(100, 150);
mapSprite.setRefPixelPosition(0, 0);
humanSprite = new Sprite(human,159,22);
humanSprite.defineReferencePixel(1, 10);
humanSprite.setRefPixelPosition(humanX, humanY);
Thread thr = new Thread(this);
thr.start();
}
public void run(){
while(true){
updateScreen(getGraphics());
try{
Thread.sleep(sleep);
}catch(Exception e){}
}
}
private void createBackground(Graphics g){
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
}
private void updateScreen(Graphics g){
createBackground(g);
mapSprite.setRefPixelPosition(0, 0);
mapSprite.paint(g);
humanSprite.setRefPixelPosition(humanX, humanY);
humanSprite.setFrame(0);
humanSprite.setPosition(50,50);
humanSprite.paint(g);
flushGraphics();
}
}
The problem seems to be with your image. All frames must have the same width and height and the image final width and hight must be a multiple of them.
For example, let's say all your frames are in a single row. If the frame width is 19 and you have 8 frames, the final image width must be 152.
On a canvas there is an image and on touch at certain part of the image, I am looking to launch a new Canvas from within pointerPressed() method.
Is it possible? So far I have done the following:
protected void pointerPressed(int x, int y){
if ((x>=164 && x<=173)&&(y>=24 && y<=36)){
disp.setCurrent(new elementDetails());
}
}
and the class is as follows:
//class to show detailed information of elements
class elementDetails extends Canvas{
private Image elmDtlImg;
public elementDetails(){
try{
elmDtlImg = Image.createImage("/details.jpg");
}
catch(IOException e){
System.out.println("Couldn't load Detailed Info image" + e.getMessage());
}
}
public void paint(Graphics g){
//set the drawing color to white
g.setGrayScale(255);
//draw a big white rectangle over the whole screen (over the previous screen)
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(elmDtlImg, 0, 0, 20);
}
}
When I run the above code nothing happens. I mean to say that the current image does not change to the new one which I am trying to show in the canvas.
My application keeps on running after the pointer pressed event. It does not crashes. It shows me the coords of other parts of the image correctly. What I am trying to achieve is that; when I click/touch at some particular points of the image it should load a new canvas in place of the old one.
A canvas is made visible by calling the Display.setCurrent() method.You would to retrieve Display from your MIDlet and pass it to your canvas,then use it.I hope this snippet code help you:
//MIDlet:
public class MyMIDlet extends MIDlet{
...
final Canvas1 c1;
final elementDetails c2;
...
public MyMIDlet(){
c1 = new Canvas1(this);
c2 = new elementDetails();
}
...
}
//canvas1:
public class Canvas1 extends Canvas{
MyMIDlet myMidlet;
Display disp;
...
/**
*constructor
*/
public Canvas1(MyMIDlet myMidlet){
this.MyMIDlet = myMidlet;
disp = myMidlet.getDisplay();
}
...
public void paint(Graphics g){
g.setColor(255,255,255);
g.drawString("canvas1", 0, 0, 0);
}
...
protected void pointerPressed(int x, int y){
if ((x>=164 && x<=173)&&(y>=24 && y<=36)){
disp.setCurrent(myMidlet.c2);
}
}
//class to show detailed information of elements
class elementDetails extends Canvas{
private Image elmDtlImg;
public elementDetails(){
try{
elmDtlImg = Image.createImage("/details.jpg");
}
catch(IOException e){
System.out.println("Couldn't load Detailed Info image" + e.getMessage());
}
}
public void paint(Graphics g){
//set the drawing color to white
g.setGrayScale(255);
//draw a big white rectangle over the whole screen (over the previous screen)
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(elmDtlImg, 0, 0, 20);
}
}
I want to show a progress bar indicating loading application at the beginning.
How can that be done? I have created a gauge but I think it cannot be implemented in LWUIT form..
Based on my comment, You can use progress bar. And also you can use slider component for instead of showing progress bar in LWUIT.
The best way is to use canvas. You can reuse the class in all your apps and it is very efficient. Create a class, say like a class named Splash:
public class Splash extends Canvas {
private final int height;
private final int width;
private int current = 0;
private final int factor;
private final Timer timer = new Timer();
Image AppLogo;
MayApp MIDlet;
/**
*
* #param mainMIDlet
*/
public Splash(MyApp mainMIDlet) {
this.MIDlet = mainMIDlet;
setFullScreenMode(true);
height = getHeight();
width = this.getWidth();
factor = width / 110;
repaint();
timer.schedule(new draw(), 1000, 01);
}
/**
*
* #param g
*/
protected void paint(Graphics g) {
try {//if you want to show your app logo on the splash screen
AppLogo = javax.microedition.lcdui.Image.createImage("/appLogo.png");
} catch (IOException io) {
}
g.drawImage(AppLogo, getWidth() / 2, getHeight() / 2, javax.microedition.lcdui.Graphics.VCENTER | javax.microedition.lcdui.Graphics.HCENTER);
g.setColor(255, 255, 255);
g.setColor(128, 128, 0);//the color for the loading bar
g.fillRect(30, (height / 2) + 100, current, 6);//the thickness of the loading bar, make it thicker by changing 6 to a higher number and vice versa
}
private class draw extends TimerTask {
public void run() {
current = current + factor;
if (current > width - 60) {
timer.cancel();
try {
//go back to your midlet or do something
} catch (IOException ex) {
}
} else {
repaint();
}
Runtime.getRuntime().gc();//cleanup after yourself
}
}
}
and in your MIDlet:
public class MyApp extends MIDlet {
Splash splashScreen = new Splash(this);
public MyApp(){
}
public void startApp(){
try{
Display.init(this);
javax.microedition.lcdui.Display.getDisplay(this).setCurrent(splashScreen);
//and some more stuff
} catch (IOException ex){}
}
//continue