How to use classes and methods in Java - class

I'm fairly new to Java and coding, but up until this point in the Java material, I haven't ran into any problems. What I really can't wrap my head around is how classes and methods actually work. I've been attempting to implement this over the last several hours to no avail:
Implement the class called Cylinder shown in UML below. The constructor accepts and initializes the radius and height for the Cylinder, while accessors and mutators allow them to be changed after object construction. The class also include methods that calculate and return the volume and surface area of the Cylinder. Lastly, it contains a toString method that returns the name of the shape, its radius, and its height. Create a main method which instantiates 4 Cylinder objects (any parameters), display them with toString(), change one parameter (your choice) in each, and display them again.
UML:
This is the code that I currently have:
class Cylinder {
private double radius;
private double height;
// Method #1
private void rad (){
}
// Constructor
public Cylinder (double radius, double height){
this.radius = radius;
this.height = height;
}
// Method #2 for calculating volume.
double calcVolume (){
double volume = Math.PI * Math.pow(radius, 2) * height;
return volume;
}
// Method #3 for calculating surface area.
double calcArea (){
double area = (2 * Math.PI * radius * height) + (2 * Math.PI * Math.pow(radius, 2));
return area;
}
// toString method.
public String toString (){
StringBuilder sb = new Stringbuilder();
sb.append(radius).append(height);
return sb.toString();
}
}
public class Murray_A03Q1 {
public static void main(String[] args) {
Cylinder cylinder1 = new Cylinder(5, "can");
System.out.println(cylinder1);
Cylinder cylinder2 = new Cylinder(6, "cup");
Cylinder cylinder3 = new Cylinder(7, "jar");
Cylinder cylinder4 = new Cylinder(8, "paper roll");
}
}
What I really don't understand is how to use the 'get' and 'set' methods. Additionally, I'm not completely sure how to implement the toString method.
The following errors that I can't figure out how to correct are:
The constructor Cylinder() is undefined for -
Cylinder cylinder1 = new Cylinder();
Stringbuilder can't be resolved to a type for -
StringBuilder sb = new Stringbuilder();
Thank you for your help!

What I really don't understand is how to use the 'get' and 'set' methods.
The purpose of getters and setters is for encapsulation. They allow you to get or set the values of the class' variables without having to declare them as being public.
For example, if you were to have
public double radius;
public double height;
You will be able to access them as
cylinder1.radius = 1;
cylinder2.height = 10;
int a = cylinder3.radius;
int b = cylinder3.height + cylinder4.radius;
etc.
Now if instead we had
private double radius;
private double height;
The above code will fail. Which is why we need getters and setters. As the names imply, getters "get" the variable.
public double getHeight() {
return height;
}
While setters "set" the variable.
public void setHeight(double height) {
this.height = height;
}
As for why we do it this way, theres a lot of information on that.
Additionally, I'm not completely sure how to implement the toString method.
As for how to implement the toString() method, all it has to do is return a String. But as for what the String contains, there is no hard rule for that. A good start would be to return the radius and height, like you have done.
The constructor Cylinder() is undefined for - Cylinder cylinder1 = new Cylinder();
Your constructor is public Cylinder (double radius, double height). However, you are trying to make a cylinder that's an int and a String.
Cylinder cylinder1 = new Cylinder(5, "can");
Either
Change the constructor to something like public Cylinder(double radius, String name); or
The instantiate your Cylinders with two doubles, a radius and a height.
e.g.
Cylinder cylinder1 = new Cylinder(1.0, 2.0);
Stringbuilder can't be resolved to a type for - StringBuilder sb = new Stringbuilder();
The only problem here is that you forgot to capitalize the b. It's StringBuilder not Stringbuilder.

An example of get and set methods:
double getRadius() {
return radius;
}
void setRadius(r) {
radius = r;
}
The constructor Cylinder() is undefined for - Cylinder cylinder1 = new
Cylinder();
Something is attempting to invoke the default constructor (a constructor with no parameters). You can either find out exactly where this error is called, or else add a default constructor:
Cylinder() {
this.radius = 0;
this.height = 0;
}
Stringbuilder can't be resolved to a type for - StringBuilder sb = new Stringbuilder();
StringBuilder is actually the class java.lang.StringBuilder. Place this text at the top of your file to help it resolve the name.
import java.lang.StringBuilder;

Related

How can i apply normalization on vector3/float3 values with a magnitude bigger than 1?

