Displaying 2D array contents on GUI colours - java

I'm in the process of creating a agent bases modelling program. So far I have the relavent classes to model a simulator, grid, different agents etc. I've also created a 2D array of object e.g. agents moving around the array doing whatever.
I am familary with creating simple GUI's but how do I come about creating a pane\panel which then is added to the GUI. which shows the 2D array on run time with each object with its corresponding colour. Also I want to try and use the MVC pattern to basically display the simulation data differently. Such as one pane shows the different objects colour and another pane showing the same objects but every objects angry levels with different shades of red. Any guidelines would be really helpful also similar tutorials.
Thanks

I'd create a queue (JMS for a very big list of agents, but there are some in-memory queue implementations that are faster to use) and would allow all your agents to write their states in there. Then in another side, I'd write a consumer that listens to the queue to get these states to be processed by your GUI as they're coming.
If there are too many events, you may want to process them in batches, periodically, according to some refresh rate that makes sense for you.

You could use a GUI API like awt and swing (look e.g. at Java 2D game graphics), to create a canvas, upon which you would draw a representation of your system. For example, a set of circles and edges, if the circle is filled, there is an agent there, you can hover mouse over it and or click on it and another panel shows some relevant properties of the agent. Maybe an arrow from a filled circle indicates where the agent is going to go next.
You can instantiate a canvas (like java.awt.canvas), it fits into your GUI as any other widget (panel combo box etc) does it has a size you can add scrollbars etc. As opposed to other controls like combo box, a canvas is a 2d area on which you draw whatever you want.
The MVC is a design structure that separates application concerns along view, control, model axis. Whereas you could put all your control logic such as user input handling, database connection handling, network operations all that could be Don in one place in your canvas class event handling methods, in MVC you would separate all control logic from canvas, canvas event handler would just call the apprpriate controller method (such as handleNewFile). In turn the controller queries the model and tells the view what to show (for instance it loops over all agents in your model and "adds" an agent to the view. The view is where you decide how to represent the agent the controller nothing about representation.

One of the easier ways to go is to create a new Class that extends javax.swing.panel and override the paintComponent()-method.
In the constructor of the new class pass a reference to your 2D-Array.
In your overriden paintComponent()-method do something like this:
public void paintComponent(Graphics g) {
for (int x=0;x<arrayWidth;x++) {
for (int y=0;y<arrayHight;y++) {
switch (array[x][y]) {
case 1: g.setColor(Color.RED);break;
case 2: g.setColor(Color.BLUE);break;
case 3: g.setColor(Color.GREEN);break;
case 4: g.setColor(Color.YELLOW);break;
}
g.drawRect(x*10,y*10,10,10);
}
}
}
Just fit the numbers and colors to your needs.
Edit: if you have some kind of values that can't be used in a switch statement (like e.g. custom classes or Strings in older Java-versions) just replace it with if/elseifs:
public void paintComponent(Graphics g) {
for (int x=0;x<arrayWidth;x++) {
for (int y=0;y<arrayHight;y++) {
if (array[x][y].equals(value1)) {
g.setColor(Color.RED);
} else if (array[x][y].equals(value2)) {
g.setColor(Color.BLUE);
} else if (array[x][y].equals(value3)) {
g.setColor(Color.GREEN);
} else {
g.setColor(Color.YELLOW);
}
g.drawRect(x*10,y*10,10,10);
}
}
}

Related

Java Swing brief paintComponent graphics

I am creating a java 2D game and have come to a point where I am thinking of creating "pop-up graphics" i.e graphics that will populate the screen when a certain event occurs. Say, you pick up a certain item, I want this item to be displayed in the middle of the screen in a box containing information about said item.
Currently I have one big paintComponent that paints all of the graphics for the game (tiles, entities, players etc (which has been done efficiently I might add)). I know that I can probably have a boolean value which checks if an item has been picked up in that method, but it feels wrong.
What I am wondering is, is there a way for items to have their own paintComponent so that when it is called, it will show say a bo for a brief period WITHOUT having a boolean value in the big paintComponent method that I currently use for everything?
Small code example (won't execute)
public class popUpGraphics extends (JComponent or JPanel or whatever works best for this scenario)
{
public popUpGraphics(){
}
#Override
protected void paintComponent(Graphics g){
//g.Draw(stuff);
}
}
and then somewhere in an event I instantiate this or somesuch.
I do not want this to override the other paintcomponent, I just want to add to it
(as if it was another layer) to the paintComponent
In short I want to know:
1. Is is possible to have brief graphics shown without including in the huge paintComponent method
2. What Swing library should be extended (JComponent, JPanel etc)
Thanks in advance!

Simple painting

I have an seemingly very simple task at hand. I have a grid (500x500 right now) I want to visualize as it is populated and I want to write a class in Java that makes this easy for me to do. I'm thinking something along the line of:
public class Screen {
...
public void plot(x,y) {
// change the color of pixel x,y to black
}
public void clear() {
// fill the screen with white
}
}
I have been looking around and quickly found Canvas in awt, however from what I have been able to figure out so far, this widget will only allow me to draw on to it by overriding its paint method. This is far from optimal in my case as this will require me to draw the entire grid every time I wish to do just plot one single pixel.
Is there any way to get canvas to just draw a single pixel rather than the entire canvas? Or some other way to accomplish what I look for here?
I would prefer to avoid having to use any external libraries.
You will need to override the paint method to display the entire grid.
However, what you can do is create a BufferedImage that flips the one pixel, and draw that entire image to the component in the paint method, using Graphics.drawImage().
Unfortunately you have to override paint() and render the entire grid every time paint() is called. That's how graphical components work - the windows system/OS may request to repaint the component at any time (eg. when the window is re-shown/resized/moved)

Java - Drawing a dynamic shape outline

I wish to create a dynamic outline to a Shape (AWT) by adding objects (with draw functions) to appropriate positions on screen along the shape's perimeter. I want a roughly even distance between each object. (An alternative approach to the same affect will be fine.)
How might I acquire the locations for these objects? I know shapes have a path iterator, but I have no idea how to use it.
You might look at a library such as the one described in A Shape Diagram Editor.
If you want to experiment, GraphPanel is a simple object drawing program that features moveable, resizable, colored nodes connected by edges. If the nodes were a little smaller, they'd be moveable points on a Shape that can be iterated as shown here for Polygon.
Addendum: I want a roughly even distance between each object.
The class Node exposes a number of static methods that operate on a List<Node> such as selected. Existing implementations serve, for example, to translate or resize multiple selections as a unit. Functions for Align and Distribute could be implemented similarly. I'd look at LayoutManger as an example for the latter.
Use FlatteningPathIterator to get points for Shape's path.
Also you can use BasicStroke's method
public Shape createStrokedShape(Shape s)
to get Shape's outline with desire width.

How to model game object rendering and behavior in modular way?

I'm making a Java shoot em up game for Android phones. I've got 20 odd enemies in the game that each have a few unique behaviors but certain behaviors are reused by most of them. I need to model bullets, explosions, asteroids etc. and other things that all act a bit like enemies too. My current design favors composition over inheritance and represents game objects a bit like this:
// Generic game object
class Entity
{
// Current position
Vector2d position;
// Regular frame updates behaviour
Behaviour updateBehaviour;
// Collision behaviour
Behaviour collideBehaviour;
// What the entity looks like
Image image;
// How to display the entity
Renderer renderer;
// If the entity is dead and should be deleted
int dead;
}
abstract class Renderer { abstract void draw(Canvas c); }
abstract class Behaviour { abstract void update(Entity e); }
To just draw whatever is stored as the entity image, you can attach a simple renderer e.g.
class SimpleRenderer extends Renderer
{
void draw(Canvas c)
{
// just draw the image
}
}
To make the entity fly about randomly each frame, just attach a behavior like this:
class RandomlyMoveBehaviour extends Behaviour
{
void update(Entity e)
{
// Add random direction vector to e.position
}
}
Or add more complex behaviour like waiting until the player is close before homing in:
class SleepAndHomeBehaviour extends Behaviour
{
Entity target;
boolean homing;
void init(Entity t) { target = t; }
void update(Entity e)
{
if (/* distance between t and e < 50 pixels */)
{
homing = true;
// move towards t...
}
else
{
homing = false;
}
}
}
I'm really happy with this design so far. It's nice and flexible in that you can e.g. modularize the latter class so you could supply the "sleep" behavior and the "awake" behavior so you could say something like new WaitUntilCloseBehaviour(player, 50/pixels/, new MoveRandomlyBehaviour(), new HomingBehaviour()). This makes it really easy to make new enemies.
The only part that's bothering me is how the behaviors and the renderers communicate. At the moment, Entity contains an Image object that a Behaviour could modify if it chose to do so. For example, one behavior could change the object between a sleep and awake image and the renderer would just draw the image. I'm not sure how this is going to scale though e.g.:
What about a turret-like enemy that faces a certain direction? I guess I could add a rotation field to Entity that Behavior and Renderer can both modify/read.
What about a tank where the body of the tank and the gun of the tank have separate directions? Now the renderer needs access to two rotations from somewhere and the two images to use. You don't really want to bloat the Entity class with this if there is only one tank.
What about an enemy that glows as his gun recharges? You'd really want to store the recharge time in the Behaviour object, but then the Renderer class cannot see it.
I'm having trouble thinking of ways to model the above so the renderers and the behaviors can be kept somewhat separate. The best approach I can think of is to have the behavior objects contain the extra state and the renderer object then the behavior objects call the renderers draw method and pass on the extra state (e.g. rotation) if they want to.
You could then e.g. have a tank-like Behaviour object that wants a tank-like Renderer where the latter asks for the two images and two rotations to draw with. If you wanted your tank to just be a plain image, you would just write a subclass Renderer that ignored the rotations.
Can anyone think of any alternatives? I really want simplicity. As it's a game, efficiency may be a concern as well if e.g. drawing a single 5x5 enemy image, when I have 50 enemies flying around at 60fps, involves many layers of function calls.
The composition design is a valid one, as it allow to mix-and-match the behaviour(s) and render.
In the game we're toying with, we've added a "databag" that contains basic informations (in your case the position and the dead/alive status), and variables datas that are set/unset by the behaviour and collision subsytem. The renderer can then use these data (or not if not needed). This work well, and allows for neat effect, such as setting a "target" for a given graphical effect.
A few problems :
if the Renderer ask for data that the behaviour did not set. In our case, the event is logged, and default values (defined in renderer) is used.
It's a little bit harder to check for the needed informations beforehand (ie what data should be in the databag for the Renderer A ? what data are set by the Behaviour B ?). We try to keep the doc up-to-date, but we're thinking of recording the set/get by the classes, and generate a doc page...
Currently we're using a HashMap for the databag, but this is on a PC, not an IPhone. I don't know if perfomance will be enough, in which case another struct could be better.
Also in our case, we've decided for a set of specialized renderer. For example, if the entity possess a non void shield data, the ShieldRenderer display the representation... In your case, the tank could possess two renderer linked to two (initialization-defined) datas :
Renderer renderer1 = new RotatedImage("Tank.png", "TankRotation");
Renderer enderer2 = new RotatedImage("Turret.png", "TurretRotation");
with "TankRotation" and "TurretRotation" set by the behaviour. and the renderer simply rotating the image before displaying it at the position.
image.rotate (entity.databag.getData(variable));
Hope this help
Regards
Guillaume
The design you're going with looks good to me. This chapter on components may help you.

Splitting up the drawing of a GUI Element

I have to use a GUI Element that draws a picture at a specific screen position.
If the user selects this picture there is a border drawn around the Image.
Now we want to include another border that identifies pictures with a specific value for the user.
At the moment the Element looks at his internal state if it is selected and then decides how to draw itself.
graphic.drawImage(icon, x, y, null);
if (selected) {
drawBorder();
}
I don't like the idea of adding another if else to this drawing method.
I thought about creating a new class that inherits the behavior of the element and overwrites the draw method but that means duplicating the whole selected code in every inherited class.
Is there a nice possibility so solve this problem without creating a subclass?
Since you tagged this with design-patterns and you seem to be looking for a pattern-oriented approach, I'd suggest taking a look at the state pattern. The example on the wikipedia page even mentions keeping state while drawing a GUI. Unfortunately, this would mean you'd have to create another class with subclasses and overridden methods.
Is this going to be something that is likely to change? I.e. do you realistically think you're going to be adding new behavior to the drawing (e.g. if the user double clicks, draw a different type of border; if the user right clicks, change the color of the border), or is this it? If you see more behavior being added, I think going ahead and taking a more OO approach is wise. If it's just these two cases, I'd say just add and else if statement.
What do you have against if-else?
It makes less sense to me to create a whole new object for the selected item than to check a flag in the drawing function.
one possibility is to allow your drawBorder() method to take parameters:
private void drawBorder(boolean isSelected, boolean hasSpecialValue);
this method can determine which type of border to draw.

Categories

Resources