How to implement chain of responsibility with Java Swing - java

I have the task of creating a simple drawing app, where one can draw basic shapes (ovals,lines,rectangles) with border and fill colors of choice, using Java Swing and MVC.
The shapes part of the model is implemented using the composite pattern. The functionality to be implementing is drawing (this is already handled by the shapes classes themselves), resizing, moving and deleting shapes and I am supposed to use chain of responsibility (CoR) pattern to accomplish this.
CoR makes sense to me in theory, but I have difficulty grasping how I can apply it for implementing the functionality in practice. I understand that when I click on the drawing panel the program should recognize which shape is selected and then I can implement the methods for resizing,moving,deleting.
So what I need advice on is:
1) how to practically implement CoR pattern here?
2) what is a good way to implement the functionality for resizing, moving, deleting? In own concrete handler classes, as methods in the shapes classes, other?
Many thanks for help.

Here is a proposed basic implementation of CoR.
For ease of use the following code is a one-file mre : the entire code can be copy-pasted into ShapeManipulator.java and run:
public class ShapeManipulator {
public static void main(String[] args) {
Shape s1 = new Shape();
Shape s2 = new Shape();
Shape s3 = new Shape();
ShapeManipulationBase move = new MoveHandler();
ShapeManipulationBase resize = new ResizeHandler();
ShapeManipulationBase delete = new DeleteHandler();
move.setXparam(50).setYparam(25).handle(s1);
resize.setXparam(100).setYparam(250).handle(s1);
resize.setXparam(200).setYparam(20).handle(s2);
delete.handle(s3);
}
}
//CoR basic interface
interface ShapeManipulationHandler {
void handle(Shape shape);
}
//base class allows swtting of optional x, y parameters
abstract class ShapeManipulationBase implements ShapeManipulationHandler {
protected int Xparam, Yparam;
//setters return this to allow chaining of setters
ShapeManipulationBase setXparam(int xparam) {
Xparam = xparam;
return this;
}
ShapeManipulationBase setYparam(int yparam) {
Yparam = yparam;
return this;
}
#Override
public abstract void handle(Shape shape) ;
}
class MoveHandler extends ShapeManipulationBase {
#Override
public void handle(Shape shape) {
System.out.println("Moving "+ shape + " by X="+ Xparam + " and Y="+ Yparam);
}
}
class ResizeHandler extends ShapeManipulationBase {
#Override
public void handle(Shape shape) {
System.out.println("Resizing "+ shape + " by X="+ Xparam + " and Y="+ Yparam);
}
}
class DeleteHandler extends ShapeManipulationBase {
#Override
public void handle(Shape shape) {
System.out.println("Deleting "+ shape);
}
}
class Shape{
private static int shapeCouner = 0;
private final int shapeNumber;
Shape() {
shapeNumber = ++shapeCouner;
}
#Override
public String toString() {
return "Shape # "+shapeNumber;
}
}

Related

TheBennyBox Engine - Performance Friendly Instanced Static Meshes Like In UE4