I am trying to have some algorithm which calculates custom gravity. In order for it to work the way i want i want to clamp my input vector to (-1,-1,-1) or (+1,+1,+1). If i use the normalize function it will turn into (0.6,0.6,0.6). I cannot just clamp this or the vector orientation would change.
My question is - Is there a builtin function to do is? Or do i need to just do the normalization math by myself?
I don't think there's a built-in function for it.
Here's an idea of how to write one as an extension method:
public static class VectorX {
public static Vector3 SquareNormalize (this Vector3 vector) {
var bounds = new Bounds(Vector3.zero, Vector3.one * 2f);
return bounds.ClosestPoint(vector);
}
}
And to use it call:
myVector.SquareNormalize();
I did it like this:
using Unity.Mathematics;
using static Unity.Mathematics.math;
public static class CustomMathHelper
{
public static float3 ClampNormalize(float3 value, float normalizeLimit)
{
var maxValue = max(abs(value.x), max(abs(value.y), abs(value.z)));
if (maxValue > abs(normalizeLimit))
{
var factor = (1 / maxValue) * abs(normalizeLimit);
return new float3(factor * value.x, factor * value.y, factor * value.z);
}
return value;
}
}
leaving question unresolved in case someone runs into a framework method that does this already

Align variables horizontally in unity inspector

