I'm not sure why but when I try to run this the only thing that shows is the last program I ran, I even added the serialVersionUID and it still wont show. Anyone have an i dea on why, maybe some setup problem on my eclipse or coomputer?
import java.awt.Graphics;
import javax.swing.JPanel;
public class Shapes extends JPanel {
private static final long serialVersionUID = 1L;
private int choice;
public Shapes(int userChoice) {
choice = userChoice;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; 1 < 10; i++) {
switch (choice) {
case 1:
g.drawRect(10 + i * 10, 10 + i * 10, 50 + i * 10, 50 + i * 10);
case 2:
g.drawOval(10 + i * 10, 10 + i * 10, 50 + i * 10, 50 + i * 10);
break;
}
}
}
}
First of all, you have no entry-point to your program. You can't just expect a program in Java, or basically any other compiled language to run without an entry point.
Inside your class, you need to have the following for the program to begin:
public static void main(String[] args) {
// Entry-point began. Put code in here.
}
Secondly, it is not a good practise (correct me if I'm wrong) to extend any of the JComponent derivatives. Without explaining again, a good reason can be found here:
Excerpt:
It makes it harder to change things later - if you've made a class public, swapping the superclass is going to break subclasses - it's a choice which, once you've made the code public, you're married to. So if you're not altering the real functionality to your superclass, you get much more freedom to change things later if you use, rather than extend the thing you need. Take, for example, subclassing JPanel - this is usually wrong; and if the subclass is public somewhere, you never get a chance to revisit that decision. If it's accessed as JComponent getThePanel() , you can still do it (hint: expose models for the components within as your API). This especially applies because your class is a Shape. So when Shape extends JPanel, every single shape will.
Object hierarchies don't scale (or making them scale later is much harder than planning ahead) - this is the classic "too many layers" problem. I'll go into this below, and how the AskTheOracle pattern can solve it (though it may offend OOP purists).
Especially since you are extending JPanel, and aren't even initialising a JFrame to begin with. Before starting out with Swing applications in Java, you should read the JavaDoc and Oracles examples beforehand...
JavaDoc: JFrame / JPanel
Example: How to make Frames.
So, revising on what I have said, a basic Swing class would look as follows:
import javax.swing.*;
public class Shapes {
public Shapes() {
JFrame frame = new JFrame();
JPanel window = new JPanel();
frame.setSize(600, 400); // Width: 600, Height: 400.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(window);
window.setLayout(new BorderLayout());
// Perform graphics drawing.
frame.revalidate();
frame.repaint();
}
public static void main(String[] args) {
new Shapes();
}
}
Related
I am trying to make a chess engine as a fun project, but for that I really want to make a GUI. The problem is that I have no experience with this, so I am a little stuck. I managed to create the board, but there are two things I have no idea how to do and looking online just confuses me further.
How do I add the pieces to the board, based on what the board looks like in the computers memory. (so for example if the engine makes a move, I want that move to also happen on the gui, how would I link the two?)
How do I figure out what square the user is clicking on in the gui?
This is the code I have so far for the gui, it's not much, but it's honest work
private final JFrame gameFrame;
private Board board;
public Table() {
this.board = new Board();
this.gameFrame = new JFrame("Chess");
this.gameFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.gameFrame.setSize(527, 550);
JPanel panel = new JPanel() {
#Override
public void paint(Graphics g) {
boolean white = true;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (white) {
g.setColor(new Color(240, 217, 181));
}
else {
g.setColor(new Color(181, 136, 99));
}
g.fillRect(j * 64, i * 64, 64, 64);
white = !white;
}
white = !white;
}
}
};
this.gameFrame.add(panel);
this.gameFrame.setVisible(true);
}
I know I am probably asking questions with complicated answers, but I am just looking for something I can look up or some general directions
One way and perhaps the the most useful is to implement a mouseListenerand then get the x y position from one of the methods.
Write a class to extend MouseAdapter.
override the desired empty methods.
then add an instance of that class to the frame via addMouseListener (and perhaps addMouseMotionListener).
Then when you do some action with the mouse, you can get the coordinnates from the MouseEvent. It helps to put some print statements in each method to observe what is going on (what method is processing what mouse movement).
The above will serve to demonstrate the process. But later on you should actually add the listener on a JPanel and add the JPanel to the frame.
I am using Intellij to program Java.
I am currently trying to make a top down tile based shooter.
My issue is that my game, after approximately 2 minutes, crashes with a popup saying "Java(TM) Platform SE Binary has stopped working. I recorded the time it took for it to crash 3 times: 1m57s, 1m59s, 1m58s.
The game is in a very simple state right now and I am not sure what could be causing the crash. All of the relevant code is in just two classes: GameFrame.java (extends JFrame) and GamePanel.java (which extends JPanel).
GameFrame.java:
package net.magnusfrater.tds.game;
import javax.swing.*;
public class GameFrame extends JFrame {
public static final int width = 1000;
public static final int height = width / 16 * 10;
private GamePanel gp;
public GameFrame () {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width,height);
setResizable(false);
setLocationRelativeTo(null);
setTitle("Time Based Fast Paced Top Down Shooter Demo");
gp = new GamePanel();
add(gp);
setVisible(true);
}
public static void main (String[] args) {
GameFrame gf = new GameFrame();
}
}
GamePanel.java
package net.magnusfrater.tds.game;
import net.magnusfrater.tds.input.Keyboard;
import javax.swing.*;
import java.awt.*;
public class GamePanel extends JPanel implements Runnable {
//panel
private Thread thread;
private static boolean running;
private boolean fpsLock;
//input
private Keyboard kb;
//game
private Game game;
public GamePanel () {
//panel
thread = new Thread(this, "Time Based Fast Paced Top Down Shooter Demo");
running = true;
fpsLock = true;
//input
//kb = new Keyboard();
//addKeyListener(kb);
//game
//game = new Game(1);
thread.start();
}
public void run () {
long iTimeNS = System.nanoTime();
int tickRate = 60;
long ns = 1000000000 / tickRate;
int ups = 0;
int fps = 0;
long iTimeS = System.nanoTime();
long s = 1000000000;
while (running) {
long fTimeNS = System.nanoTime();
if (fTimeNS - iTimeNS >= ns){
iTimeNS = System.nanoTime();
tick();
ups++;
if (fpsLock){
repaint();
fps++;
}
}
if (!fpsLock){
repaint();
fps++;
}
long fTimeS = System.nanoTime();
if (fTimeS - iTimeS >= s){
iTimeS = System.nanoTime();
System.out.println("ups: " + ups + "\tfps: " + fps);
ups = 0;
fps = 0;
}
}
System.exit(0);
}
public void tick () {
if (kb != null)
kb.tick();
if (game != null)
game.tick();
}
#Override
public void update (Graphics g) {
paint(g);
}
#Override
public void paint (Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0,0,GameFrame.width, GameFrame.height);
//if (game != null)
//game.paint(g);
}
public static void quitGame () {
running = false;
}
}
I originally thought that the issue was because of the way that I was loading images for spritesheets or maybe the way I was loading text files for the level design but after reworking both of those, the issue remained.
That left me curious and a little bit fed up so I tried finding out more about the explanation for the crash. First I read more from the popup but it didn't say anything useful: (See below)
Second I looked at the exit code given by Intellij: (See below)
I looked up what exit code 255 was but there wasn't anything useful. The best explanation I could find was that exit code 255 meant that the real exit code was out of range: (See below)
I was out of ideas at this point so I just started plain old googling everything I could think of. The problem with googling "Java(TM) Platform SE Binary has stopped working" is that almost every suggested link is a question about Minecraft. Limiting my search to Stack Overflow yielded me some results, but nothing conclusive. Some of the fixes I found were stuff I already tried (such as not handling input streams properly, not handling buffered reader properly, not disposing of elements, etc). I found these links but none of them were truly related to my issue:
(See below)
(See below)
(See below)
(See below)
(See below)
(See below)
The last fix I tried was to re-install Java SE Development Kit 8u101 AND Java SE Development Kit 8u102. I then restarted Intellij. I then restarted my computer.
Nothing worked.
At this point I think I'm just dumb. I've overlooked something easy I can tell. What am I missing?
(ps~ This is a possibly related issue. So if I run my game with almost no content in it with the fps not locked to 60, I get really absurd numbers of frames per second. I didn't think that fps as high as 7,000,000 was possible. I think. I don't know. Have I programmed that wrong as well? Here is a related picture of my ups/fps output: [see below])
(SEE HERE) So Stack Overflow doesn't allow members with a score within a certain threshold post more than 2 links and allows absolutely no posting of images. So here is a link to a google doc with all of the links and images I mentioned above:
https://docs.google.com/document/d/1XrBuVio19GmkFz0EfRzXVp5AJmM5zPfVO6vK3oS3Eaw/edit?usp=sharing
Try and set your -Xmx to something like 2G and see if it runs longer. If so, something is allocating memory and maybe you have that other setting set that exits instead of garbage collecting for some reason.
Also, try changing your code to limit things using Guava's RateLimiter.
…
// class level
final RateLimiter frameLimiter = RateLimiter.create(60.0);
final RateLimiter outputLimiter = RateLimiter.create(1.0);
…
// in run method
while (running) {
frameLimiter.acquire();
repaint();
fps++;
if (outputLimiter.tryAcquire()){
System.out.println("fps: " + fps);
fps = 0;
}
}
I've removed ups and tick(). You should do your work after repainting and I don't think you want to do more work than needed for the next frame, which at the soonest should be at your max rate. Later you'll need to add logic to handle skipping work when frames are being skipped. I might make more sense to increment the fps within repaint.
You could put the output in its own thread and only acquire that limiter if you synchronized the increments and resetting of fps.
I'm trying to write a code that does the following:
If I click on the String C(JLabel) whose starting position is (100,100), the String moves WITHIN the boundaries of JFrame. The code itself wasn't hard to implement but I'm having issues with setting the (x,y) for JLabel so that any Part of the String "C" doesn't get cut off.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class adfadf extends JFrame{
JLabel text = new JLabel("C");
Container container = getContentPane();
public adfadf(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container.setLayout(null);
MyMouseListener mml = new MyMouseListener();
text.addMouseListener(mml);
text.setLocation(100,100);
text.setSize(30,30);
add(text);
setSize(400,400);
setVisible(true);
}
public static void main(String[] args) {
new adfadf();
}
}
class MyMouseListener extends MouseAdapter{
#Override
public void mouseClicked(MouseEvent e){
JLabel text = (JLabel)e.getSource();
int x = (int)(Math.random()*(400-30));
int y = (int)(Math.random()*(400-30));
text.setLocation(x,y);
}
}
How should I change
int x = (int)(Math.random()*(400-30));
int y = (int)(Math.random()*(400-30));
in order to achieve what I want?
First, understanding that a JFrame is much more complex then it seems
To start with, a JFrame has a JRootPane, that contains the contentPane and JMenuBar and glassPane
This is further complicated by the fact the window's decorations are actually painted WITHIN the visible bounds of the frame, meaning that the visible area available to your content is actually smaller than the frame's size.
You can have a look at How can I set in the midst?, Graphics rendering in title bar and How to get the EXACT middle of a screen, even when re-sized for more details and examples of this.
But how does this help you? Well, now you know that you have a space of less than 400x400 to display your label in, but how much?
The simple solution is to stop using "magic" numbers, and take a look at something which is been used by the frame, the contentPane. The contentPane is managed by the the JFrame (via the JRootPane) so that it sits within the frame decorations, so you could do something more like...
JLabel text = (JLabel)e.getSource();
int width = getContentPane().getSize().width;
int height = getContentPane().getSize().height;
int x = (int)(Math.random()*(width-30));
int y = (int)(Math.random()*(height-30));
text.setLocation(x,y);
The reason for looking at the contentPane in this instance is simply because, that's the container that the label is actually added to.
This is one of the reasons why we suggest you don't use "magic" numbers, but look at the actual known values at the time you need them.
GUI.java
package ccc;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GUI implements ActionListener {
JFrame f;
JPanel bg, s, a;
JLabel ca, £, cav, co, cov, co2, pr, error;
JTextField tf;
JButton b1, b2;
public GUI(){
f = new JFrame();
bg = new JPanel();
bg.setSize(650, 500);
bg.setBackground(Color.darkGray);
bg.setLayout(null);
bg.setLocation(0, 0);
s = new JPanel();
s.setSize(180, 445);
s.setBackground(Color.white);
s.setLayout(null);
s.setLocation(10, 10);
a = new JPanel();
a.setSize(430, 445);
a.setBackground(Color.white);
a.setLayout(null);
a.setLocation(202, 10);
ca = new JLabel("CASH:");
ca.setSize(70,25);
ca.setLocation(10, 25);
£ = new JLabel("£");
£.setSize(10, 25);
£.setLocation(80, 25);
cav = new JLabel("128.23");
cav.setSize(80, 25);
cav.setLocation(90, 25);
co = new JLabel("COCAINE:");
co.setSize(70, 25);
co.setLocation(10, 50);
cov = new JLabel("6 units");
cov.setSize(70, 25);
cov.setLocation(80, 50);
co2 = new JLabel("COCAINE");
co2.setSize(70, 25);
co2.setLocation(10, 25);
pr = new JLabel("£39.95");
pr.setSize(60, 25);
pr.setLocation(90, 25);
tf = new JTextField();
tf.setSize(70, 25);
tf.setLocation(160, 25);
b1 = new JButton("BUY");
b1.setSize(70, 25);
b1.setLocation(270, 25);
b1.addActionListener(this);
b2 = new JButton("SELL");
b2.setSize(70, 25);
b2.setLocation(350, 25);
b2.addActionListener(this);
error = new JLabel();
error.setSize(200, 25);
error.setLocation(50, 50);
s.add(ca);
s.add(£);
s.add(cav);
s.add(co);
s.add(cov);
a.add(co2);
a.add(pr);
a.add(tf);
a.add(b1);
a.add(b2);
a.add(error);
bg.add(s);
bg.add(a);
f.add(bg);
f.setSize(650, 500);
f.setLayout(null);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public static void main(String[] args) {
new GUI();
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1){
Buy a = new Buy();
a.Buy();
}
if (e.getSource() == b2){
}
}
}
Buy.java
package ccc;
public class Buy extends GUI {
String pri, qua, cas, uni, aaa;
double price, quantity, cash, units, total, deduction;
public Buy(){
pri = pr.getText();
price = Double.parseDouble(pri);
qua = tf.getText();
quantity = Double.parseDouble(qua);
cas = cav.getText();
cash = Double.parseDouble(cas);
uni = cov.getText();
units = Double.parseDouble(uni);
total = price * quantity;
if (cash >= total){
deduction = cash - total;
aaa = String.valueOf(deduction);
cav.setText(aaa);
}
else if (cash < total){
error.setText("Sorry, you don't currently have the funds");
}
}
}
Hi folks,
I am currently learning java and wanted to give myself a project that was both challenging and fun. I decided to build a game that I remember playing when I was a kid called dopewars.
This is my second attempt at this game. When I began my first attempt, all went well. After a short while my source code began to fill wildly out of control until I could continue no more as I kept getting lost within mountains of code.
I then decided to begin again, only this time I wanted to seperate the gui from the logic (2 different .java files). This is where my problem lies. Previously this would work fine. Since seperating my java files the functionality has stopped.
When I press jbutton b1, my program is supposed to take the price value of cocaine and the units value entered into the jtextfield by the user, perform a calculation by accessing a method within Buy.java, and then update the appropriate JLabels within the s jpanel of GUI.java.
For example, user x wants to buy cocaine at the price indicated, so he enters a value representing the quantity he would like. He then presses the buy button which ultimately deducts the money from his pocket which is shown on the left side of the program window by using a method within the Buy class.
I hope you can understand my explanation and I hope to hear from you soon. Thanks.in advance. My Source code is below.
Your problems begin right here:
public class Buy extends GUI {
Try to rewrite you game logic so that it does not know a single thing about GUI. Assume you want to make your game playable via command line. Your game logic should be written in a way that it does not have to be changed at all to make this possible.
Try to identify the interface through which the user interacts with model of the game. Then implement this interface.
Here are some ideas (I don't know DopeWars, so I'll give you some generalized examples)
public class MyGameEngine {
public PlayerData getPlayerData() { ... }
public void sellSomeStuff(int numberOfStuff) throws InvalidPlayerOperation {
if (numberOfStuff > getPlayerData().getAmountOfStuff() {
throw new InvalidPlayerOperation("Not enough stuff");
}
....
}
}
public class PlayerData {
public int getAmountOfStuff() { ... }
}
public class InvalidPlayerOperation extends RuntimeException { ... }
There are a lot of patterns in this area. But if you want really to learn something, try it without looking up patterns first. When you got it working, there will be enough time to learn about patterns and then you check your code if you used them intuitively or if you could introduce them to improve its quality.
In particular, the MVC pattern might be overkill for your simple game, especially if you don't want to use an MVC framework (you don't).
The Singleton pattern, on the other hand, seems simple at first but is generally bad style and will only cause problems later on.
The following answer in no shape or form encourages real dope wars ;)
MVC is your friend. The way I do this usually is to write the data and data manipulation parts of the code first, without any thought whatsoever as to how it's going to look on screen.
Try to separate out the "data" part of your code first. Keep that neatly elsewhere; simple pojo objects representing real world objects, for example.
Then write the operations you can do on those objects into different classes. Make these completely independent of UI, as I said before. This ensures that the functionality part of your code is nice and separate, and essentially test-able.
Then write your UI part. A button click routes to a method call in your operations part of the code, for example.
Hope that helps.
I'm just starting learning Java after a few years of HTML/CSS coding so hopefully I'm not asking a old or stupid question here but any help explaining this problem would be very much appreciated.
I'm currently working through the Stanford CS106A online material and I've reached week 6, Assignment 2, Question 3 (http://see.stanford.edu/materials/icspmcs106a/13-assignment-2-simple-java.pdf).
As you can see it requires the placement of various objects on the screen to create the Graphics Hierarchy, as described. My plan was to use the centre coordinates to relatively place all the objects on the screen. However I've hit a problem that I can't seem to find an answer to. The course describes how Method Decomposition should allow each method to handle one problem (Single Responsibility Principle, I believe) so I have written the first part of my code as such:
//Import any libraries
import acm.program.*;
import acm.graphics.*;
public class GraphicsHierarchy extends GraphicsProgram {
//Define constants
static final int BOX_WIDTH = 200;
static final int BOX_HEIGHT = 75;
public void run() {
placeGRect();
}
//Find centre x & y
double centre_x = getWidth() / 2; //check this
double centre_y = getHeight() * 0.5;//and this
//placeGRect method
public void placeGRect() {
for (int count = 0; count < 4; count++) {
GRect box = new GRect (BOX_WIDTH, BOX_HEIGHT);
add(box);
switch (count) {
case 0:
box.setLocation(centre_x, 75);
break;
case 1:
box.setLocation((centre_x * 0.5), 250);
break;
case 2:
box.setLocation(centre_x, 250);
break;
case 3:
box.setLocation((centre_x * 1.5), 250);
break;
}
}
}
}
However this doesn't work due to the centre_x & centre_y producing zero values. I discovered this by changing the program to a ConsoleProgram and having the getWidth & getHeight lines inside the run() method (and println their values on screen), which then produced the required values but didn't pass them to the GRect method (so still didn't work). However if I have the getWidth/getHeight lines listed out of the run() then they don't produce any values for relative positioning.
My question is given that each method should handle one task and (as much as possible) methods should be defined out of the run() method, then how I can I get the getWidth/getHeight values to the placeGRect() method without having one big block of code within the run() method. Which I understand is bad practise.
I'm not after any code to solve this, I really need to understand the principles of this so I can write effective code in the future. I prefer understanding to parrot-fashion code copying.
Thanks in advance for any help.
In your specific example:
You have declared centre_x and centre_y as instance variables. When your program first creates an instance of GraphicsHierarchy the order of object creation is as such:
ClassLoader loads the class... static variables (BOX_WIDTH,BOX_HEIGHT) are assigned specified values;
Space is allocated on the heap for an instance of GraphicsHierarchy (enough space to hold the instance variables - a double for centre_x and a double for centre_y- including space for base class instance variables)
Instance variables are set to default values: centre_x = 0, centre_y = 0
The GraphicsHierarchy default constructor is called (which does nothing other than call the base class constructor - GraphicsProgram).
The base class will go through steps 1-4 and when it's finished execution returns to GraphicsHiearchy which now evaluates explicit instance variable initializers before executing any remaining constructor statements (which in the case of the default constructor, there are none).
(additional reference on this process http://java.dzone.com/articles/java-object-initialization)
Having said all of that, it would appear that when your class GraphicsHierarchy gets to step 5 and tries to assign values to centre_x and centre_y, the subsystem that getWidth and getHeight rely upon is not ready (i.e. a window or canvas has not been created yet, so the methods return 0). But when you moved your assignments inside run and getWidth/getHeight returned values, that would imply whatever method is calling run has first gone through the necessary window creation steps.
Etienne de Martel's suggestion is fine. It delays assignment of your centre values until right before they are needed. If you'd rather, you could create an init method and move the assignments inside the init method, and then call init as the first step of run
private void init() {
centre_x = getWidth / 2;
centre_y = getHeight * 0.5;
}
public void run() {
init();
placeGRect();
}
This is nearly the same thing as Martel's suggestion, although if you find later you have other initialization code that needs to happen, you can throw it in the same place.
As for crafting flexible code you might think about renaming placeGRect to placeGRects and passing in array of points (or Collection if you prefer) placeGRects(Point[] points)
(you can use Java.awt.Point or define your own Point class)
In this way, your placeGRects method is simplified. It no longer decides how many boxes to render (the array that is passed in does). It also doesn't determine where those new boxes are located (again the array of Point objects do). It simply loops through the size of the array, makes a new box, adds it, and sets the location.
private Point[] boxPoints;
public void run() {
init();
placeGRects(boxPoints);
}
public void placeGRects(Point[] points) {
for(int i=0;i<points.length;i++) {
GRect b = new GRect(BOX_WIDTH,BOX_HEIGHT);
add(b);
b.setLocation(points[i].x,points[i].y);
}
}
And you can put your Point array initialization inside your new init() method.
private void init() {
centre_x = getWidth / 2;
centre_y = getHeight * 0.5;
boxPoints = {new Point(centre_x, 75),new Point(centre_x * 0.5, 250)};
}
It makes your code easier to understand and modify when needed.
Perhaps I don't understand your question, but why not pass them as parameters?
protected void placeGRect(double centre_x, double centre_y) {
// ...
}
You can then call placeGRect like so:
public void run() {
placeGRect(getWidth() / 2, getHeight() * 0.5);
}
Very nice question! How to compose your methods is a matter of intuition rather than strict guidelines.
Certainly, methods should be focused on doing one thing and one thing only. Firstly, having short methods (even one-liners!) improves the understandability of the code. As a very rough example, think of this:
if (DateUtils.before(ticket.getExpirationDate(), new Date())) {
accept(ticket);
}
and then this
if (isNotExpired(ticket)) {
accept(ticket);
}
...
private boolean isNotExpired(Ticket t) {
return DateUtils.before(t.getExpirationDate(), now());
}
private Date now() {
return (new Date());
}
Pay attention to how the introduction of one line methods isNotExpired() and now() significantly improved your undestanding of what the code does.
Here's another example, this time that has to do with constructing objects:
Loan l1 = new Loan(15000, 36, f7.2, 2.5);
Loan l2 = new Loan(15000, 36, f7.2);
vs.
Loan l1 = Loan.newSubsidizedLoan(15000, 36, f7.2, 2.5);
Loan l2 = Loan.newNormalLoan(15000, 36, f7.2);
Note in this example how wrapping the constructors in two different methods significantly improves the documentation of code (without even needing to write comments);
If you are interested on the general topic of coding style, you should read this book.
Cheers
L.
Your code doesn't seem to include the getWidth() and getHeight() methods. Also, the following piece of code is totally wrong as a placement and should be placed in a constructor:
double centre_x = getWidth() / 2; //check this
double centre_y = getHeight() * 0.5;//and this
Should become
private double centre_x;
private double centre_y;
GraphicsHierarchy(){
centre_x = GraphicsHierarchy.BOX_WIDTH / 2;
centre_y = GraphicsHierarchy.BOX_HEIGHT * 0.5;
}
This code will at least compile, but consider the solution described below, which is even better.
Considering that you have defined BOX_WIDTH and BOX_HEIGHT as static variables, you can always find centre_x and centre_y. Therefore, you don't even need to define BOX_WIDTH and BOX_HEIGHT
You can define your class like this:
//Import any libraries
import acm.program.*;
import acm.graphics.*;
public class GraphicsHierarchy extends GraphicsProgram {
public void run() {
placeGRect();
}
//Define constants
public static final double CENTRE_X= 100.00;
public static final double CENTRE_Y = 37.50;
//placeGRect method
public void placeGRect() {
for (int count = 0; count < 4; count++) {
GRect box = new GRect (200, 75);
add(box);
switch (count) {
case 0:
box.setLocation(GraphicsHierarchy.CENTRE_X, 75);
break;
case 1:
box.setLocation((GraphicsHierarchy.CENTRE_X * 0.5), 250);
break;
case 2:
box.setLocation(GraphicsHierarchy.CENTRE_X, 250);
break;
case 3:
box.setLocation((GraphicsHierarchy.CENTRE_X * 1.5), 250);
break;
}
}
}
}
In my opinion, you can go even further by eliminating all computations and replace such stuff
GraphicsHierarchy.CENTRE_X * 1.5
with
150
Come on, have it easy on your Virtual Machine! Your class uses a whole load of static information, so there is no need for so much computation. But having a BOX_WIDTH and BOX_HEIGHT is completely useless as constants, as they are used only internally and only on one place. Calculating centre_x and centre_y out of the BOX_WIDTH and BOX_HEIGHT is also useless, as as they are final, you can easily do the computation yourself and reduce unnecessary creation of variables.
In addition, you don't use the centre_y value anywhere, so you should ditch it.
To further add some helpful advice, a decent IDE, like NetBeans, Eclipse, or IntellIJIDEA should have code completion and syntax highlighting and will help you immensely in becoming a better (or more knowledgable, which is even better) programmer.