I'm using the java game engine made by thebennybox to create my own engine. Previously I worked with UE4 where you could have Static Mesh Actors, in his engine this would probably be a GameObject with a MeshRenderer component attached to it:
GameObject staticMeshActor_Grass = new GameObject();
AddObject(staticMeshActor_Grass.addComponent(new MeshRenderer(
new Mesh("plane.obj"), new Material(
new Texture("T_Grass_BC.png"), 1, 8,
new Texture("T_Grass_N.png")))));
Now I'm trying to create a large field of these grass tiles but since these are all their individual GameObjects (or Actors in UE4 terms) after 16x16 tiles it starts to cripple the frame rate!
I believe I can solve this problem if I make instances of multiple static meshes inside one GameObject in order to make it performance friendly. In UE4 this feature is called 'Instanced Static Mesh Component' which allows for that and I would like to have something similar.
Here's the GameObject class made by thebennybox:
public class GameObject
{
private ArrayList<GameObject> m_children;
private ArrayList<GameComponent> m_components;
private Transform m_transform;
private CoreEngine m_engine;
public GameObject()
{
m_children = new ArrayList<GameObject>();
m_components = new ArrayList<GameComponent>();
m_transform = new Transform();
m_engine = null;
}
public GameObject AddChild(GameObject child)
{
m_children.add(child);
child.SetEngine(m_engine);
child.GetTransform().SetParent(m_transform);
return this;
}
public GameObject AddComponent(GameComponent component)
{
m_components.add(component);
component.SetParent(this);
return this;
}
public void InputAll(float delta)
{
Input(delta);
for(GameObject child : m_children)
child.InputAll(delta);
}
public void UpdateAll(float delta)
{
Update(delta);
for(GameObject child : m_children)
child.UpdateAll(delta);
}
public void RenderAll(Shader shader, RenderingEngine renderingEngine)
{
Render(shader, renderingEngine);
for(GameObject child : m_children)
child.RenderAll(shader, renderingEngine);
}
public void Input(float delta)
{
m_transform.Update();
for(GameComponent component : m_components)
component.Input(delta);
}
public void Update(float delta)
{
for(GameComponent component : m_components)
component.Update(delta);
}
public void Render(Shader shader, RenderingEngine renderingEngine)
{
for(GameComponent component : m_components)
component.Render(shader, renderingEngine);
}
public ArrayList<GameObject> GetAllAttached()
{
ArrayList<GameObject> result = new ArrayList<GameObject>();
for(GameObject child : m_children)
result.addAll(child.GetAllAttached());
result.add(this);
return result;
}
public Transform GetTransform()
{
return m_transform;
}
public void SetEngine(CoreEngine engine)
{
if(this.m_engine != engine)
{
this.m_engine = engine;
for(GameComponent component : m_components)
component.AddToEngine(engine);
for(GameObject child : m_children)
child.SetEngine(engine);
}
}
}
The AddObject() method shown in the first part comes from an abstract class and eventually calls the method AddChild(GameObject child) inside the GameObject class. As you can see we have an ArrayList of GameObjects and GameComponents. Now I would have to implement some method in order to support the creation of multiple mesh instances inside one GameObject.
I've already tried to add multiple MeshRenderer components to one GameObject but this didn't work out. Maybe someone has a suggestion how I might go about this?
if you're really interested and want to help me you can download the engine here: https://github.com/BennyQBD/3DGameEngine
Just use 'Open Projects From File System..' in eclipse, choose the directory of this folder and once you've done that you should be able to run the program.
Thanks a lot for your help!
this might be what you are looking for:
http://www.java-gaming.org/topics/issues-with-batching-meshes/37809/view.html
They mention that ThinMatrix has created a tutorial about instancing meshes, hope this helps you!

Encapsulation of array with reference variables