I'm writing a very simple class for storing data (at least, for now) for use in a Unity project to do with a learning AI. I want to be able to easily customize multiple agents in the inspector and the number of checkboxes stacked vertically makes this part of my project dominate the inspector. If I could simply have one section make use of the ample empty space on the right side of the inspector, that would be considerably less ugly.
I've been reading a lot about custom property drawers and inspector windows, but it seems like a lot of work, involving rewriting how the entire class is displayed, for one change.
For reference, here is the class itself.
[System.Serializable]
public class NNInfo
{
public string networkName = "Agent";
[Header("Movement Properties")]
public float movementSpeed = 10f;
public float rotationSpeed = 1f;
[Header("Learning Properties")]
public float learningRate = 0.1f;
public float momentum = 0f;
public Rewards rewardFunc;
public int[] hiddenLayers;
[Header("Other Properties")]
public int maxHealth = 1000;
[Header("Optional Inputs")]
public bool m_PointToNearestBall = false; // input which is 1 while the agent is facing a ball and -1 when facing away
public bool m_DistanceToNearestBall = false; // input which is 1 while the agent is at the ball and -1 when at max possible distance away
public bool m_PointToEndzone = false; // similar to m_PointToNearestBall but for the endzone
public bool m_Position = false; // two inputs which inform the player of its normalized x and y coordinates on the field
public bool m_WhetherHoldingBall = false; // tells the player whether its holding a ball
public bool m_CanSeeHealth = false; // Whether the player can know its own health
[Header("Optional Outputs")]
public bool m_ForwardLeft = false; // turn left and move forward simultaneously
public bool m_ForwardRight = false; // turn right and move forward simultaneously
public bool m_Reverse = false; // move backwards
public bool m_Flip = false; // instantly switch to opposite direction
public bool m_TurnToBall = false; // instantly turn to face nearest ball
public bool m_TurnToLeft = false; // instantly turn to face left side of field
public bool m_Attack = false; // attack a player (or idle if no contact)
}
Custom Property Drawer is keyword which should be interesting for you.
Writing your own code for managing those - lets you describe how you want to show your properties inside Inspector View in Unity editor.
To start, go to official documentation site, which contains code you can base on.
Code snippets (Javacrpt, c# version can be found under the link):
Object's code:
enum IngredientUnit { Spoon, Cup, Bowl, Piece }
// Custom serializable class
class Ingredient extends System.Object {
var name : String;
var amount : int = 1;
var unit : IngredientUnit;
}
var potionResult : Ingredient;
var potionIngredients : Ingredient[];
function Update () {
// Update logic here...
}
Editor code:
#CustomPropertyDrawer(Ingredient)
class IngredientDrawer extends PropertyDrawer {
// Draw the property inside the given rect
function OnGUI (position : Rect, property : SerializedProperty, label : GUIContent) {
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty (position, label, property);
// Draw label
position = EditorGUI.PrefixLabel (position, GUIUtility.GetControlID (FocusType.Passive), label);
// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Calculate rects
var amountRect = new Rect (position.x, position.y, 30, position.height);
var unitRect = new Rect (position.x+35, position.y, 50, position.height);
var nameRect = new Rect (position.x+90, position.y, position.width-90, position.height);
// Draw fields - passs GUIContent.none to each so they are drawn without labels
EditorGUI.PropertyField (amountRect, property.FindPropertyRelative ("amount"), GUIContent.none);
EditorGUI.PropertyField (unitRect, property.FindPropertyRelative ("unit"), GUIContent.none);
EditorGUI.PropertyField (nameRect, property.FindPropertyRelative ("name"), GUIContent.none);
// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty ();
}
}

Circle class definition compiling with static error

I followed step by step with how we did this in class, yet when I try to compile I get the follow error:
error: non-static variable this cannot be referenced from a static context.
The line under questioning is
cir1 = new Circle();
and
cir2 = new Circle();
I understand what the error means I am just having difficulty seeing what my mistake was because it is the exact same as what we did in class (or so I thought..)
public class CircleDemo{
public static void main(String[] args){
Circle cir1, cir2;
cir1 = new Circle();
cir2 = new Circle();
cir1.setRadius(3.0);
cir2.setRadius(11.01);
System.out.println("Area of the first circle: " + cir1.findArea());
System.out.println("Circumference of the first circle: " + cir1.findCircumference());
System.out.println("Area of the second circle: " + cir2.findArea());
System.out.println("Circumference of the second circle: " + cir2.findCircumference());
}
public class Circle{
//Instance Variables
private double PI = 3.1459;
private double radius;
//Methods
public Circle ( ) { }
//get method (Accessor Methods )
public double getRadius ( ) {
return radius;
}
//set method (Mutator Methods)
public void setRadius (double r) {
radius=r;
}
public double findArea ( ) {
return PI*radius*radius; //area= pi r squared
}
public double findCircumference ( ) {
return 2 * PI * radius;
}
}//end Circle
}
If anyone could help me understand what I did wrong it would be greatly appreciated! Thanks.
It seems to be a simple bracket error. And perhaps a misuse of the keyword "public" in the Circle class definition. Here is the revised code:
public class CircleDemo {
public static void main(String[] args){
Circle cir1, cir2;
cir1 = new Circle();
cir2 = new Circle();
cir1.setRadius(3.0);
cir2.setRadius(11.01);
System.out.println("Area of the first circle: " + cir1.findArea());
System.out.println("Circumference of the first circle: " + cir1.findCircumference());
System.out.println("Area of the second circle: " + cir2.findArea());
System.out.println("Circumference of the second circle: " + cir2.findCircumference());
} //Added this bracket
}
class Circle { //removed the word "public" I'll this explain below
//Instance Variables
private double PI = 3.1459;
private double radius;
//Methods
public Circle () {}
//get method (Accessor Methods )
public double getRadius ( ) {
return radius;
}
//set method (Mutator Methods)
public void setRadius (double r) {
radius=r;
}
public double findArea ( ) {
return PI*radius*radius; //area= pi r squared
}
public double findCircumference ( ) {
return 2 * PI * radius;
}
} //Removed an extra bracket here
Some incorrect brackets were causing the error. Also, if the Circle class is defined in the same file as the CircleDemo class, then the Circle class must not be defined as "public", as this causes an error. If the Circle class is defined in it's own file, then it can be "public". I tested this to ensure it works.

Is there any way to find a string's position and click on it using robotium?

I have the following list appearing on UI of an android application which tells about the date and the temperature on that date.
temp degree
11/01 --.-- c
11/02 21.7 c
11/03 22.5 c
Here I want to find the position of string "--.--" and then click on it, so that I can update the list. Is there any way to find the position of string? I know that solo.searchText() will tell whether the string is present or not, but what about the position?
// i think it will help you
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
// TODO Auto-generated method stub
if(yourliststring.trim().equals("--.--"))
{
//your condition
}
else
{
//your condition
}
}
});
I got a simple way to find and click on the string
if(solo.searchText("--.--")){
solo.clickLongOnText("--.--");
}
All I need is to click on the string "--.--".
I'm not sure what position you need, however if you need position on screen you can simple do:
TextView textView = solo.getText("--.--"); // or solo.getText(Pattern.quote("--.--")); if needed
int[] xy = new int[2];
textView.getLocationOnScreen(xy);
final int viewWidth = textView.getWidth();
final int viewHeight = textView.getHeight();
final float x = xy[0] + (viewWidth / 2.0f);
final float y = xy[1] + (viewHeight / 2.0f);
this way you have central point of view (x, y).
If you need position of text in list, you can do:
private int getPosition(ListView listView, String text) {
for (int i = 0; i < listView.getAdapter().getCount(); i++) {
Object o = listView.getAdapter.getItemAtPosition(i);
if (o instanceof TextView) {
if (((TextView)o).getText().toString().equals(text)) {
return i;
}
}
}
return -1; // not found
}
you can call it for instance this way (set proper parameters):
int position = getPosition((ListView) solo.getView(ListView.class, 0), "--.--");
Everything written without testing and even compiling, however main idea should be fine.

