Reputation: 95
I'm building a tower defense game for a homework assignment. I'm recycling old code from a homework where I had to create an ocean and I have looked back and compared so the panel should show the JButtons, and it was showing them earlier but now the panel doesn't show the buttons. There are other classes with this code but everything relating to the JButtons happens in these.
Thanks for the help.
import javax.swing.JFrame;
import java.awt.BorderLayout;
public class Td {
public static void main(String[] args) {
JFrame frame = new JFrame("Tower Defence");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ControlPanel2 control = new ControlPanel2();
frame.add(control, BorderLayout.WEST);
frame.add(new GamePanel(control)); //defaults to CENTER
frame.pack();
frame.setVisible(true);
}
}
import javax.swing.Box;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ControlPanel2 extends JPanel {
private JButton basicTower, advanceTower, nextWave;
private JLabel score, money;
private int x, y;
private String action;
public ControlPanel2() {
setPreferredSize(new Dimension(150, GamePanel.HEIGHT));
basicTower = new JButton("Basic Tower");
basicTower.addActionListener(new ButtonListener("BasicTower"));
this.add(basicTower);
advanceTower = new JButton("Advance Tower");
advanceTower.addActionListener(new ButtonListener("advanceTower"));
add(advanceTower);
nextWave = new JButton("Next Wave!");
nextWave.addActionListener(new ButtonListener("nextWave"));
add(nextWave);
System.out.println("MADE IT");
action = "none";
x = 100;
y = 1000;
score = new JLabel ("Score: " + x);
money = new JLabel ("Money: " + y);
add(score);
add(money);
}
public void setY(int z) {
y = y - z;
money.setText("Money: " + y);
}
public void setX(int z) {
x = x + z;
score.setText("Score: " + x);
}
public int getY() {
return y;
}
public int getX() {
return x;
}
public String getAction() {
return action;
}
public class ButtonListener implements ActionListener {
private String name;
public ButtonListener(String className) {
name = className;
}
public void actionPerformed(ActionEvent e) {
action = name;
}
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.Timer;
import java.awt.Point;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.lang.reflect.InvocationTargetException;
import java.util.Random;
public class GamePanel extends JPanel{
public static final int WIDTH = 600, HEIGHT = 600;
private ArrayList<Cage> cage = new ArrayList<Cage>();
private ArrayList<Tower> towers = new ArrayList<Tower>();
private ControlPanel2 cPanel;
private Timer timer;
private Rectangle bounds;
public GamePanel(ControlPanel2 control) {
//***Does not need to be edited
cPanel = control;
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.gray);
bounds = new Rectangle(0, 0, WIDTH, HEIGHT);
addMouseListener(new ClickListener());
timer = new Timer(200, new TimerListener());
timer.start();
}
public void paintComponent(Graphics g) {
//***Does not need to be edited
super.paintComponent(g); //Call to the super constructor to make sure
//all of JPanel's paintComponent stuff is called first
for (Tower a : towers) {
a.draw(g);
}
}
private class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//INSERT CODE HERE
//Call the methods in OceanPanel that you think need
//to be called each time the timer is triggered.
validate();
repaint();
}
}
private class ClickListener extends MouseAdapter {
//***You do not need to edit this private inner class
// but you should know what it is accomplishing.
/**
* You are not required to know what exactly is going on in this method.
* However, if you are curious, you should check out the Class API. Using
* a tool called 'reflection', it is instantiating a Fish given a
* String that represents the class name. This way, we don't need a long
* series of 'if' statements to create a certain type of Fish.
*@param Point p is where the fish will be placed to start.
*@param String className is the class name for the type of Fish that
* we want to instantiate.
*@return Fish that is exactly the type of Fish that we want to add
* to the panel.
*/
public Tower instantiateTower(Point p, String className) {
try {
Class cl = Class.forName(className);
return (Tower) (cl.getDeclaredConstructor(
int.class, int.class, Rectangle.class).newInstance(
p.x, p.y, bounds));
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.exit(1);
} catch (InstantiationException e) {
e.printStackTrace();
System.exit(1);
} catch (IllegalAccessException e) {
e.printStackTrace();
System.exit(1);
} catch (InvocationTargetException e) {
e.printStackTrace();
System.exit(1);
}
return null;
}
public void mousePressed(MouseEvent e) {
//Determine which type of Fish to create by asking ControlPanel
//This information is based on the button that was last clicked
// String towerType = cPanel.getAction();
Point p = e.getPoint();
System.out.println(e.getPoint());
repaint();
}
}
}
Upvotes: 2
Views: 814
Reputation: 285405
Your ControlPanel2 class, a class that extends JPanel, has two methods, getX()
and getY()
that override key Component methods, methods that are critical for component placement, and your inadvertent overrides messes with this. You will want to change the names of these methods. Perhaps you can rename your variables xPos and yPos and change the methods to getXPos()
and getYPos()
.
So for example you could do:
public class ControlPanel2 extends JPanel {
private JButton basicTower, advanceTower, nextWave;
private JLabel score, money;
// note change
private int xPos;
private int yPos;
private String action;
public ControlPanel2() {
setPreferredSize(new Dimension(150, GamePanel.HEIGHT));
basicTower = new JButton("Basic Tower");
basicTower.addActionListener(new ButtonListener("BasicTower"));
this.add(basicTower);
advanceTower = new JButton("Advance Tower");
advanceTower.addActionListener(new ButtonListener("advanceTower"));
add(advanceTower);
nextWave = new JButton("Next Wave!");
nextWave.addActionListener(new ButtonListener("nextWave"));
add(nextWave);
System.out.println("MADE IT");
action = "none";
// **** note changes. As an aside -- avoid "magic" numbers
xPos = 100;
yPos = 1000;
score = new JLabel ("Score: " + x);
money = new JLabel ("Money: " + y);
add(score);
add(money);
}
public void setYPos(int z) {
yPos -= z;
money.setText("Money: " + yPos);
}
public void setXPos(int z) {
xPos += z;
score.setText("Score: " + xPos);
}
public int getYPos() {
return yPos;
}
public int getXPos() {
return xPos;
}
Note that this is one reason why it is often better to extend a class by composition rather than by inheritance -- to avoid inadvertent overrides causing strange side effects.
Upvotes: 3