I intend to write a program that simulates particles collisions in one or more dimension. For the 2D case, I would also like to make a GUI that shows the particles.
I have a main class, ParticleCollider, which contains an inner class, Particle, an array of said Particlesas well as some methods for updating the positions and velocities of the particles. The class roughly looks like this:
class ParticleCollider {
class Particle {
private double mass;
private double[] pos;
//plus some other private class variables
public Particle(double mass, double[] pos) {
this.mass = mass;
this.pos = pos;
}
}
private Particle[] pArray;
//Details of constructor are irrelevant
public ParticleCollider() {
}
//Do stuff to particles in pArray, i.e. change their positions and velocitites
public void update() {
//For example
pArray[0].pos[0] = 0;
}
}
In the graphics class, I want to be able to access the Particles so that I can find their positions and radii for drawing purposes. One way would of course be to add a method getParticlesin ParticleColliderto return the array of Particles, pArray. My question is now if this would be considered a violation of encapsulation. Because the Particleclass has no setters, I cannot change the Particles. Also, because an array hase fixed length, I cannot add any Particles. The only thing I could do, which I guess is pretty bad, is take some Particleand assign it the value of null.
EDIT
It has been suggested that I use a List instead of an array and provide an iterator to said List. It would seem to me that this would not solve the encapsulation problem. Regardless, I'm relucant to abandon the array because I need to be able to select a random Particle in the collection of Particles and then iterate it cyclically.
How about using this pattern:
public class Particle {
// Particle code
}
public class Particles implements Iterable<Particle> {
ArrayList<Particle> myParticles = new ArrayList<Particle>();
public void add(Particle particle) { myParticles.add(particle); }
public Iterator<Particle> iterator() {
return myParticles.iterator();
}
// more code on particles
}
void bla() {
Particles particles = new Particles();
particles.add(new Particle());
particles.add(new Particle());
for (Particle particle : particles) {
System.out.println("P="+particle);
}
}
If you want to inhibit the remove() on this iterator you might use this pattern:
public static class Particles implements Iterable<Particle> {
ArrayList<Particle> myParticles = new ArrayList<Particle>();
public void add(Particle particle) { myParticles.add(particle); }
public Iterator<Particle> iterator() {
return new Iterator<Particle>() {
Iterator<Particle> listIterator = myParticles.iterator();
#Override
public boolean hasNext() {
return listIterator.hasNext();
}
#Override
public Particle next() {
return listIterator.next();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}

Calling a method from JFrame from another class

I am currently making a terrain generator, everything works fine in one class but I am going to be expanding my application.
Currently I have a JFrame class which holds everything, generating the terrain, painting the terrain, finding locations etc.
I want to add another class that will generate the terrain but when I create this class I need to access fields from the main JFrame class and when I do I get a stack overflow error - here is my code.
public class Simulator extends Applet
{
//fields
public Simulator()
{
grid = new int[100][100];
inhabGrid = new boolean[grid.length][grid.length];
gridSize = grid.length - 1;
dist = grid.length;
TerrainGenerator gen = new TerrainGenerator();
setSize(dist,dist);
seedGrid();
findInhabLocation();
printGridToConsole();
}
public void paint(Graphics g)
{
//panting the grid
}
public void seedGrid()
{
//seeding
}
public boolean generateTerrain(int x1,int y1, int x2, int y2)
{
//terrain generator
}
public boolean mouseUp(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public boolean keyEvents(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public void findInhabLocation()
{
//find best inhabitant location
}
public int locateWater(int x, int y)
{
//finding closest water
}
public int locateJungle(int x, int y)
{
//finding closest jungle
}
}
}
That works fine in its own class but when I create a class for example:
public class TerrainGenerator
{
Simulator sim = new Simulator();
}
I know this has something to do with the constructor and it's something silly I am doing, what would be the best way of splitting up this app into classes, for example terrain generator, inhabitants etc
For example I want to be able to call a method from the 'TerrainGenerator' class and call i.e. terrainGenerator.generateTerrain
Your TerrainGenerator creates a Simulator object and vice versa, hence you'll end up with infinitely many objects (but at some point the stack is full and a stack overflow exception is thrown instead...)
Instead of creating a new Simulator in your TerrainGenerator, you should pass a reference to your current Simulator (well, actually, that is not a great design either, but I'm not gonna confuse you with the problems of circular references).
Heuster answer is correct, furthermore, I think you could take look at MVC to help you organize your classes.
Depending which should be the parent, you can pass in the instantiated class to the other, ie;
private final TerrainGenerator gen; //if you need to save this.
public Simulator(TerrainGenerator terrainGenerator)
{
this.gen = terrainGenerator;
....etc
}
public class TerrainGenerator
{
Simulator sim = new Simulator(this);
}
or
private final TerrainGenerator gen; //if you need to save this.
public Simulator()
{
this.gen = new TerrainGenerator(this);
....etc
}
private final Simulator sim; //If you need to save it.
public class TerrainGenerator
{
public TerrainGenerator(Simulator simulator) {
this.sim = simulator;
}
}

method does not override or implement a method from a supertype error

I'm trying to design an undo/redo mechanism to my Chess game.. I decided to use stack data structure which is going to build on an ArrayList.. I also want that my UndoStack and RedoStack classes should be singleton.. However i'm getting
method does not override or implement a method from a supertype
pop() in UndoStack cannot implement pop() in IStackable
return type Move is not compatible with cgas5.Move
where Move is a type-variable:
Move extends Object declared in class UndoStack
error..
Here is my IStackable interface:
package cgas5;
public interface IStackable {
abstract public Move pop();
abstract public void push(Move m);
}
and my UndoStack class
package cgas5;
import java.util.ArrayList;
public class UndoStack<Move> extends ArrayList<Move> implements IStackable {
UndoStack undoStack;
private UndoStack() {
undoStack = new UndoStack();
}
public UndoStack getUndoStack() {
if (undoStack == null) {
undoStack = new UndoStack();
}
return undoStack;
}
#Override
public Move pop() {
Move m = get(size() - 1);
remove(size() - 1);
return m;
}
#Override
public void push(Move m) {
add(m);
}
}
and if it's necessary my Move class:
package cgas5;
public class Move {
private Piece pieceToMove;
private Square currentSquare;
private Square targetSquare;
private Piece capturedPiece;
private Piece promotedPiece;
public Move(){
}
public Move(Piece pieceToMove, Square currentSquare, Square targetSquare){
this.pieceToMove = pieceToMove;
this.currentSquare = currentSquare;
this.targetSquare = targetSquare;
}
public Piece getPieceToMove() {
return pieceToMove;
}
public void setPieceToMove(Piece pieceToMove) {
this.pieceToMove = pieceToMove;
}
public Square getCurrentSquare() {
return currentSquare;
}
public void setCurrentSquare(Square currentSquare) {
this.currentSquare = currentSquare;
}
public Square getTargetSquare() {
return targetSquare;
}
public void setTargetSquare(Square targetSquare) {
this.targetSquare = targetSquare;
}
public Piece getCapturedPiece() {
return capturedPiece;
}
public void setCapturedPiece(Piece capturedPiece) {
this.capturedPiece = capturedPiece;
}
public Piece getPromotedPiece() {
return promotedPiece;
}
public void setPromotedPiece(Piece promotedPiece) {
this.promotedPiece = promotedPiece;
}
}
Thanks in advance..
This is the problem:
public class UndoStack<Move> extends ArrayList<Move>
That's using Move as a generic type parameter, whereas really you don't want a generic type at all - you just want to use Move as the type argument for ArrayList<E>. You want:
public class UndoStack extends ArrayList<Move>
That should fix the problem - although personally I'd strongly recommend using composition instead of inheritance here. (In other words, make your UndoStack type contain an ArrayList<Move> - or something similar - rather than subclassing it.)
Additionally, this is never going to work:
UndoStack undoStack;
private UndoStack() {
undoStack = new UndoStack();
}
That means that to create an UndoStack, you need to create another UndoStack... how do you expect that to happen? You'll currently get a stack overflow exception... why do you need the variable at all?

Retrieve object from Java Vector by using its class name

I will start by explaining the scenario.
I have to create a Vector to hold a list of Circles.
Then I create a circle object, and add it to the Vector.
Finally I have to print the state of each circle in the list (the state isn't important to define, just it's colour and position etc).
Basically my problem is, how do I hold the circles so that I can then pass in the name of one of them and it will print the correct circle's state. It may be clearer to show you my code.
I have 3 classes, that main one called Lab83Test, the Vector one, called CircleList, and the Circle one, called Circle. (The formatting has gone weird and I can't fix it, so apologies!)
Lab83Test:
public class Lab83Test {
public static void main(String[] args) {
makeNewCircle();
}
public static void makeNewCircle() {
CircleList newList = new CircleList();
Circle newCircle = new Circle();
newList.addCircle(newCircle);
newCircle.makeVisible();
newList.printDetails();
}
}
CircleList:
import java.util.Vector;
public class CircleList {
private Vector circleVector;
public CircleList() {
circleVector = new Vector();
}
public void addCircle(Circle circleName) {
circleVector.add(circleName);
printDetails();
}
public void addCircleToPlace(Circle circleName, int pos) {
circleVector.add(pos, circleName);
printDetails();
}
public void removeCircleFromPos(int pos) {
circleVector.remove(pos);
printDetails();
}
public void removeAllCircles(int pos) {
circleVector.clear();
printDetails();
}
public void printDetails() {
}
}
The circle class isn't too important, and it has a lot of methods for moving the circle and stuff. The main thing is that it has to return its state.
If you just want to iterate over all Circel in your list and print their name, you can do it this way:
public void printDetails() {
for (Circle c: circleVector) {
System.out.println(String.format("%s: center=(%.1f/%.1f) radius=%.1f", c.getName(), c.getCenterX(), c.getCenterY(), c.getRadius()));
}
}
I don't know how your Circle class looks so I just assumed some method names.
If you want to find a specific circle by name:
for (Circle c: circleVector) {
if (c.getName().equals(nameToFind)) return c;
}
Or you could use a Map<String, Circle> instead of your vector and just do return circleMap.get(name);. Your addCircle() would then look like this:
public void addCircle(Circle circle) {
circleMap.add(circle.getName(), circle);
printDetails();
}
Edit1: regarding your comment: Your vector does not have a defined type. Change this:
...
public class CircleList {
private Vector<Circle> circleVector;
public CircleList() {
circleVector = new Vector<Circle>();
}
...

Categories