Custom ProgressBar widget

I am trying to do something similar to this but in Android.
In Android I can extend the ProgressBar but I am doubting of how to add the TextViews on top. In iphone it was easy because I can use absolute positions, but not here.
Any ideas?
EDIT:
I decided to use SeekBar instead of ProgressBar to add the thumb drawable. I commented below. Some points to notice:
I am using hardcoded values, actually three but it can be more or less.
When the thumb is moved it moves to 50 but it should move to the different options.
I am using pixels instead of dpi. I should fix that.
I need to solve the lack of animation when the thumb moves.
My progress so far:
public class SliderFrameLayout extends FrameLayout implements OnSeekBarChangeListener {
private SeekBar mSlider;
private Context mContext;
private int mSize = 3;
private TextView[] mTextViews;
private String[] mTexts = {"Nafta", "Gas", "Gasoil"};
public SliderFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setWillNotDraw(false);
mTextViews = new TextView[mSize];
addSlider();
addTextViews();
}
private void addTextViews() {
for ( int i=0 ; i < mSize ; i++ ) {
TextView tv;
tv = new TextView(mContext);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
tv.setText(mTexts[i]);
mTextViews[i] = tv;
addView(tv);
}
}
private void addSlider() {
FrameLayout fl = new FrameLayout(mContext, null);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
fl.setLayoutParams(params);
fl.setPadding(30, 30, 30, 0);
mSlider = new SeekBar(mContext, null);
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
//lp.setMargins(30, 30, 30, 0);
//mSlider.setPadding(30, 30, 30, 0);
mSlider.setLayoutParams(lp);
//mSlider.setMax(mSize-1);
mSlider.setThumbOffset(30);
//mSlider.setProgressDrawable(mContext.getResources().getDrawable(R.drawable.slider_track));
//mSlider.setThumb(mContext.getResources().getDrawable(R.drawable.slider_thumb));
mSlider.setOnSeekBarChangeListener(this);
//addView(mSlider);
fl.addView(mSlider);
addView(fl);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rectf = new Rect();
mSlider.getLocalVisibleRect(rectf);
Log.d("WIDTH :",String.valueOf(rectf.width()));
Log.d("HEIGHT :",String.valueOf(rectf.height()));
Log.d("left :",String.valueOf(rectf.left));
Log.d("right :",String.valueOf(rectf.right));
Log.d("top :",String.valueOf(rectf.top));
Log.d("bottom :",String.valueOf(rectf.bottom));
int sliderWidth = mSlider.getWidth();
int padding = sliderWidth / (mSize-1);
for ( int i=0 ; i < mSize ; i++ ) {
TextView tv = mTextViews[i];
tv.setPadding(i* padding, 0, 0, 0);
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.d("SEEK", "value: " + seekBar.getProgress());
seekBar.setProgress(50);
}
}
You're already overriding onDraw, why not just draw the text strings yourself? Rather than go through the overhead of adding TextViews and messing with the padding, just use canvas.drawText to physically draw the text strings in the right place.
You can specify the style and color of the text using a Paint object:
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(r.getColor(R.color.text_color));
textPaint.setFakeBoldText(true);
textPaint.setSubpixelText(true);
textPaint.setTextAlign(Align.LEFT);
And get the exact positioning by using the measureText method on that Paint object to find what width a particular string would be when drawn on a canvas:
textWidth = (int)textPaint.measureText(mTexts[i]);
Then you can iterate over your array of text strings and draw each string in the right place.
#Override
protected void onDraw(Canvas canvas) {
int myWidth = getMeasuredWidth()-LEFT_PADDING-RIGHT_PADDING;
int separation = myWidth / (mSize-1);
for (int i = 0; i++; i < mSize) {
int textWidth = (int)textPaint.measureText(mTexts[i]);
canvas.drawText(mTexts[i],
LEFT_PADDING+(i*separation)-(int)(textWidth/2),
TOP_PADDING,
textPaint);
}
}
You'll probably want to do the measurements in onMeasure instead of onDraw, and you should probably only measure the width of each string when you change the text or the paint, but I've put it all in one place to (hopefully) make it easier to follow.
Just a try. You could put your custom progressBar inside a FrameLayout then, inside this layout, you have to add three TextViews with fill_parent as width.
Then you can align the three texts in this way: left, center and right. Your texts shouldn't overwrite and you can adjust a little their position using margins.
You can use this... not exact what you looking for... but really easy to set up and customize...
You can set the TextViews to have:
android:layout_width="0dp"
android:layout_weight="1"
This will let the android framework take care of the placing of the TextViews and save you from manually calculating the padding of each one.