how can i access beginX & beginY to setBeginX & setBeginY.can i use setX() method for retrieving beginX & beginY
public class Line {
private Point begin;
private Point end;
public Line (Point begin, Point end) {
this.begin = begin;
this.end=end;
}
public Line (int beginX, int beginY, int endX, int endY) {
begin = new Point(beginX, beginY);
end =new Point(endX,endY);
}
public void setBeginX(int beginX) {
// how can i set beginX here.
}
public void setBeginY(int beginY) {
// how can i set beginY here.
}
Checking the API for Point (see https://docs.oracle.com/javase/7/docs/api/java/awt/Point.html) you can see that there is no setX() or setY() but there is:
setLocation(int x, int y)
Changes the point to have the specified
location. This method is included for completeness, to parallel the
setLocation method of Component. Its behavior is identical with
move(int, int).
The coordinates x and y are also public, meaning you could access them directly. You could technically do:
public void setBeginX(int beginX) {
this.begin.setLocation(beginX, this.begin.getY());
}
I would however recommend you change your own API perhaps to allow you to set both x and y at the same time.
If you are actually asking "how can I set beginX variable passed to the constructor", you can't without making it a member variable.
Related
I am working on 2D graphical optimal fitting project. I was coding in C++ and changed to Java, therefore I know the algorithm works. But I am having a problem with reaching elements of ArrayList outside of the scope of loop or more likely adding to an ArrayList.
I can reach to an element I want in this scope, but outside of this scope some elements are lost. I know this is irrelevant and probably something occurs beyond my attention.
Triangle Class:
public class Triangle implements Shape, Cloneable
{
private double length; // size of equaliteral triangle's each edge.
private double x,y;
private boolean rotate; // Flag for rotate by 90 degress around pos(x,y)
private boolean fill; // Flag for fill
private static double total_area = 0;
private static double total_perim = 0;
private int[] xPoints;
private int[] yPoints;
.
...
}
Definitions:
Triangle t2 = (Triangle)small;
Triangle t = (Triangle)t2.clone();
List<Shape> shape = new ArrayList<Shape>();
In the code below, I draw it as soon as I added it into the List. Method draw() does not matter in this case, it only uses fields such as x and y.
Code 1:
// (a,width-a*sqrt(3)) init for fill inside without rotating
for(y = r1.getHeight()-tri_height;y>=0;y-=tri_height)
{
x=t.getLength()/2.0;
while(x+t.getLength()/2.0<=r1.getWidth())
{
t.setPosition(x+_x,y+_y);
shape.add((Triangle)t.clone());
shape.get(size).draw(g); // check this line.
++size;
x+=t.getLength();
}
}
In this same piece of code, I only draw/print them after insertion is done.
Code 2:
// (a,width-a*sqrt(3)) init for fill inside without rotating
for(y = r1.getHeight()-tri_height;y>=0;y-=tri_height)
{
x=t.getLength()/2.0;
while(x+t.getLength()/2.0<=r1.getWidth())
{
t.setPosition(x+_x,y+_y);
shape.add((Triangle)t.clone());
x+=t.getLength();
}
}
for(Shape s:shape)
s.draw(g);
clone() method:
#Override
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
Output 1(Wrong)
Output 2(Expected)
I am only using draw() method to show the difference better. The problem is the elements are gone after the scope. Or I didn't achieve to add them properly. It shows me that last element I added instead of every element I appended. What am I missing in this case?
It seems that your problem is in Triangle.clone() method. You have references in Triangle, like int[] xPoints or int[] yPoints.
Defualt implementation of Object.clone() works only for simple types, but not for references.
Triangle t = (Triangle)t2.clone();
t.xPoints == t2.xPoints; // this is same array (not a copy)
All your rectangles are drawn on the same place.
How to solve
Do not use clone() method. In general it is outdated. You have to create like C++ copy constructor and manually create copy of your object.
public class Triangle implements Shape {
private static double total_area = 0;
private static double total_perim = 0;
private double length;
private double x,y;
private boolean rotate;
private boolean fill;
private int[] xPoints;
private int[] yPoints;
public Triangle(Triangle triangle) {
this.length = triangle.length;
this.x = triangle.x;
this.y = triangle.y;
this.rotate = triangle.rotate;
this.fill = triangle.fill;
this.xPoints = xPoints != null ? Arrays.copyOf(xPoints, xPoints.length) : null;
this.yPoints = yPoints != null ? Arrays.copyOf(yPoints, yPoints.length) : null;
}
}
P.S.
int[] xPoints: xPoints - is not an array, this is reference to the array of int.
int[] xPointsCopy = xPoints: xPointsCopy - this is another reference to the same array of int.
I am on my way to learning java, so please bear with me on this one, even if its very simple to you.
I'm working with two LinkedLists:
private LinkedList<BloodDonor> x;
private LinkedList<BloodDonor> y;
public List()
{
x = new LinkedList<>();
y = new LinkedList<>();
}
I have a method called heroDonors that searches the LinkedList x to see if there are any people who donated blood more than 50 times. If so, that donor gets added to LinkedList y and removed from LinkList x. If no donors who donated more than 50 times are present, an empty LinkedList of y is returned.
I need the LinkedList y to be returned by the method, but I get the error java.util.LinkedList<BloodDonor> cannot be converted to BloodDonor.
public BloodDonor heroDonors()
{
int donations = 50;
for (BloodDonor donor : x) {
int number = donor.getNumberOfDonations();
if (donations < number) {
y.add(donor);
x.remove(donor);
}
if (donations > number) {
}
}
return y;
}
Could anyone explain why I am getting this error?
If you want to return a List of BloodDonors you have to actually make your method of that type:
public LinkedList<BloodDonor> heroDonors() {
LinkedList<BloodDonor> result = new LinkedList<>();
...
return result;
}
BTW: I think in this case you should not use a field y but declare a local variable on order to avoid side effects. You might also consider returning the base type List<BloodDonor> instead, this will better allow to use another collection if needed (and I would never call a application class List).
Change
public BloodDonor heroDonors()
to
public List<BloodDonor> heroDonors()
Is there a way to reset a value of a static variable to their initial state? For example:
I have a lot of variables which holds score, speed, etc. All those variables are changing during the program execution. So when the user fails in a game, I would like to reset ALL variables to their initial state. Is there some way? Because i don't know if it is a good idea to do this manually for EACH variable in my program. for example:
static int SCORE = 0;
static float SPEED = 2.3f;
public void resetGame() {
SCORE = 0;
SPEED = 2.3;
}
Use an object, and set its initial state in the constructor:
public class GameSettings {
private int score = 0;
private float speed = 2.3F;
// methods omitted for brevity
}
...
public void resetGame() {
gameSettings = new GameSettings();
}
Also, please respect the Java naming conventions. ALL_CAPS is reserved for constants. Variables should be lowerCase.
Store the default values.
static final int DEFAULT_SCORE = 0;
static final float DEFAULT_SPEED =2.3;
static int SCORE = DEFAULT_SCORE;
static float SPEED = DEFAULT_SPEED;
public static void resetGame() {
SCORE = DEFAULT_SCORE;
SPEED = DEFAULT_SPEED;
}
Why not just recreate the object if you want it reset? Then it'll implicitly have the default values.
You could just declare your variables without values and have a method initGamestate() which sets all variables to their initial values. Call this function both on initialization of the application and when the user starts a new game.
A more object-oriented solution would be to have a class GameState which has all these variables and sets the default in its constructor. You then start every game by initializing a fresh object with new GameState();
You'll just have to reset them one by one. If you're worried about typos you could do: int initialscore = 0; int score = initialscore; and then reset them to the initial... variables in your function.
I have a lot of variables which holds score, speed, etc
You should put them all into one class and every member get initialsed (if the default won't work).
You will hold the player's state in one reference to an object of this class. To reset simply create a new object of this class and assign it to the reference.
Usually games use more than one thread (for example when using Swing or painting any graphics), e.g. so inputs are not blocked. That means with all the other solutions you might run into race conditions. This solution of Evan Knowles came closest.
I would suggest a immutable GameState class, e.g.
public GameState {
private final int score;
private final int speed;
// initial state/"reset game"
public GameState() {
score = 0;
speed = 2.3;
}
// Private so we are always in a valid state
private GameState(int _score, int _speed) {
score = _score;
speed = _speed;
}
public GameState updateSpeed(int _speed) { return new GameState(this.score, _speed); }
public GameState updateScore(int _score) { return new GameState(_score, this.speed); }
public int getSpeed() { return speed;}
public int getScore() { return score;}
// add getters, setters and whatsoever here. But watch for proper synchronization between threads!
}
The advantage here is that once the values are assigned, they can't be changed anymore ("immutable"/read-only) from the outside, so there are no concurrency issues. Plus, you get a sort of chaing for free (see below)! Moreover, you can safely (de-)serialize the game state for saving/loading games.
Effectively, each GameState represents one state in a finite state machine. Calling either updateSpeed or updateScore is a transition to a new state.
The public default constructor is a transition to the initial state of the state machine.
On a side note, the state machine is finite because the value ranges of score and speed are finite, thus all combiniations of them result in a finite amount of states.
I now assume your class for doing other game stuff is called Game.
public Game {
private volatile GameState gameState = new GameState();
public void resetGame() {
gameState = new GameState();
}
// Just an example
public increaseSpeed(int _additionalSpeed) {
gameState = gameState.updateSpeed(gameState.getSpeed() + _additionalSpeed);
}
// Change more than one value
public changeBoth(int _newSpeed, int _newScore) {
// First way: Create a new GameState, change both values step by step and then assign afterwards.
GameState _newState = gameState.updateScore(_newScore);
// other computations follow
// Do NOT assign to gameSpate here, because the state would be inconsistent then.
_newState = _newState.updateSpeed(_newSpeed);
// At the END of the method, assign the new game state. That ensures that the state is always valid
gameState = _newState;
// Second way: Use method chaining if you don't need to make other computations in between. Again, do this at the end of the method
gameState = gameState.updateScore(_newScore).updateSpeed(_newSpeed);
}
}
The volatile keyword makes sure every thread sees the same value of the gameState variable. You might want to consider using other synchronization/locking techniques instead, too. Alternatively you can make the gameState field static and skip the volatile keyword if you only have one Game object.
Because GameState is immutable(read-only), the state of your game now is always consistent/valid.
A good way is to use a static init() and call it when exception occurs.
package com.kvvssut.misc;
public class ResetStatic {
private static int SCORE = 0;
private static float SPEED = 2.3f;
private static void init() {
SCORE = 0;
SPEED = 2.3f;
}
public static void main(String[] args) {
SCORE = 100;
SPEED = 230.3f;
try {
throw new RuntimeException();
} catch (Exception e) {
init();
}
System.out.println(SCORE);
System.out.println(SPEED);
}
}
So this is a stupid dbeginner's question.
I wrote a function that checks if a specific game move is legal (Reversi). The function must only return a boolean true/false value.
Later, in a different function, I actually make the move (makeMove function). In this function, before making the move I call the isLegal function to make sure the move is legal.
Now, when the isLegal function decides the move is legal, it would help me to save the specific info that lead to the decision, and use it in the makeMove function. I have no ideah ow to do that. I tried writing a function that will store the relevant data, and then send it back, but there's an obvious provlem with scopes here.
So here's the relevant code from isLegal:
else if(board[k][l]==player){relevantDirection=false; isLegal=true; ReversiPlay.saveLegalMove(direction, k, l);}
Then the problematic saving function:
public static int[] saveLegalMove(int direction, int row, int column){
if(direction==0){ //get info from function
return legalMoveData;
}
else{ //save legal move data
int[] legalMoveData = new int[3];
legalMoveData[0]= direction;
legalMoveData[1]= row;
legalMoveData[2]= column;
return null;
}
}
And lastly, I try calling the stored data:
int[] getSavedInfo = ReversiPlay.saveLegalMove(0, 0, 0);
I'm sure there's a very simple way of pulling the variables direction+k+l... anyone?
Thanks!
Edit: Here's a clearer example:
public static boolean A(int a){
...calculations...
int x = [value]
int y = [value]
return false;}
public static void B(int a){
...calculations...
boolean h = A(3);
[here I'd like to know what x,y were]
}
else { //save legal move data
int[] legalMoveData = new int[3];
legalMoveData[0]= direction;
legalMoveData[1]= row;
legalMoveData[2]= column;
return null;
}
This part doesn't save anything. It stores the values to a local variable and returns null.
An approach would be to make a Move object that contains the data you need:
public class Move {
private int direction;
private int row;
private int column;
...
}
Your isLegal method would only tell you if the move is legal. Then you can use that same Move instance to make the move.
if(ReversiPlay.isLegalMove(move)) {
ReversiPlay.makeMove(move);
}
There is no need to explicitly save the move; you already have that information inside the Move object instance.
UPDATE
Based on your edit, perhaps it is better to return an object instead of a boolean from A:
public static boolean A(int a) {
...calculations...
int x = [value]
int y = [value]
return new MyObject(x, y, false);
}
...
MyObject myObject = A(someValue);
Then you can query myObject to see what the value of the flag is.
UPDATE
You mentioned you aren't allowed to use objects. If so, instead of making the same calculations however, you can extract that logic into its own method and then call that. That way you won't have to duplicate logic.
I have a class as follows:
public class Element extends Activity
{
public float mX;
public float mY;
public void animate(long elapsedTime)
{
mX += mSpeedX * (elapsedTime / 20f);
mY += mSpeedY * (elapsedTime / 20f);
setmX(mX);
setmY(mY);
checkBorders();
}
public void setmX(float mX)
{
Log.i("this.mX","mY at setmX read is :"+this.mX ); **//Line 1**
this.mX = mX;
}
public float getmX() {
Log.i("mX","mX in getmX read is :"+mX ); **//Line 2**
return mX;
}
public void setmY(float mY) {
this.mY = mY;
Log.i("this.mY","mY at setmY read is :"+this.mY ); **//Line 3**
}
public float getmY() {
Log.i("mY","mY in getY read is :"+mY ); **//Line 4**
return mY;
}
}
I have another class
public class Panel extends SurfaceView implements SurfaceHolder.Callback
{
int x = 100;
int y = 0;
public float xval;
public float yval;
#Override
public boolean onTouchEvent(MotionEvent event)
{
Element element = new Element();
float x = event.getX();
float y = event.getY();
Log.i("x","x in panel is :"+x);
//toast tos = new toast();
xval = element.getmX();
Log.i("xval","xval in playactivity obtained is :"+xval ); **//Line 5**
yval = element.getmY();
Log.i("yval","yval in playactivity obtained is :"+xval ); **//Line 6**
return super.onTouchEvent(event);
}
Lines 2, 4, 5, and 6 are showing values as zero. Which I don't want to. Below is the logcat image.
Have I made error in the access Specifiers?
You should not create an object of Activity class (in you class Element class) in another class. Please go through the Application fundamentals
Though you are creating an object of Element class in the Panel class, you never called setter method setmX() and setmY() to set the values. You are directly calling the getter methods which returns you the default values.
It's hard for us to tell what's going on without knowing mSpeedX and mSpeedY. Try casting both elapsedTime and your mSpeedX/Y variables to floats before doing the math. Floating point math is pretty picky in Java. Also ensure that the animate method is actually being called.
One final note, I probably shouldn't bring this up but it's killing me. You should really, really work on your code consistency and style. Your naming conventions, newline/sameline brace conventions, and indentation habits are all over the place. Code readability and maintainability go down dramatically if your programming style is not consistent.
One more thing: you don't need to call the setter methods after assigning values to a variable. You've already set the value of the very same variable that your set/get methods are accessing. Good luck!