I'm working on a homework project for an intro to java course. To practice calling methods and organizing tasks, we have to create two balloon objects s1 and s2 and modify their colors and altitudes using methods in a separate java class.
I have everything working fine, but not exactly to the requirements of the assignment. The sheet lists the method declarations and they cannot be changed, only the code within them can.
The method that is used to change a balloon's color is to be created as public void setColor(). This doesn't make sense to me, though. I'm using public void setColor(String color) for now.
How can I change the color property of a balloon object without passing anything to the setColor method?
I totally agree with #RealSkeptic but as your question says that changing the color without passing any value it means you need to generate the color each time your could use the following code. I'm not sure do this code is what you need.
public void setColor()
{
int red,green,blue;
red = green = blue = 0;
Random random = new Random();
int high = 255, low = 0;
red = random.nextInt(high-low)+low;
green = random.nextInt(high-low)+low;
blue = random.nextInt(high-low)+low;
color = new Color(red,green,blue);
//set this color to your balloon
}
Well, you can't specify any particular color without a parameter in the method. You can hardcode so that the color changes.
class Baloon {
private String[] colors = {"blue", "red" , "green"};
private int index = 0;
private String currentColor = colors[index];
public void setColor(){
index ++;
if (index = colors.length)
index = 0;
currentColor = colors[index];
}
}
Related
I wish to create an array of all the Colors predefined in java.awt.Color in order to randomly select one of them.
My current best attempt is:
` Color[] colors = Color.getClass().getEnumConstants();
which was suggested in the top answer to the question: Color Class in Java
but that generates the error:
Cannot make a static reference to the non-static method getClass() from the type Object
The constructor in which the erroneous call is made is below:
private Ball() {
Random initialSetter = new Random();
ballX = marginSize + initialSetter.nextInt(xSize - 2 * marginSize);
ballY = marginSize + initialSetter.nextInt(ySize - 2 * marginSize);
ballXV = initialSetter.nextInt(doubleMaxV) - doubleMaxV/2;
ballYV = initialSetter.nextInt(doubleMaxV) - doubleMaxV/2;
Color[] colors = Color.getClass().getEnumConstants();
color = colors[initialSetter.nextInt(colors.length)];
}
Replacing ".getClass().getEnumConstants()" with ".values()" generates much the same error (static reference to non-static method).
To fix your immediate error, you can do:
Color[] colors = Color.class.getEnumConstants();
But this only works if Color is an enum. According to your comments, Color refers to java.awt.Color, which is not an enum. The first way suggested by the linked answer is quite incorrect (Maybe it was 6 years ago?).
As far as I know, the best thing you can do here is to list them all out. There's not much - only 13. It's not like this number is going to change any time soon, as AWT is pretty old, they are unlikely to add new colours in at this stage.
For fun (this is only for fun), you can do it with reflection:
List<Color> colors = Arrays.stream(Color.class.getFields())
// fields of type Color, and in all caps, snake case
.filter(x -> x.getType() == Color.class && x.getName().matches("[A-Z_]+"))
.map(x -> {
try {
return (Color)x.get(null);
} catch (IllegalAccessException e) {
e.printStackTrace();
return Color.BLACK;
}
}).collect(Collectors.toList());
Note that reflection is really slow though, which is why your best choice is to hardcode it.
So far i tried so many different things to make this work. I can't seem to understand why this shouldn't work.
I have a class called StatusRect.java.
This class returns a rectangle when a new object is being made with the method makeRectangleStatus.
The idea is to color this rectangle every time an integer becomes a certain value.
In the class StatusRect.java the method changeIntFlag is invoked from another class. Here the integer is being changed. That works.
Now I just want the color of the rectangle to change in this StatusRect.java class.
The main question is actually can this color be set inside this StatusRect.java class, or can it only be done outside this class?
The rectangle object is being made in the Stage of the application like below. There the color red is given as a parameter.
Any help here is greatly appreciated.
public void start(Stage stage) throws Exception {
Rectangle rec = new StatusRect().makeRectangleStatus(50, 700, 20, 20, "red", "black", "btnObj1", 7, 0);
}
StatusRect class:
public class StatusRect {
private String ColorStatusOn;
private String ColorStatusOff;
private int IntFlag;
Rectangle rec = new Rectangle();
public Rectangle makeRectangleStatus (double x, double y, double Witdh, double Height, String ColorStatOn, String ColorStatOff, String BtnId, int SetIntStatus, int Current){
rec.setLayoutX(x);
rec.setLayoutY(y);
rec.setWidth(Witdh);
rec.setHeight(Height);
ColorStatusOn = ColorStatOn;
return rec;
}
public void changeIntFlag(int iEnabled) {
if(IntFlag == iEnabled) return;
IntFlag = iEnabled;
System.out.println("VALUE CHANGED!!!: " + IntFlag);
if (IntFlag == 7){
//this is being triggerd every time the int Flag value becomes "7"
System.out.println("SAME NUMBER: SET COLOR RECTANGLE TO red");
//Why doesnt the color change here??
rec.setStyle("-fx-fill:" + ColorStatusOn);
}
}
}
}
You can change your makeRectangleStatus method (and if it is necessary your Rectangle class adding some setters/getters) and set the colour of this.rec directly inside makeRectangleStatus. For instance, if you want that your Rectangle instance goes to ColorStatOn string, try this:
public void makeRectangleStatus (double x, double y, double Witdh, double Height, String ColorStatOn, String ColorStatOff, String BtnId, int SetIntStatus, int Current){
rec.setLayoutX(x);
rec.setLayoutY(y);
rec.setWidth(Witdh);
rec.setHeight(Height);
rec.setColorStatOn(ColorStatOn);
}
Besides pay attention: you don't need to return anything in makeRectangleStatus since you are using this.rec object.
What I noticed is that all the changes of styles from objects, rectangles buttons,etc work with events. Like action event, move, touch etc.
So when an action is true then something is changed. Just making a set method and setting a value doesnt do anything. You have to evaluate the value and add for example a changeproperty listener to it. Like with a slider, when the value of the property of the slider changes, and binding it. Objects are created only once.
I tried to do this like below. I understood that the method called "changed" is invoked when the value of the property changes, but sadly that doesnt work.
I think this is the way it should work, but Iam no expert.
IntegerProperty currentvalue = new SimpleIntegerProperty(IntFlag);
currentvalue.addListener(new ChangeListener<Number>(){
#Override
public void changed(ObservableValue <? extends Number>
observableValue, Number oldValue, Number newValue){
System.out.println("CHANGED, LISTENER TRIGGERD!!!!" +newValue);
}
});
I have a question regarding the awt Color class in Java.
I am currently using the class abbreviations such as Color.RED and Color.BLACK. I also have a list of three integers such as the following:
int var1 = 0
int var2 = 0
int var3 = 255
Is there a method to convert these integers into the appropriate Java Color name?
There is no way to do this with a single method in the Java core classes. However, you can fairly easily do this yourself in two ways.
First way
First, create a HashMap of Colors that contains all the colors you want:
HashMap<Color, String> colors = new HashMap<Color, String>();
colors.put(Color.BLACK, "BLACK");
colors.put(Color.BLUE, "BLUE");
colors.put(Color.CYAN, "CYAN");
colors.put(Color.DARK_GRAY, "DARK_GRAY");
colors.put(Color.GRAY, "GRAY");
colors.put(Color.GREEN, "GREEN");
colors.put(Color.LIGHT_GRAY, "LIGHT_GRAY");
colors.put(Color.MAGENTA, "MAGENTA");
colors.put(Color.ORANGE, "ORANGE");
colors.put(Color.PINK, "PINK");
colors.put(Color.RED, "RED");
colors.put(Color.WHITE, "WHITE");
colors.put(new Color(192, 0, 255), "PURPLE");
colors.put(new Color(0xBADA55), "BADASS_GREEN");
colors.put(new Color(0, 0, 128), "DARK_BLUE");
Then, create a new Color out of the RGB values you have:
Color color = new Color(var1, var2, var3);
Last, get the value in colors for the key color:
String colorName = colors.get(color);
Second way
This is potentially a less brittle way, but does have issues, and doesn't work as-is. You'll need to catch some exceptions, and maybe handle the case where a field isn't static and you can't just do f.get(null).
Create a new Color out of the RGB values you have:
Color color = new Color(var1, var2, var3);
Then
Get the Class object from the Color class with getClass().
Get the fields from that with getDeclaredFields().
Stream it using Arrays.stream()
Filter it by calling filter(), so it only contains all the enum constants that equal the color you made (there should be either one or zero).
Use toArray() to turn the stream into an array.
Get the first element of that array with [0]. This will throw an ArrayIndexOutOfBoundsException if there isn't a predefined color matching your color.
Get the name of that color with Enum's toString().
String colorName = Arrays.stream(Color.getClass().getDeclaredFields())
.filter(f -> f.get(null).equals(color))
.toArray()[0]
.toString();
There is no set function for this kind of behavior, but you could do something like this:
public static String getColorName(int r, int g, int b) {
String[] colorNames = new String[] {
"BLACK",
"BLUE",
"GREEN",
"CYAN",
"DARK_GRAY",
"GRAY",
"LIGHT_GRAY",
"MAGENTA",
"ORANGE",
"PINK",
"RED",
"WHITE",
"YELLOW"
};
Color userProvidedColor = new Color(r,g,b);
Color color;
Field field;
for (String colorName : colorNames) {
try {
field = Class.forName("java.awt.Color").getField(colorName);
color = (Color)field.get(null);
if (color.equals(userProvidedColor)) {
return colorName; // Or maybe return colorName.toLowerCase() for aesthetics
}
} catch (Exception e) {
}
}
Color someOtherCustomDefinedColorMaybePurple = new Color(128,0,128);
if (someOtherCustomDefinedColorMaybePurple.equals(userProvidedColor)) {
return "Purple";
}
return "Undefined";
}
There are a few options from here as well, maybe you want the nearest color? In which case you could try and resolve the distance somehow (here by distance from each r,g,b coordinate, admittedly not the best method but simple enough for this example, this wiki page has a good discussion on more rigorous methods)
// ...
String minColorName = "";
float minColorDistance = 10000000;
float thisColorDistance = -1;
for (String colorName : colorNames) {
try {
field = Class.forName("java.awt.Color").getField(colorName);
color = (Color)field.get(null);
thisColorDistance = ( Math.abs(color.red - userProvidedColor.red) + Math.abs(color.green - userProvidedColor.green) + Math.abs(color.blue - userProvidedColor.blue) );
if (thisColorDistance < minColorDistance) {
minColorName = colorName;
minColorDistance = thisColorDistance;
}
} catch (Exception e) {
// exception that should only be raised in the case color name is not defined, which shouldnt happen
}
}
if (minColorName.length > 0) {
return minColorName;
}
// Tests on other custom defined colors
This should outline how you would be able to compare to the built in colors from the Color library. You could use a Map to expand the functionality further to allow for you to define as many custom colors as you like (Something #TheGuywithTheHat suggests as well) which gives you more control over the return names of matched colors, and allows for you to go by more colors than just the predefined ones:
HashMap<String,Color> colorMap = new HashMap<String,Color>();
colorMap.put("Red",Color.RED);
colorMap.put("Purple",new Color(128,0,128));
colorMap.put("Some crazy name for a color", new Color(50,199,173));
// etc ...
String colorName;
Color color;
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
colorName = entry.getKey();
color= entry.getValue();
// Testing against users color
}
As far as i know, we don't have any such library to directly access the colors from the Constants.
But we can manage do it using Hex Color Library in Java.
References :
Hex
Color Class
Without any helping libraries I would say: No. Especially because not every RGB-Color has a specific name. However, you could of course build an own function, which tries to match some of the available colors and deliver something like "Unknown" if there is no match.
The matching attempt could theoretically be done using the Java reflection API...
OK, I'm in the process of making a simple java swing chess game. This question is more about OOP design then Java Swing.
I have the following:
I have a Panel class that implements JPanel.
I then have an abstract class Piece that extends from my Panel class
Then I have my classes for the different Pieces: Pawn, King, Bishop etc that extend from my Pieces class
In my main ChessGame Class:
I am using an array of Panel to store the layout of my board
So the array will store, Panel objects, for board places with no pieces on it.
And it will store, the subclasses such as Pawn, Queen, Bishop etc (board places with pieces)
So, the top left square (0,0) maps to myArray[0][0]
My problem is that, to check if the place is empty or has chess pieces in it I have to use:
if(panels[x][y] instanceof Piece){
((Piece)panels[x][y]).makeMove();
}
What I'm asking is this terrible design? I know I should try and stay away from instanceof.
What would be a better approach?
Thanks.
You shouldn't combine the Model code (Piece) with the view code (JPanels). If you ever want to change how the board is displayed you have to change how pieces are stored!
A better design might be to separate Piece from JPanels. Then you can use a single JPanel to display a matrix of Pieces : Pieces[8][8].
My problem is that, to check if the place is empty or has chess pieces in it I have to use:
If you use a matrix, you can just have a null cell or use the Null Object Pattern to have an "empty" piece.
EDIT
Each cell in the piece matrix is a square in the board so piece[0][0] would be the top corner of the board (A8).
To paint the board your paintComponent() method would have to iterate over this matrix and draw each cell appropriately. There are several ways to implement this:
You would need to do a similar instanceof check to draw each type of piece differently
Make a new intermediate "paint strategy" object using the strategy pattern. This may require a matrix of strategy objects instead of piece objects. You may still need to do instance of checks, but maybe only the once to create the strategy objects.
After considering your problem, and knowing the problem domain, I would actually suggest the following...
In your class Panel implement a function int hasMass() as follows...
public int hasMass() {
return 0;
}
In your class Piece override that function as follows...
public int hasMass() {
if (isWhite()) // white pieces are negative.
return -1;
return 1; // black pieces positive.
}
Now you can check if the square has a piece, whether another given piece could take it... (because they have opposite polarity)... e.g. mass + mass == 0 means a capture, != 0 means the panel was empty. And of course an absolute value of 2 (for mass) would mean the move was illegal.
OK, ill start by throwing away the option of setting null to indicate that place is empty (you can do it ofc but using the Empty class is just 'better' in a way).
So let's say you have array of Panels representing your game board:
Panel[][] board;
Now for ilustration, how your class hierarchy could look like:
abstract class Panel extends JPanel { ... }
class Empty extends Panel { ... }
abstract class Piece extends Panel { ... }
class Pawn extends Piece { ... }
...
My Panel class is my Empty class is it not?
Not sure if i understand you, but let's have a look on what extends means exactly: in the show nmodel every Piece is also a Panel or every Pawn is also a Piece, so every Pawn can do all the same things as Piece (for example, 4 is complex number as well as natural number or real number, so in a way, you could say that real numbers extend complex numbers, since every real number is also a complex number)
So now you can have some nice abstract getTexture() method declared in Panel implemenented in Empty class and in all Piece subclasses, and when drawing a Panel, you dont need to look if it is empty or not.
Instead of creating (I assume) almost identical classes for each piece (Rook, Pawn, Queen etc.), you could just keep the original Piece class, make it non abstract and add a PieceType field to it. PieceType is just an enum that tells what type of piece (if any) is placed there. Instead of using instanceof, now you can check using panels[i][j].getType() == PieceType.ROOK. At least that's what I'm doing in my implementation :)
I'm also using JLabel instead of JPanel for my 8x8 board.
Instead of splitting panel to 8x8 smaller panels, you must draw the board and the pieces on a canvas. Later the players will eventually be dragging to move pieces on board. Also you could look for Bitboard presentation in chess game, although this presentation is only required for chess engines which are able to "think" for fast calculations, it is still useful when you have to check if the move that player is trying to make is correct.
Posible Bitboard:
public class BitBoard
{
public static final int P = 0;
public static final int N = 2;
public static final int B = 4;
public static final int R = 6;
public static final int Q = 8;
public static final int K = 10;
public static final int p = 1;
public static final int n = 3;
public static final int b = 5;
public static final int r = 7;
public static final int q = 9;
public static final int k = 11;
// empty field
public static final int empty = 12;
// number of pieces , squares
public static final int nPieces = 12;
public static final int nSquares = 64;
public static final int whitePieces = 12;
public static final int blackPieces = 13;
public static final int nBoards = 14;
public static long squareBits[];
// static member initialization
static
{
squareBits = new long[64];
long square = 1;
square = square << 8 * 8 - 1;
for (int i = 0; i < 64; i++) {
squareBits[i] = square >>> i;
}
}
long bitBoards[];
public BitBoard() {
bitBoards = new long[nBoards];
}
public boolean initBoard()
{
// Put the pieces on the board
EmptyBoard();
addPiece(0, r);
addPiece(1, n);
addPiece(2, b);
addPiece(3, q);
addPiece(4, k);
addPiece(5, b);
addPiece(6, n);
addPiece(7, r);
for (int i = 8; i < 16; i++) {
addPiece(i, p);
}
for (int i = 48; i < 56; i++) {
addPiece(i, P);
}
addPiece(56, R);
addPiece(57, N);
addPiece(58, B);
addPiece(59, Q);
addPiece(60, K);
addPiece(61, B);
addPiece(62, N);
addPiece(63, R);
return true;
}
public boolean addPiece(int whichSquare, int whichPiece)
{
bitBoards[whichPiece] |= squareBits[whichSquare];
bitBoards[nPieces + (whichPiece % 2)] |= squareBits[whichSquare];
return true;
}
private boolean removePiece(int whichSquare, int whichPiece)
{
bitBoards[whichPiece] ^= squareBits[whichSquare];
bitBoards[nPieces + (whichPiece % 2)] ^= squareBits[whichSquare];
return true;
}
private boolean EmptyBoard()
{
for (int i = 0; i < nBoards; i++)
{
bitBoards[i] = 0;
}
return true;
}
}
I would keep a structure of the pieces separate from the rendered board.
For example, I would make the chess pieces pure models w/o knowledge of hit they're rendered.
Pieces (baseclass)
+- Pawn
+- Knight
+- King
+- Queen
+- ..etc
This will allow you to keep an array of Pieces only, where empty squares are null.
For simplicity sake, I'd just have a matrix of peices:
Peices[][] board = new Pieces[8][8];
(of course an initialization method to traverse your 'board' and populate the board w/ the initial positions)
I would then have a visible board constructed of JPanels; a class called "Chess" to manage game; and the actual rendering of the tile/panel in the move function. Imagine:
// what a move might look like when initializing your panels
piece = board [0][0];
Chess.move(piece, 0 ,0); //responsible for clearing the old panel and rendering the panel at target location.
When the user interacts w/ your game..they click your panels..which will give you the panel coordinates. You use the same coordinates w/ your 'board' to determine what the piece is..how it can move etc..
Something like that...
I would just represent the game board using objects...for simplicity. Easiest to understand..and besides..computers are plenty fast now.
So I have been studying Java for about 8 weeks and for class I had to design a shape guessing game. Yes it is Homework. So I have built my four shape classes with an example of one below.
public class square extends shape {
//square member variables
boolean equalSides = true;
// check if sides are equal
public boolean isEqual() {
return equalSides;
}
//constructor
public square(int numsides, String shapeName, boolean b, String shapehint) {
super(numsides, shapeName, shapehint);
}
}
I then created a shape.java class
public class shape {
int numSides;
String shapeName;
String shapeHint;
public shape(int numsides, String shapename, String shapehint) {
numSides = numsides;
shapename = shapeName;
shapehint = shapeHint;
}
//getter methods
public int getSides() {
return numSides;
}
public String getName(){
return shapeName;
}
public String getHint(){
return shapeHint;
}
}
It's now that I have reached the shapeGuesser class that I am starting to struggle just a little. I'm unsure how to incorporate a guard for my game and the JOptionPane side of it. I need shapeGuesser to run until the user guesses the correct shape.
I have been instructed to present the user with this option at the start.
What question shall I ask?
Enter Number:
1.How many sides?
2.Are your sides the same length?
3. Hint
Based on the number you enter 1, 2 or 3.That question will be asked of that
shape. So your Shape must have an appropriate response ready.
import javax.swing.JOptionPane;
import java.util.Random;
public class shapeGuesser {
public static void main(String[] args, Object Do) {
// TODO Auto-generated method stub
// the shape the program uses
int random;
shape shapeChoice;
// create shapes
square s = new
square(4, "Square", true, "Geeks were called this in the 80s");
Rectangle r = new Rectangle(4, "Rectangle", false, "Not Pentangle");
Triangle t = new Triangle(3, "Triangle",false, "Toblerone");
Circle c = new Circle(0, "Circle",true, "Circle Circle Circle");
//declare shape array
shape[] Shapes;
//create shape array
Shapes = new shape[4];
//put shape objects in shape array
Shapes[0] = s;
Shapes[1] = r;
Shapes[2] = t;
Shapes[3] = c;
// generate random number
random = (int) (1 + (Math.random() * 3));
//pick shape from shape array based on random number
shapeChoice = Shapes[random];
}
}
Anyone who read this far and might have the time to enlighten me in anyway. It would be much appreciated.
Thanks,
isEqual() needs an implementation in the base class, shape, as with all methods you want to call on all your shapes. Have the base shape return false. (Ideally shape should be abstract so you can't have a basic shape object, only squares, rectangles, etc. but its okay, you're new, and nobody else will use this. So you yourself can just never create a base shape. But for the future, that's what abstract is for ^^) Then, have all your other shapes override that base isEqual() the way your square already does.
You're doing good! You've selected a random shape, and created many shapes.
Now create a loop that prints the options,
system.out.println("Enter Number: 1.How many sides? 2.Are your sides the same length? 3. Hint");
Then take the user input, and parse it to an integer. Have an if/else/else or a switch/case using that integer. (alternatively, use if/else/else with the string as it is, but make sure to use .equals() not ==)
So now you've asked a question, and selected one. Now you print out
if(userInput.equals("1")){
system.outprintln("How many sides? " + shapeChoice.getSides());
}
Do the same thing for 2 and 3. You'll be dealing with a shapeChoice, so you have to call the base methods of shape. However, at runtime, if the object is a square or a rectangle, when you call shapeChoice.getSides() it will invoke the square or rectangle implementation, giving you the answer you want! :)
Then all you have to do is loop back, ask the question over and over again, and if the user wants to, let him guess, and check his answer! (compare .equals(shapeChoice.getName()))
so have a big while(true) forever loop, inside of which you can ask a question, and then check if they want to answer. If they answer right, you break out. Otherwise, you loop back around, and keep asking them which hint they'd like.
EDIT: Actually, now that I look at it, since you're practicing polymorphism, you should probably use it a little more. Right now, You have your separate classes, but you're passing in all your information when you construct them. Instead of:
square s = new square(4, "Square", true, "Geeks were called this in the 80s");
Rectangle r = new Rectangle(4, "Rectangle", false, "Not Pentangle");
Have it be more like
square s = new square();
and have part of square's definition inherently define
public class square extends shape {
//square member variables
boolean equalSides = true;
int numSides = 4;
//and so on
//OR even better, don't define them, since the base class already does!
//merely set the values in the constructor
public square(){
numSides = 4;
equalSides = true;
shapeHint = "Geeks were called this in the 80s";
}
}
EVERY square object is going to be this way, so there's no reason it should be a parameter. That is part of the definition of a square.