I'm building a Tree traversal program which allows users to run BFS and DFS traversals, as well as add and remove nodes.
So far I've been able to update the adjacency matrix when someone clicks to add a new child node to a parent:
Then I click Add Node, which adds Z to parent A:
You can see that the adjacency matrix appends Z to A... but I'm expecting the node Z to appear on the left side tree as well.
I think the problem is the updated nodeList is not being sent to paintComponent() loop for painting... so it's not being shown.
Here is a SSCCE of my program:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import javax.swing.JFrame;
public class MainSSCCE extends JFrame {
static MainSSCCE run;
int amount, nodeWidth, nodeHeight;
GraphSSCCE g;
JFrame f;
public MainSSCCE(){
f = new JFrame("DTurcotte's Graph Traversals");
g = new GraphSSCCE(450, 300);
f.add(g);
f.setSize(g.getWidth(),g.getHeight());
f.setVisible(true);
nodeWidth = 25;
nodeHeight = 25;
f.setResizable(false);
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
public static void main(String[] args) {
run = new MainSSCCE();
}
}
Graph:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GraphSSCCE extends JPanel {
ArrayList<NodesSSCCE> nodeList;
public int[][] adjMatrix;
NodesSSCCE rootNode;
int size, height, width, x, y, counter;
Color color;
String message = "", run = "", nodeVal = "";
JButton AddButton;
JLabel label;
int nodeX = 180, nodeY = 100, nodeWidth, nodeHeight;
TextField child;
JComboBox parents;
public GraphSSCCE(int w, int h) {
height = h;
width = w;
nodeList = new ArrayList<NodesSSCCE>();
nodeWidth = 25;
nodeHeight = 25;
AddButton = new JButton("Add Node");
label = new JLabel("to parent");
label.setForeground(Color.WHITE);
child = new TextField(1);
parents = new JComboBox();
add(AddButton);
add(child);
add(label);
add(parents);
NodesSSCCE nA = new NodesSSCCE("A", nodeX, nodeY, nodeWidth, nodeHeight);
NodesSSCCE nB = new NodesSSCCE("B", nodeX, nodeY, nodeWidth, nodeHeight);
NodesSSCCE nC = new NodesSSCCE("C", nodeX, nodeY, nodeWidth, nodeHeight);
addNode(nA);
addNode(nB);
addNode(nC);
setRootNode(nA);
connectNode(nA, nB);
connectNode(nA, nC);
for (NodesSSCCE n : nodeList) {
parents.addItem(n.getValue());
}
//send in selected parent from combo box
AppendChildren ac = new AppendChildren(child);
this.child.addActionListener(ac);
this.AddButton.addActionListener(ac);
}
class AppendChildren implements ActionListener {
private TextField child;
public AppendChildren(TextField child) {
this.child = child;
}
public void actionPerformed(ActionEvent ae) {
String childName = child.getText();
NodesSSCCE newChild = new NodesSSCCE(childName, nodeX, nodeY, nodeWidth, nodeHeight);
appendNode(rootNode, newChild);
}
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setColor(rootNode.getColor());
g.fillRect(rootNode.getX(), rootNode.getY(), rootNode.getWidth(), rootNode.getHeight());
g.setColor(Color.WHITE);
g.drawString(rootNode.getValue(), rootNode.getX()+9, rootNode.getY()+16);
paintComponent(g, rootNode);
}
public void paintComponent(Graphics g, NodesSSCCE parentNode) {
ArrayList<NodesSSCCE> nodePrintList = new ArrayList<NodesSSCCE>();
if (nodeList.indexOf(parentNode)==nodeList.size()) {
System.out.println("\nend");
}
else {
nodePrintList = getChildren(parentNode);
int x = parentNode.getX()-50;
//PAINT TREE: THIS IS NOT PAINTING THE NEWLY APPENDED NODE
for (NodesSSCCE child : nodePrintList) {
g.setColor(child.getColor());
child.setX(x);
child.setY(parentNode.getY()+50);
g.fillRect(child.getX(), child.getY(), child.getWidth(), child.getHeight());
g.setColor(Color.WHITE);
g.drawString(child.getValue(), child.getX()+9, child.getY()+16);
x+=50;
paintComponent(g, child);
g.setColor(child.getColor());
g.drawLine(parentNode.getX()+10, parentNode.getY()+23, child.getX()+10, child.getY());
}
//PAINT ADJACENCY MATRIX
for (int i = 0; i < adjMatrix.length; i++) {
for (int j = 0; j < adjMatrix[i].length; j++) {
g.setColor(Color.white);
g.drawString("" + adjMatrix[i][j], (i*19)+350, (j*19)+100);
g.setColor(Color.gray);
g.drawString("" + nodeList.get(i).getValue(), (i*19)+350, 75);
}
g.drawString("" + nodeList.get(i).getValue(), 325, (i*19)+100);
}
}
}
public void setRootNode(NodesSSCCE n) {
rootNode = n;
}
public NodesSSCCE getRootNode() {
return rootNode;
}
public void addNode(NodesSSCCE n) {
nodeList.add(n);
}
public void appendNode(NodesSSCCE parent, NodesSSCCE child) {
//add new node X to nodeList
addNode(child);
int newSize = nodeList.size();
//make a new adj matrix of the new size...
int[][] adjMatrixCopy = new int[newSize][newSize];
int fromNode = nodeList.indexOf(parent);
int toNode = nodeList.indexOf(child);
//copy adjMatrix data to new matrix...
for (int i = 0; i < adjMatrix.length; i++) {
for (int j = 0; j < adjMatrix[i].length; j++) {
adjMatrixCopy[i][j] = adjMatrix[i][j];
}
}
adjMatrixCopy[fromNode][toNode] = 1;
adjMatrix = adjMatrixCopy;
repaint();
}
public void connectNode(NodesSSCCE from, NodesSSCCE to)
{
if(adjMatrix == null) {
size = nodeList.size();
adjMatrix = new int[size][size];
}
int fromNode = nodeList.indexOf(from);
int toNode = nodeList.indexOf(to);
adjMatrix[fromNode][toNode] = 1;
}
public ArrayList<NodesSSCCE> getChildren (NodesSSCCE n) {
ArrayList<NodesSSCCE> childrenList;
childrenList = new ArrayList<NodesSSCCE>();
int index = nodeList.indexOf(n);
int col = 0;
while (col < size) {
if (adjMatrix[index][col] == 1) {
childrenList.add(nodeList.get(col));
}
col++;
}
return childrenList;
}
}
Nodes class:
import java.awt.Color;
import java.awt.Graphics;
public class NodesSSCCE {
Boolean visited;
String val;
Color color;
int xLoc, yLoc, width, height;
public NodesSSCCE(String s, int x, int y, int w, int h) {
visited = false;
val=s;
xLoc = x;
yLoc = y;
width = w;
height = h;
color = Color.gray;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public int getX() {
return xLoc;
}
public int getY() {
return yLoc;
}
public void setX(int x) {
xLoc = x;
}
public void setY(int y) {
yLoc = y;
}
public void visited(Boolean v) {
visited = v;
}
public String getValue() {
return val;
}
public void setValue(String value) {
val = value;
}
public void setColor (Color c) {
color = c;
}
public Color getColor () {
return color;
}
}
Nope, ignore my comment.
You forget to update size correctly.
In the GraphSSCCE, go to method getChildren(NodesSSCCE) and change the loop condition from col < size to col < nodeList.size().
Being able to debug your own programs can save a lot of time.
Related
I create a JFrame, followed by a JPanel and the set the parameters. I have a JPanel called boardSquares where each square would be coloured later on.
Once I attempt to add the checker to the board, the board colours are re-arranged.
I have had numerous attempts to fix this but have not succeeded. I am also sure that there is a better way to do this. Below is some code. All help is appreciated!
public void paintComponent(Graphics g)
{
g.setColor(Color.BLUE);
g.fillOval(0, 0, 30, 30);
}
public static void checkerBoard()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
boardSquares[i][j] = new JPanel();
if ((i + j) % 2 == 0)
{
boardSquares[i][j].setBackground(Color.BLACK);
}
else
{
boardSquares[i][j].setBackground(Color.WHITE);
}
frameOne.add(boardSquares[i][j]);
}
}
}
Look at this example https://www.javaworld.com/article/3014190/learn-java/checkers-anyone.html
And I've little bit upgrade your example
Sorry, I don't have much time for it
import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.Color;
import java.awt.Graphics;
public class Circle extends JPanel
{
public static JFrame frameOne = new JFrame("Frame 1");
public static Circle boardSquares[][] = new Circle[8][8];
public static void main(String[] args)
{
checkerBoard();
frameOne.setSize(new Dimension(400,400));
frameOne.getContentPane().setLayout(new GridLayout(8,8,0,0));
frameOne.setBackground(Color.BLACK);
frameOne.setVisible(true);
frameOne.setResizable(false);
frameOne.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
boardSquares[1][1].setChecker(true);
}
private Color c;
private boolean checker;
public Circle(int i, int j) {
super();
//setBorder(new Border());
//set
if ((i + j) % 2 == 0)
{
c = Color.DARK_GRAY;
}
else
{
c = Color.WHITE;
}
}
void setChecker(boolean ch) {
checker = ch;
}
public static void checkerBoard()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
boardSquares[i][j] = new Circle(i, j);
frameOne.add(boardSquares[i][j]);
}
}
}
public void paintComponent(Graphics g)
{
g.setColor(c);
g.fillRect(0, 0, 40, 40);
if (checker) {
g.setColor(Color.BLUE);
g.fillOval(4, 4, 32, 32);
}
}
}
I would create a separate board class and override the paintComponent method to draw the actual grid.
Then I would give the board a grid layout and add panels to hold the checkers.
There is an issue with the margin of the checker, but that may be due to the size of the panels. You can mess around with this. I fixed this by applying a border layout to the panel.
Finally, avoid using "magic numbers". Try to declare some instance variables inside your classes and pass their value in via the constructor or some setter/mutator methods.
Application.java
package game.checkers;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
public class Application implements Runnable {
public static final String APP_NAME = "Checkers Game";
private GameFrame gameFrame;
private GameBoard checkerBoard;
#Override
public void run() {
initialize();
Checker redChecker = new Checker(50, Color.RED);
Checker greenChecker = new Checker(50, Color.GREEN);
Checker blueChecker = new Checker(50, Color.BLUE);
checkerBoard.placeChecker(redChecker, 1, 5);
checkerBoard.placeChecker(greenChecker, 2, 4);
checkerBoard.placeChecker(blueChecker, 3, 3);
redChecker.addMouseListener(new CheckerMouseListener(redChecker));
greenChecker.addMouseListener(new CheckerMouseListener(greenChecker));
blueChecker.addMouseListener(new CheckerMouseListener(blueChecker));
}
protected void initialize() {
gameFrame = new GameFrame(APP_NAME);
checkerBoard = new GameBoard(8, 8);
checkerBoard.setPreferredSize(new Dimension(400, 400));
gameFrame.setContentPane(checkerBoard);
gameFrame.pack();
gameFrame.setVisible(true);
}
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Application());
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
GameFrame.java
package game.checkers;
import javax.swing.JFrame;
public class GameFrame extends JFrame {
private static final long serialVersionUID = 6797487872982059625L;
public GameFrame(String title) {
super(title);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
GameBoard.java
package game.checkers;
import java.awt.*;
import javax.swing.JPanel;
public class GameBoard extends JPanel {
private static final long serialVersionUID = 5777309661510989631L;
private static final Color[] DEFAULT_TILE_COLORS = new Color[] { Color.LIGHT_GRAY, Color.WHITE };
private BoardZone[][] zones;
private Color[] tileColors;
private int rows;
private int cols;
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getCols() {
return cols;
}
public void setCols(int cols) {
this.cols = cols;
}
public GameBoard(int rows, int cols, Color[] tileColors) {
super();
this.rows = rows;
this.cols = cols;
this.tileColors = tileColors;
initialize();
}
public GameBoard(int rows, int cols) {
this(rows, cols, DEFAULT_TILE_COLORS);
}
protected void initialize() {
this.setLayout(new GridLayout(rows, cols, 0, 0));
generateZones();
}
private void generateZones() {
this.setLayout(new GridLayout(rows, cols, 0, 0));
this.zones = new BoardZone[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
this.add(zones[row][col] = new BoardZone());
}
}
}
public void placeChecker(Checker checker, int row, int col) {
zones[row][col].add(checker);
}
public Checker getChecker(int row, int col) {
return (Checker) zones[row][col].getComponent(0);
}
public void removeChecker(Checker checker, int row, int col) {
zones[row][col].remove(checker);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int tileWidth = this.getWidth() / cols;
int tileHeight = this.getHeight() / rows;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
int x = col * tileWidth;
int y = row * tileHeight;
g.setColor(tileColors[(row + col) % 2]);
g.fillRect(x, y, tileWidth, tileHeight);
}
}
}
}
Checker.java
package game.checkers;
import java.awt.*;
import javax.swing.JComponent;
public class Checker extends JComponent {
private static final long serialVersionUID = -4645763661137423823L;
private int radius;
private Color color;
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public String getHexColor() {
return String.format("#%06X", getColor() == null ? 0 : getColor().getRGB());
}
public Checker(int radius, Color color) {
super();
this.setPreferredSize(new Dimension(radius, radius));
this.radius = radius;
this.color = color;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.radius <= 0 || this.color == null) {
return; // Do not draw it.
}
g.setColor(this.color);
g.fillOval(0, 0, this.radius - 1, this.radius - 1);
}
}
BoardZone.java
package game.checkers;
import java.awt.BorderLayout;
import javax.swing.JPanel;
public class BoardZone extends JPanel {
private static final long serialVersionUID = 8710283269464564251L;
public BoardZone() {
this.setOpaque(false);
this.setLayout(new BorderLayout());
}
}
CheckerMouseListener.java
package game.checkers;
import java.awt.event.*;
public class CheckerMouseListener implements MouseListener {
private Checker target;
public CheckerMouseListener(Checker target) {
this.target = target;
}
private String getCheckerName() {
String hexCode = target.getHexColor();
switch (hexCode) {
case "#FFFF0000":
return "RED";
case "#FF00FF00":
return "GREEN";
case "#FF0000FF":
return "BLUE";
default:
return hexCode;
}
}
#Override
public void mouseReleased(MouseEvent e) {
System.out.println("Released click over " + getCheckerName() + " checker.");
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("Pressed on " + getCheckerName() + " checker.");
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("Finished hovering over " + getCheckerName() + " checker.");
}
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("Began hovering over " + getCheckerName() + " checker.");
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Clicked on " + getCheckerName() + " checker.");
}
}
To be frank i have not the slightest clue how to fix this whats so ever. It works until you get to the part that only 1 brick shows and its kinda frustrating... If anyone could help me i would appreciate it. I did look up how to fix this but i didn't even find anyone that had this problem. Google searching isn't really that good. Oh and i used Eclipse for this program.
Board Class
package Final;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;
public class Board extends JPanel implements Commons {
private Timer timer;
private String message = "Your Fired";
private Ball ball;
private Paddle paddle;
private Brick bricks[];
private boolean ingame = true;
public Board() {
initBoard();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
bricks = new Brick[N_OF_BRICKS];
setDoubleBuffered(true);
timer = new Timer();
timer.scheduleAtFixedRate(new ScheduleTask(), DELAY, PERIOD);
}
#Override
public void addNotify() {
super.addNotify();
gameInit();
}
private void gameInit() {
ball = new Ball();
paddle = new Paddle();
int k = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
bricks[k] = new Brick(j * 40 + 30, i * 10 + 50);
k++;
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
if (ingame) {
drawObjects(g2d);
} else {
gameFinished(g2d);
}
Toolkit.getDefaultToolkit().sync();
}
private void drawObjects(Graphics2D g2d) {
g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),
ball.getWidth(), ball.getHeight(), this);
g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(),
paddle.getWidth(), paddle.getHeight(), this);
for (int i = 0; i < N_OF_BRICKS; i++) {
if (!bricks[i].isDestroyed()) {
g2d.drawImage(bricks[i].getImage(), bricks[i].getX(),
bricks[i].getY(), bricks[i].getWidth(),
bricks[i].getHeight(), this);
}
}
}
private void gameFinished(Graphics2D g2d) {
Font font = new Font("Verdana", Font.BOLD, 18);
FontMetrics metr = this.getFontMetrics(font);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
g2d.drawString(message,
(Commons.WIDTH - metr.stringWidth(message)) / 2,
Commons.WIDTH / 2);
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
}
private class ScheduleTask extends TimerTask {
#Override
public void run() {
ball.move();
paddle.move();
checkCollision();
repaint();
}
}
private void stopGame() {
ingame = false;
timer.cancel();
}
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
for (int i = 0, j = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
if ((ball.getRect()).intersects(paddle.getRect())) {
int paddleLPos = (int) paddle.getRect().getMinX();
int ballLPos = (int) ball.getRect().getMinX();
int first = paddleLPos + 8;
int second = paddleLPos + 16;
int third = paddleLPos + 24;
int fourth = paddleLPos + 32;
if (ballLPos < first) {
ball.setXDir(-1);
ball.setYDir(-1);
}
if (ballLPos >= first && ballLPos < second) {
ball.setXDir(-1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos >= second && ballLPos < third) {
ball.setXDir(0);
ball.setYDir(-1);
}
if (ballLPos >= third && ballLPos < fourth) {
ball.setXDir(1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos > fourth) {
ball.setXDir(1);
ball.setYDir(-1);
}
}
for (int i = 0; i < N_OF_BRICKS; i++) {
if ((ball.getRect()).intersects(bricks[i].getRect())) {
int ballLeft = (int) ball.getRect().getMinX();
int ballHeight = (int) ball.getRect().getHeight();
int ballWidth = (int) ball.getRect().getWidth();
int ballTop = (int) ball.getRect().getMinY();
Point pointRight = new Point(ballLeft + ballWidth + 1, ballTop);
Point pointLeft = new Point(ballLeft - 1, ballTop);
Point pointTop = new Point(ballLeft, ballTop - 1);
Point pointBottom = new Point(ballLeft, ballTop + ballHeight + 1);
if (!bricks[i].isDestroyed()) {
if (bricks[i].getRect().contains(pointRight)) {
ball.setXDir(-1);
} else if (bricks[i].getRect().contains(pointLeft)) {
ball.setXDir(1);
}
if (bricks[i].getRect().contains(pointTop)) {
ball.setYDir(1);
} else if (bricks[i].getRect().contains(pointBottom)) {
ball.setYDir(-1);
}
bricks[i].setDestroyed(true);
}
}
}
}
}
Brick Class
package Final;
import javax.swing.ImageIcon;
public class Brick extends Sprite {
private boolean destroyed;
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
public boolean isDestroyed() {
return destroyed;
}
public void setDestroyed(boolean val) {
destroyed = val;
}
}
Commons Class
package Final;
public interface Commons {
public static final int WIDTH = 300;
public static final int HEIGTH = 400;
public static final int BOTTOM_EDGE = 390;
public static final int N_OF_BRICKS = 30;
public static final int INIT_PADDLE_X = 200;
public static final int INIT_PADDLE_Y = 360;
public static final int INIT_BALL_X = 230;
public static final int INIT_BALL_Y = 355;
public static final int DELAY = 1000;
public static final int PERIOD = 10;
}
Sprite Class
package Final;
import java.awt.Image;
import java.awt.Rectangle;
public class Sprite {
protected int x;
protected int y;
protected int i_width;
protected int i_heigth;
protected Image image;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
public int getWidth() {
return i_width;
}
public int getHeight() {
return i_heigth;
}
Image getImage() {
return image;
}
Rectangle getRect() {
return new Rectangle(x, y,
image.getWidth(null), image.getHeight(null));
}
}
Breakout Class
package Final;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Breakout extends JFrame {
public Breakout() {
initUI();
}
private void initUI() {
add(new Board());
setTitle("Lord Carl's Demolition Job");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(Commons.WIDTH, Commons.HEIGTH);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Breakout game = new Breakout();
game.setVisible(true);
}
});
}
}
The problem is in checkCollision(). Inside the loop, j will never equal N_OF_BRICKS because of the loop condition. You could change to:
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
int j = 0;
for (int i = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
Also, in the Brick class you neglect to store the x,y coords:
public class Brick extends Sprite {
....
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
// Save these
this.x = x;
this.y = y
}
....
}
Or, add a constructor to the Sprite class and call that from the Brick constructor:
public class Sprite {
....
public Sprite(int x, int y) {
this.x = x;
this.y = y;
}
....
}
public class Brick extends Sprite {
....
public Brick(int x, int y) {
// Call the sprite constructor
super(x, y);
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
....
}
I am trying to create a program that record mouse clicks, draw lines between those points and after some calculations display some circles through a button call. My problem is that I can display the lines or the circles, but not both.
I know there is something overlapping something else, but I am very new to Java and I don't know how to fix it. Here is the code:
package fempack;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.lang.Math;
public class MainFem extends JPanel {
final DrawPoints Npoints = new DrawPoints();
final DrawLines Nline = new DrawLines();
private static final long serialVersionUID = 1L;
private MouseHandler mouseHandler = new MouseHandler();
private Point p1 = new Point(100, 100);
public int Xpoint[][] = new int[500][30];
public int Ypoint[][] = new int[500][30];
private double Xmpoint[][] = new double[500][1000]; // [i γραμμή][συντεταγμένη Χ]
private double Ympoint[][] = new double[500][1000];
private double Vec[][][] = new double[500][2][500]; // [i γραμμή][0,1][0α 1β]
private double dist[] = new double[10000];
private boolean drawing;
private int c1;
private int c2;
public MainFem() {
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
// -------------- Draw by clicking -----------------------
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e)){
drawing=false;
c2++;
}
if(SwingUtilities.isLeftMouseButton(e)){
p1 = e.getPoint();
Xpoint[c1][c2] = p1.x;
Ypoint[c1][c2] = p1.y;
if (c1 > 3) {
for (int j = 0; j<c2+1; j++){
for (int i = 0; i<c1; i++){
if ((Math.abs(Xpoint[i][j]-Xpoint[c1][c2]) < 10) && (Math.abs(Ypoint[i][j]-Ypoint[c1][c2]) < 10)) {
Xpoint[c1][c2] = Xpoint[i][j];
Ypoint[c1][c2] = Ypoint[i][j];
System.out.println(Xpoint[i][j]);
}
}
}
}
if (drawing == true){
Nline.addLine(Xpoint[c1][c2], Ypoint[c1][c2], Xpoint[c1-1][c2], Ypoint[c1-1][c2]);
}
c1++;
drawing = true;
}
}
}
// ---------------- Create Mesh Points --------------------------
public void createmesh() {
int mdi = 0;
for (int j = 0; j<=c2; j++){
for (int i = 0; i<c1-1; i++){
// Υπολογισμός a και b συνιστωσών της εξίσωσης της γραμμής
Vec[i][0][mdi] = (Ypoint[i+1][j] - Ypoint[i][j])/(Xpoint[i+1][j] - Xpoint[i][j]);
Vec[i][1][mdi] = Ypoint[i][j] - Xpoint[i][j]*Vec[i][1][mdi];
// Υπολογισμός μέτρου διανύσματος
dist[mdi] = Math.sqrt(Math.pow(Xpoint[i][j] - Xpoint[i+1][j], 2) + Math.pow(Ypoint[i][j] - Ypoint[i+1][j], 2) );
// Υπολογισμός ενδιάμεσον σημείων
int nkom = 3;
double xa = Xpoint[i][j];
double ya = Ypoint[i][j];
for (int ii = 0; ii <nkom; ii++) {
double a = Vec[i][0][mdi];
double b = Vec[i][1][mdi];
Xmpoint[i][ii] = (-((2*a)*(b - ya) - 2*xa) + Math.sqrt(Math.abs(Math.pow(((2*a)*(b - ya) - 2*xa), 2) - 4*(1 + a*a)*(xa*xa + Math.pow((b - ya),2) - Math.pow(dist[mdi]/nkom,2)))))/(2 + 2*a*a);
Ympoint[i][ii] = a*Xmpoint[i][ii] + b;
double xm11 = Xmpoint[i][ii];
double ym11 = Ympoint[i][ii];
int xm1 = (int) xm11;
int ym1 = (int) ym11;
Npoints.addPoint(xm1, ym1);
System.out.println("i:" + ym11 + "...ii:" + ym1 );
xa = Xmpoint[i][ii];
ya = Ympoint[i][ii];
}
mdi++;
}
}
}
//------------------------- Display ---------------------------
private void display() {
JFrame f = new JFrame("LinePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setPreferredSize(new Dimension(500, 600));
f.setLocationRelativeTo(null);
f.add(Npoints);
f.add(Nline);
JPanel buttonsPanel = new JPanel();
//-----------------Complete---------------
JButton dcomp = new JButton("Complete");
buttonsPanel.add(dcomp);
dcomp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
createmesh();
}
});
//------------------Clean-------------------
JButton clearButton = new JButton("Clear");
buttonsPanel.setBorder(BorderFactory.createLineBorder(Color.black));
buttonsPanel.setPreferredSize(new Dimension(500, 100));
f.add(buttonsPanel, BorderLayout.SOUTH);
buttonsPanel.add(clearButton);
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Nline.clearLines();
}
});
f.pack();
f.setVisible(true);
f.add(this);
}
//---------------------------------------------------------
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MainFem().display();
}
});
}
}
Class to draw lines:
package fempack;
import java.awt.Graphics;
import java.util.LinkedList;
import javax.swing.JPanel;
public class DrawLines extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public DrawLines() {
}
private static class Line{
final int x1;
final int y1;
final int x2;
final int y2;
public Line(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
}
private final LinkedList<Line> lines = new LinkedList<Line>();
public void addLine(int x1, int x2, int x3, int x4) {
lines.add(new Line(x1,x2,x3,x4));
repaint();
}
public void clearLines() {
lines.clear();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
// System.out.println(line);
g.drawLine(line.x1, line.y1, line.x2, line.y2);
}
}
}
And class to draw Circles:
package fempack;
import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.LinkedList;
public class DrawPoints extends JPanel {
private static final long serialVersionUID = 1L;
public DrawPoints() {
}
private static class Point {
final int x;
final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
private final LinkedList<Point> points = new LinkedList<Point>();
public void addPoint(int x, int y) {
points.add(new Point(x,y));
// System.out.println(x);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Point point : points) {
// System.out.println(point);
g.drawOval(point.x, point.y, 5, 5);
}
}
}
Here is my solution to draw the points added in the createmesh(). I did not modify any handling of the points you got from the mouse position. I just tried to refactor and clean up your code.
Now DrawLine and DrawPoint are no more JPanel's they just hold the data you give them and draw to the Graphics-Object you pass to them in public void draw(Graphics g) method, which is called on paint in the DrawPanel-Class. DrawPanel inherits from JPanel and overrides void PaintComponent(Graphics g); to realize this (Thanks to MadProgrammer ;). Also DrawPanel handels the MouseEvents to put the mouse-positions into DrawLines- and DrawPoints-objects.
MainWindow inherits from JFrame and is the MainWindow. It creates all GUI-elements and calls the DrawPanel if necessary.
MainWindow:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainWindow extends JFrame {
private static final long serialVersionUID = 6755417048009930291L;
// begin gui components
JButton clearButton = null;
JButton dcomp = null;
JPanel buttonsPanel = null;
DrawPanel drawPanel = null;
// end gui components
public MainWindow(){
// Add ButtonPanel
add(getDrawPanel(), BorderLayout.CENTER);
add(getButtonPanel(), BorderLayout.SOUTH);
// Add Buttons
getButtonPanel().add(getDcomp());
getButtonPanel().add(getClearButton());
addMouseListener(getDrawPanel());
}
// begin getters and setters for gui components
private DrawPanel getDrawPanel(){
if(drawPanel == null){
drawPanel = new DrawPanel();
drawPanel.setVisible(true);
}
return drawPanel;
}
private JPanel getButtonPanel() {
if(buttonsPanel == null){
buttonsPanel = new JPanel();
buttonsPanel.setBorder(BorderFactory.createLineBorder(Color.black));
buttonsPanel.setPreferredSize(new Dimension(500, 100));
}
return buttonsPanel;
}
private JButton getClearButton() {
if(clearButton == null){
clearButton = new JButton("Clear");
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getDrawPanel().clearLines();
}
});
}
return clearButton;
}
private JButton getDcomp() {
if(dcomp == null){
dcomp = new JButton("Complete");
dcomp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getDrawPanel().createmesh();
getDrawPanel().repaint();
}
});
}
return dcomp;
}
// end begin getters and setters for gui components
//as always program entry-point
public static void main(String[] args) {
MainWindow wnd = new MainWindow();
wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wnd.setPreferredSize(new Dimension(500, 600));
wnd.setLocationRelativeTo(null);
wnd.pack();
wnd.setVisible(true);
}
}
DrawPanel:
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawPanel extends JPanel implements MouseListener {
private static final long serialVersionUID = -7726303639184194659L;
// begin members
private DrawLines dlines;
private DrawPoints dpoints;
// dont know what these members do
private Point p1 = new Point(100, 100);
public int Xpoint[][] = new int[500][30];
public int Ypoint[][] = new int[500][30];
private double Xmpoint[][] = new double[500][1000]; // [i
// γραμμή][συντεταγμένη
// Χ]
private double Ympoint[][] = new double[500][1000];
private double Vec[][][] = new double[500][2][500]; // [i γραμμή][0,1][0α
// 1β]
private double dist[] = new double[10000];
private boolean drawing;
private int c1;
private int c2;
// end members
public DrawPanel() {
dlines = new DrawLines();
dpoints = new DrawPoints();
addMouseListener(this);
}
// begin class logic
public void clearLines(){
dlines.clearLines();
repaint();
}
// dont know what this does
public void createmesh() {
int mdi = 0;
for (int j = 0; j <= c2; j++) {
for (int i = 0; i < c1 - 1; i++) {
// Υπολογισμός a και b συνιστωσών της εξίσωσης της γραμμής
Vec[i][0][mdi] = (Ypoint[i + 1][j] - Ypoint[i][j])
/ (Xpoint[i + 1][j] - Xpoint[i][j]);
Vec[i][1][mdi] = Ypoint[i][j] - Xpoint[i][j] * Vec[i][1][mdi];
// Υπολογισμός μέτρου διανύσματος
dist[mdi] = Math.sqrt(Math.pow(Xpoint[i][j] - Xpoint[i + 1][j],
2) + Math.pow(Ypoint[i][j] - Ypoint[i + 1][j], 2));
// Υπολογισμός ενδιάμεσον σημείων
int nkom = 3;
double xa = Xpoint[i][j];
double ya = Ypoint[i][j];
for (int ii = 0; ii < nkom; ii++) {
double a = Vec[i][0][mdi];
double b = Vec[i][1][mdi];
Xmpoint[i][ii] = (-((2 * a) * (b - ya) - 2 * xa) + Math
.sqrt(Math.abs(Math.pow(
((2 * a) * (b - ya) - 2 * xa), 2)
- 4
* (1 + a * a)
* (xa * xa + Math.pow((b - ya), 2) - Math
.pow(dist[mdi] / nkom, 2)))))
/ (2 + 2 * a * a);
Ympoint[i][ii] = a * Xmpoint[i][ii] + b;
double xm11 = Xmpoint[i][ii];
double ym11 = Ympoint[i][ii];
int xm1 = (int) xm11;
int ym1 = (int) ym11;
dpoints.addPoint(xm1, ym1);
System.out.println("i:" + ym11 + "...ii:" + ym1);
xa = Xmpoint[i][ii];
ya = Ympoint[i][ii];
}
mdi++;
}
}
}
// end class logic
// begin MouseListener implementation
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
drawing = false;
c2++;
}
if (SwingUtilities.isLeftMouseButton(e)) {
p1 = e.getPoint();
Xpoint[c1][c2] = p1.x;
Ypoint[c1][c2] = p1.y;
if (c1 > 3) {
for (int j = 0; j < c2 + 1; j++) {
for (int i = 0; i < c1; i++) {
if ((Math.abs(Xpoint[i][j] - Xpoint[c1][c2]) < 10)
&& (Math.abs(Ypoint[i][j] - Ypoint[c1][c2]) < 10)) {
Xpoint[c1][c2] = Xpoint[i][j];
Ypoint[c1][c2] = Ypoint[i][j];
System.out.println(Xpoint[i][j]);
}
}
}
}
if (drawing == true) {
dlines.addLine(Xpoint[c1][c2], Ypoint[c1][c2],
Xpoint[c1 - 1][c2], Ypoint[c1 - 1][c2]);
}
c1++;
drawing = true;
repaint();
}
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
// end MouseListener implementation
// beging PAINTING
#Override
protected void paintComponent(Graphics g) {
System.out.println("paintComponent");
super.paintComponent(g);
dlines.draw(g);
dpoints.draw(g);
}
// end PAINTING
}
DrawPoints:
import java.awt.Graphics;
import java.util.LinkedList;
public class DrawPoints {
public DrawPoints() {
}
private static class Point {
final int x;
final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
private final LinkedList<Point> points = new LinkedList<Point>();
public void addPoint(int x, int y) {
points.add(new Point(x, y));
}
public void draw(Graphics g){
for (Point point : points) {
g.drawOval(point.x, point.y, 5, 5);
}
}
}
DrawLines:
import java.awt.Graphics;
import java.util.LinkedList;
public class DrawLines{
public DrawLines() {
}
private static class Line {
final int x1;
final int y1;
final int x2;
final int y2;
public Line(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
}
private final LinkedList<Line> lines = new LinkedList<Line>();
public void addLine(int x1, int x2, int x3, int x4) {
lines.add(new Line(x1, x2, x3, x4));
}
public void clearLines() {
lines.clear();
}
public void draw(Graphics g){
for (Line line : lines) {
g.drawLine(line.x1, line.y1, line.x2, line.y2);
}
}
}
I think its a good idea to handle things like this. You want to paint on a Panel or something so pass it to the object which hold your data and let them draw to their common canvas like I did with the void draw(Graphics g) method in DrawPoints- and DrawLines-class.
I hope this will help you.
Fell free to ask if something is unclear.
I have a window that dynamically updates the buffered image set on a JPanel using javax.swing.Timer
Everything works as expected but every time I invoke the dynamic update there seems to be another buffered image displayed below the currently updating one.
The image of the window before and after clicking the train button (which triggers the dynamic update) is given below.
Since the image below the dynamically updating image looks like the initial screen. I rechecked the following
Whether I'm adding two dynamic lattice objects to the same panel
Multiple calls of repaint()
Unwanted initialization of the dynamic lattice
I could not find any of these in my code. I cannot post the code since it is huge and whenever I'm creating a minimal set to reproduce the same behavior it is not there. So I'm sure I'm missing something or doing something on my project code which triggers this behavior. Any suggestions on how to debug this or why it is doing something like this?
Thank you
EDIT
SSCCE is give below. If executing, click the load button followed by the train button to get the error.
(MapScreen.java - Main Class)
package test;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import java.awt.Font;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import test.DisplayLattice;
import test.SelfOrganizingMap;
public class MapScreen extends JFrame {
private double NUM_ITERATIONS = 0.0;
private double ETA = 0.0;
private double SPREAD_FACTOR = 0.0;
private double RADIUS = 0.0;
private int WIDTH = 0;
private int HEIGHT = 0;
private SelfOrganizingMap SOM = null;
private Timer REFRESH_TIMER = null;
private JPanel pnlMap;
private JButton btnLoadParameters;
private JButton btnTrain;
private DisplayLattice displayScreen;
public MapScreen(double iterations, double learningRate, double spreadFactor, double radius, int option, int width, int height, int mapOption) {
NUM_ITERATIONS = iterations;
ETA = learningRate;
SPREAD_FACTOR = spreadFactor;
RADIUS = radius;
WIDTH = width;
HEIGHT = height;
setType(Type.UTILITY);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Map");
setSize(650, 800);
setLocation(150,150);
getContentPane().setLayout(null);
displayScreen = new DisplayLattice();
pnlMap = displayScreen;
pnlMap.setBounds(6, 130, 600, 600);
getContentPane().add(pnlMap);
btnLoadParameters = new JButton("Load Parameters");
btnLoadParameters.setFont(new Font("Tahoma", Font.PLAIN, 11));
btnLoadParameters.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
SOM = new SelfOrganizingMap(10000,0,0,13,displayScreen);
}
});
btnLoadParameters.setBounds(192, 46, 126, 23);
getContentPane().add(btnLoadParameters);
btnTrain = new JButton("Train");
btnTrain.setFont(new Font("Tahoma", Font.PLAIN, 11));
btnTrain.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
initialObjectSetUp();
}
});
btnTrain.setBounds(192, 72, 62, 23);
getContentPane().add(btnTrain);
}
private void initialObjectSetUp()
{
SOM.initTrainSOM(null, 100, 0.25);
REFRESH_TIMER = new Timer(100, SOM);
REFRESH_TIMER.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
MapScreen frame = new MapScreen(100,0.25,0.0,0.0,1,100,0,0);
frame.setVisible(true);
}
});
}
}
(SelfOrganizingMap.java)
package test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SelfOrganizingMap implements ActionListener {
private Node[][] SOM = null;
private double[][] NORM_MAP = null; //holds the L2 norm of each vector in the SOM[][].
#SuppressWarnings("unused")
private int GRID_OPTION = 0;
private int INPUT_DIMENSION = 0;
private int NUMER_OF_ITERATIONS = 0;
private int CURRENT_ITERATION=0;
private int SOM_HORIZONTAL_LENGTH = 0;
private int SOM_VERTICAL_LENGTH = 0;
private double INITIAL_LEARNING_RATE = 0.0;
private double LEARNING_RATE = 0.0;
private double MAX_RADIUS = 0.0; //radius at first epoch (t = 0)
private double RADIUS = 0.0;
private double TIME_STEP = 0.0; //lambda of X(t) = t0 * exp(-t/lambda)
private String INPUT_SAMPLES = null;
private DisplayLattice DISPLAY_SCREEN = null;
public SelfOrganizingMap(int numberOfNodes, int depth, int grid, int inputDimensison, DisplayLattice screen)
{
INPUT_DIMENSION = inputDimensison;
if(grid == 0)
{
int side = (int)Math.sqrt(numberOfNodes);
SOM = new Node[side][side];
NORM_MAP = new double[side][side];
GRID_OPTION = grid;
MAX_RADIUS = side/2;
DISPLAY_SCREEN = screen;
}
RADIUS = MAX_RADIUS;
}
public void initTrainSOM(String input, int iterations, double learningRate)
{
NUMER_OF_ITERATIONS = iterations;
INITIAL_LEARNING_RATE = learningRate;
LEARNING_RATE = INITIAL_LEARNING_RATE;
TIME_STEP = NUMER_OF_ITERATIONS/Math.log(MAX_RADIUS);
INPUT_SAMPLES = input;
}
private void singleCompleteRun()
{
DISPLAY_SCREEN.render();
System.out.println(CURRENT_ITERATION);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(CURRENT_ITERATION <= NUMER_OF_ITERATIONS)
{
singleCompleteRun();
CURRENT_ITERATION++;
}
}
}
(DisplayLattice.java)
package test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
#SuppressWarnings("serial")
public class DisplayLattice extends JPanel {
private BufferedImage img = new BufferedImage(500, 500, 1);
public void paintComponent(Graphics g) {
if (img == null)
super.paintComponents(g);
else
g.drawImage(img, 0, 0, this);
}
public void render() {
float cellWidth = 100;
float cellHeight = 100;
int imgW = img.getWidth();
int imgH = img.getHeight();
float r, g, b;
Graphics2D g2 = img.createGraphics();
g2.setBackground(Color.black);
g2.clearRect(0,0,imgW,imgH);
for (int x=0; x<100; x++) {
for (int y=0; y<100; y++) {
r = (float)Math.random();
g = (float)Math.random();
b = (float)Math.random();
g2.setColor(new Color(r,g,b));
g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
(int)cellWidth+1, (int)cellHeight+1);
}
}
g2.setColor(Color.black);
g2.dispose();
repaint();
}
public BufferedImage getImage() {
if (img == null)
img = (BufferedImage)createImage(500, 500);
return img;
}
public void setImage(BufferedImage bimg) {
img = bimg;
}
}
(Node.java - Structure class for the SOM)
package test;
public class Node {
private int DIMENSION = 0;
private int POSITION_X = 0;
private int POSITION_Y = 0;
private double ACTIVATION_VALUE = 0.0;
public Node(int Dimensions, int x, int y)
{
DIMENSION = Dimensions;
setWeightVector();
POSITION_X = x;
POSITION_Y = y;
}
public int getX() {
return POSITION_X;
}
public int getY() {
return POSITION_Y;
}
public double getACTIVATION_VALUE() {
return ACTIVATION_VALUE;
}
public void setPOSITION_X(int x) {
POSITION_X = x;
}
public void setPOSITION_Y(int y) {
POSITION_Y = y;
}
public void setACTIVATION_VALUE(double y) {
ACTIVATION_VALUE= y;
}
private void setWeightVector()
{
double temp[] = new double[DIMENSION];
for(int i = 0; i<temp.length ; i++)
{
temp[i] = Math.random();
}
}
}
The problem is your DiaplyLattice class.
You overrode paintComponent but you invoke super.paintComponents(g). Notice the extra s you have at the end of paintComponents! This of course is unwanted and should be super.paintComponent(g);
I would have you method as follow:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
Now, just as a good advice/tip to give, don't use null layout and rather use LayoutManager's and possibly use several level of nesting. It's always easier.
Also, you missed an important thing in SSCCE: the SHORT part. Meaning that you should remove anything unnecessary and have a single file to copy/paste.
I am creating yet another version of pong. This one uses 3 paddles for each person. I have spent almost two hours trying to figure out why the two other paddles are not detecting when the ball strikes the paddle. The original (top) paddle does detect the hit and properly updates the hit counter. I have tried separate if statements, else if statements etc., with no success. I created three Y variables to detect the position of all three paddles still no luck.
Any suggestions?
import java.awt.Point;
public class box {
private int xTopLeft, yTopLeft, width, height;
int xBall, yBall;
private int radius = 5;
int xBallVel, yBallVel;
int VELOCITY_MAG =5;
public Point ballLoc = new Point();
private int paddleY;
private int paddleYP2;
private int paddleYP3;
private int paddleWidth = 20;
private int paddleWidth2 = 20;
private int paddleWidth3 = 20;
int hitCount = 0;
int missCount = 0;
private boolean updating=true;
public int getBallRadius()
{
return radius;
}
public Point getBallLoc()
{
ballLoc.x = xBall;
ballLoc.y = yBall;
return ballLoc;
}
public box(int x, int y, int w, int h)
{
xTopLeft =x;
yTopLeft = y;
width =w;
height = h;
createRandomBallLocation();
}
public void updatePaddle(int y)
{
paddleY = y;
}
public void updatePaddleP2(int yp2)
{
paddleYP2 = yp2;
}
public void updatePaddleP3(int yp3)
{
paddleYP3 = yp3;
}
public int getPaddleWidth()
{
return paddleWidth ;
}
public int getPaddleWidth2()
{
return paddleWidth2 ;
}
public int getPaddleWidth3()
{
return paddleWidth3 ;
}
public int getPaddleY()
{
System.out.println(paddleY);
return paddleY;
}
public int getPaddleP2()
{
System.out.println(paddleYP2);
return paddleYP2;
}
public int getPaddleP3()
{
return paddleYP3;
}
public int getHitCount()
{
return hitCount;
}
public int getMissCount()
{
return missCount;
}
public int velMag()
{
return VELOCITY_MAG;
}
public void update()
{
if (!updating) return;
xBall = xBall + xBallVel;
yBall = yBall + yBallVel;
if (xBall + radius >= xTopLeft+width && xBallVel>=0)
if ((yBall >= paddleY-paddleWidth && yBall <= paddleY + paddleWidth)
|| (yBall >= paddleYP2-paddleWidth2 && yBall <= paddleYP2 + paddleWidth2 )
|| (yBall >= paddleYP3-paddleWidth3 && yBall <= paddleYP3 + paddleWidth3 ))
{
// hit paddles
xBallVel = - xBallVel;
hitCount++;
}
else if (xBall+radius >= xTopLeft + width)
{
xBallVel = - xBallVel;
}
if (yBall+radius >= yTopLeft + height && yBallVel >= 0)
{
yBallVel = - yBallVel;
}
if (yBall-radius <= yTopLeft && yBallVel <=0)
{
yBallVel = - yBallVel;
}
if (xBall-radius <= xTopLeft && xBallVel <= 0)
{
xBallVel = - xBallVel;
}
}
public void createRandomBallLocation()
{
xBall = xTopLeft + radius +
(int)((width-2*radius)*Math.random());
yBall = yTopLeft + radius +
(int)((height-2*radius)*Math.random());
xBallVel = velMag();
yBallVel = velMag();
}
}
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
public class Pong extends JFrame
implements Runnable{
box box = null;
int top, left, width, height;
final int LINE_THICKNESS = 5;
Graphics bufferGraphics;
int sleep=25;
public Pong(String name)
{
super(name);
int windowWidth = 1024;
int windowHeight =768;
this.setSize(windowWidth, windowHeight);
this.setResizable(false);
this.setLocation(400, 150);
this.setVisible(true);
this.createBufferStrategy(4);
MyMouseClick mmc = new MyMouseClick();
addMouseListener(mmc);
MyMouseMotion mmm = new MyMouseMotion();
addMouseMotionListener(mmm);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Thread thread = new Thread(this);
thread.start();
}
public void run()
{
while(true)
{
try
{
if (box != null)
{
box.update();
repaint();
}
Thread.sleep(sleep);
}
catch (InterruptedException e)
{}
}
}
public void paint(Graphics g)
{
BufferStrategy bf = this.getBufferStrategy();
g = bf.getDrawGraphics();
Dimension d = getSize();
if (box ==null)
{
Insets insets = getInsets();
left = insets.left;
top = insets.top;
width = d.width-left - insets.right;
height = d.height - top - insets.bottom;
box = new box(left, top, width, height);
}
g.fillRect(0,0, d.width, d.height);
g.setColor(Color.BLUE);
g.setFont(new Font("Arial", 20, 30));
g.drawString("Hits: "+box.getHitCount(), 20, 60);
g.setColor(Color.red);
g.setFont(new Font("Arial", 20, 30));
g.drawString("Misses: "+box.getMissCount(), 20, 380);
g.fillRect(left, top, left+width, LINE_THICKNESS); // top of box
g.setColor(Color.white);
g.fillRect(left, top+height, left+width, LINE_THICKNESS); // bottom of box
g.drawLine(left, top, left, top+height); // left of box
g.drawLine(left+width, top, left+width, top+height); // right side
Point ballLoc = box.getBallLoc();
int radius = box.getBallRadius();
g.fillOval(ballLoc.x - radius, ballLoc.y-radius, 2*radius, 2*radius);
// Draw paddles Player 1
g.setColor(Color.yellow);
int yp = box.getPaddleY();
int yp2 = box.getPaddleP2();
int yp3 = box.getPaddleP3();
int yw = box.getPaddleWidth();
int yw2 = box.getPaddleWidth2();
int yw3 = box.getPaddleWidth3();
g.fillRect(left+width-5, yp-yw, 4, 50);
g.fillRect(left+width-5, (yp2-yw2)+280, 4, 50);
g.fillRect(left+width-5, (yp3-yw3)+140, 4, 50);
bf.show();
}
// *********************** Inner classes
class MyMouseClick extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
box = null;
repaint();
}
}
class MyMouseMotion extends MouseMotionAdapter
{
public void mouseMoved(MouseEvent e)
{
int y = e.getY();
int y2 = e.getY();
int y3 = e.getY();
if (box != null)
{
box.updatePaddle(y);
box.updatePaddleP2(y2);
box.updatePaddleP3(y3);
repaint();
}
}
}
// ************************************
public static void main(String[] args) {
Pong t = new Pong("Three Paddle Pong");
t.setVisible(true);
} // end of main
}
In the paint method you do paint your 3 paddles at different y positions, but for the actual paddle positions, paddleYP? which are used for collision detection, you just set the 3 paddles to the same y in mouseMoved.