I created a simple GUI using swing in Netbeans. The idea is user chooses a shape, enters dimensions, clicks the button to render a GLUT shape in the internal panel (in green) on the GUI. I'm stuck at trying to get the shapes to render on the inner panel.
What is a good method or example to draw or render shapes onto an internal panel or canvas of a GUI?
GUI layout for reference:
Update:
Shape Class
package swing_tests;
import static com.sun.javafx.fxml.expression.Expression.add;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.*;
import com.jogamp.opengl.util.gl2.GLUT;
/**
*
* #author Charlie
*/
public class Shape extends GLJPanel {
/**
* #param args the command line arguments
*/
// fields
int width;
int height;
int length;
String name;
//Constructor
public Shape (int w, int h, int l, String n){
width = w;
height = h;
length = l;
name = n;
}
private final GLUT glut = new GLUT();
// Methods
public void JOGLShapes() {
GLCapabilities caps = new GLCapabilities(null);
GLJPanel display = new GLJPanel(caps);
display.setPreferredSize( new Dimension (50,50));
display.setVisible(true);
display.setBackground(Color.red);
add(display, BorderLayout.CENTER);
}
/////////////////////////////////////
public void display(GLAutoDrawable drawable) {
GL2 gl2 = drawable.getGL().getGL2(); // The object that contains all the OpenGL methods.
gl2.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
gl2.glLoadIdentity(); // Set up modelview transform.
glut.glutSolidTeapot(2);
}
public void init(GLAutoDrawable drawable) {
// called when the panel is created
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(0.3F, 0.3F, 0.3F, 1.0F); // TODO: Set background color
gl.glEnable(GL2.GL_DEPTH_TEST); // TODO: Required for 3D drawing, not usually for 2D.
}
public void getArea () {
System.out.println("Area is " + width * height);
}
public void getVolume(){
System.out.println("Volume is "+ width * height * length);
}
public String getName(){
return name;
}
/// Setters
public void setWidth(int newWidth){
width = newWidth;
}
public void setHeight(int newHeight){
height = newHeight;
}
public void setDepth(int newLength){
length = newLength;
}
}
Related
I'm making a Swing application using LibGdx as a backend for the map editor part. I use a LwjglApplication and pass a java.awt.Canvas to it.
I use a ScreenViewport to make the area being resize as the window is resized, but it does not work. The graphics is interpolated with a bad aspect ratio.
public class MapEditorCanvas extends JPanel implements ApplicationListener
{
/**
*
*/
private static final long serialVersionUID = 5383413314123855231L;
/**
*
*/
private Canvas _canvas;
/**
*
*/
public MapEditorCanvas()
{
super(new BorderLayout());
_canvas = new Canvas();
add(_canvas,BorderLayout.CENTER);
LwjglApplication app = new LwjglApplication(this, _canvas);
}
/**
*
*/
private SpriteBatch batch;
/**
*
*/
private Sprite sprite;
/**
*
*/
private Viewport viewport;
/**
*
*/
private OrthographicCamera _camera;
#Override
public void create()
{
_camera = new OrthographicCamera();
_camera.setToOrtho(true);
_camera.update();
viewport = new ScreenViewport(_camera);
batch = new SpriteBatch();
batch.setProjectionMatrix(_camera.combined);
sprite = new Sprite(new Texture(Gdx.files.internal("project/assets/graphics/wheel.png")));
repaint();
}
#Override
public void render()
{
GL11.glClearColor(0, 0, 0, 1);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
batch.begin();
viewport.apply();
sprite.draw(batch);
batch.end();
}
//
// Some others methods
//
/**
*
*/
#Override
public void resize(int width, int height){
viewport.setScreenSize(width, height);
viewport.update(width, height, false);
_camera.setToOrtho(true,width,height);
_camera.update();
}
}
Is there something wrong with my code ?
Bonus question : the LibGdx application is not drawn until the component is resized, someone knows why ?
Thanks in advance
I am currently making a tile based game. Everything so far is working fine. However, I want the player to be able to add objects, like stone or wood to the screen when he/she presses the mouse button. I attempted this myself but it is not working. Here is what I have done, but is not working:
This is my KeyInput class, where all the keyboard and mouse events take place.
public static ArrayList<StoneTile> sTile = new ArrayList<StoneTile>();
public KeyInput(Handler handler) {
this.handler = handler;
}
public void tick(LinkedList<Square> object) {}
public void mousePressed(MouseEvent e){
int mx = e.getX();
int my = e.getY();
System.out.println("Pressed (X,Y): " + mx + " " + my);
sTile.add(new StoneTile(1,mx,my));
if(sTile.add(new StoneTile(1,mx,my))){
System.out.println("ADDED");
}
}
public void mouseReleased(MouseEvent e){
System.out.println("Released");
}
Here is my StoneTile class, this is what I want to add to screen:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.LinkedList;
public class StoneTile extends Tile {
Textures tex;
public StoneTile(int id,int x,int y) {
super(Textures.stoneArray[0], id);
Tile.x = x;
Tile.y = y;
}
public static void main(String[] args) {
}
public Rectangle getBounds(){
return new Rectangle(x,y,Tile.TILEWIDTH,Tile.TILEHEIGHT);
}
}
The Textures.stoneArray[0] is simply the image that I want to add to the screen.
The Tile.(instance variable, like x, y, TILEWIDTH, and TILEHEIGHT) is simply a Tile class that contains all the render methods for the tiles (grass, stone, etc). If anything is unclear I will clarify or if you need any code provided, then I will add it in.
Note - The ArrayList was just an idea that I had in mind, if there are more efficient ways of doing this or any better ideas, I am open to all of them.
Here is where I set the MouseListener. I set it in an init() method and then called in a run() method (last line):
private void init() {
BufferedImageLoader loader = new BufferedImageLoader();
level = loader.loadImage("level.png");
world = new worldLoader("res/worlds/world1.txt");
handler = new Handler();
WIDTH = getWidth();
HEIGHT = getHeight();
cam = new Camera(handler, Game.WIDTH / 2, Game.HEIGHT / 2);
setWIDTH(getWidth());
setHEIGHT(getHeight());
tex = new Textures();
//backGround = loader.loadImage("/background.jpg");
handler.addObject(new Coin(100, 100, handler, ObjectId.Coin));
handler.addObject(new newStoneTile(20,20,ObjectId.newStoneTile));
handler.addObject(new player_Square(100,100, handler, ObjectId.player_Square));
//handler.addObject(new OneUp(300, 150, handler, ObjectId.OneUp));
this.addKeyListener(new KeyInput(handler));
this.addMouseListener(new KeyInput(handler));
}
jcomponent, is this what you meant?
public class Window {
private static final long serialVersionUID = -6482107329548182911L;
static final int DimensionX = 600;
static final int DimensionY = 600;
public Window(int w, int h, String title, Game game) {
game.setPreferredSize(new Dimension(w, h));
game.setMaximumSize(new Dimension(w, h));
game.setMinimumSize(new Dimension(w, h));
JFrame frame = new JFrame();
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
}
Perhaps the best way to try and answer this question is to give a small example.
Essentially what needs to happen is the following (assuming my understanding of the problem is correct):
User clicks on the JComponent/JPanel to determine where to place a Tile. This will cause a MouseEvent that needs to be listened for and handled.
The JComponent/JPanel needs a MouseListener implementation which will create a new Tile object and add it to the List of the Tile objects. Once this is complete the JComponent/JPanel needs to know to repaint(). You do not override repaint() but rather paintComponent(Graphics g), which will be called by repaint() (eventually).
The paintComponent(Graphics g) method will iterate over the List of Tile objects, drawing them to the JComponent/JPanel using the Graphics context for the component.
To illustrate this I have simplified your problem. Note this isn't the best way to solve the problem since the Model (game logic) and the GUI should be separated, ideally using Model View Controller / Observer pattern.
First and most importantly is the GamePanel class, which extends JPanel. It's sole role in this example is to display the game graphically and handle mouse clicks. i.e. handling the list of tasks noted above.
GamePanel
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
private List<Tile> tiles; // Stores the Tile objects to be displayed
/**
* Sole constructor for GamePanel.
*
* #param width the width of the game panel
* #param height the height of the game panel
*/
public GamePanel(int width, int height) {
tiles = new ArrayList<>();
setPreferredSize(new Dimension(width, height));
// Implement mouse events for when the JPanel is 'clicked', only using the
// mouse released operation in this case.
addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
// On mouse release, add a StoneTile (in this case) to the tiles List
tiles.add(new StoneTile(e.getX(), e.getY()));
// Repaint the JPanel, calling paint, paintComponent, etc.
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
// Do nothing
}
#Override
public void mousePressed(MouseEvent e) {
// Do nothing
}
#Override
public void mouseEntered(MouseEvent e) {
// Do nothing
}
#Override
public void mouseExited(MouseEvent e) {
// Do nothing
}
});
}
/**
* Draws the Tiles to the Game Panel.
*
* #param g the Graphics context in which to paint
*/
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // Make sure you do this
// For this example, using black as the color to draw
g.setColor(Color.BLACK);
// Iterate over the tile list and draw them to the JPanel
for (Tile tile : tiles) {
Rectangle tileRect = tile.getBounds();
g.fillRect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
}
}
}
Second is the GameFrame, which extends JFrame. This is just a basic JFrame which adds a GamePanel object. I've also included the main method which will ensure the GUI is initialized on the Event Dispatch Thread.
GameFrame
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GameFrame extends JFrame {
private static final String TITLE = "Tile Game"; // Game Frame Window Title
private final JPanel gamePanel;
/**
* Sole constructor for GameFrame.
*
* #param width the width of the game in pixels
* #param height the height of the game in pixels
*/
public GameFrame(int width, int height) {
gamePanel = new GamePanel(width, height);
}
/**
* Performs final configuration and shows the GameFrame.
*/
public void createAndShow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(TITLE);
add(gamePanel);
pack();
setVisible(true);
}
/**
* Entry point for the program.
*
* #param args not used
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
GameFrame gameFrame = new GameFrame(640, 480);
gameFrame.createAndShow();
}
});
}
}
Finally, the other classes used in the example for completeness, Tile and StoneTile. Personally I don't see much benefit from using Rectangle inside the model, but each to their own and I wanted to keep the example somewhat similar to your currently implementation.
Tile
import java.awt.Rectangle;
public abstract class Tile {
private int x, y, width, height;
public Tile(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
}
StoneTile
public class StoneTile extends Tile {
public StoneTile(int x, int y) {
super(x, y, 100, 100);
}
}
One final comment. I notice that your sTile ArrayList is static, this should probably not be the case as it belongs to the class rather than a particular instance of the class.
There's a breakout game that's been partially created for me; currently it only has a bouncing ball and a bat; there are no bricks which the ball can hit.
I need to add code to generate bricks but I'm struggling; I have no idea how to approach this as I'm not very good with Java GUI.
I have included the classes where the code needs to be added; the areas which need the code are written in comments
Modelbreakout class:
package breakout;
import java.util.Observable;
import static breakout.Global.*;
/**
* Model of the game of breakout
* The active object ActiveModel does the work of moving the ball
* #author Mike Smith University of Brighton
*/
public class ModelBreakout extends Observable
{
private GameObject ball; // The ball
private GameObject bricks[]; // The bricks
private GameObject bat; // The bat
private ModelActivePart am = new ModelActivePart( this );
private Thread activeModel = new Thread( am );
private int score = 0;
public void createGameObjects()
{
ball = new GameObject(W/2, H/2, BALL_SIZE, BALL_SIZE, Colour.RED );
bat = new GameObject(W/2, H - BRICK_HEIGHT*4, BRICK_WIDTH*3,
BRICK_HEIGHT, Colour.GRAY);
bricks = new GameObject[BRICKS];
// *[1]**********************************************************
// * Fill in code to place the bricks on the board *
// **************************************************************
}
public void startGame() { activeModel.start(); }
public GameObject getBall() { return ball; }
public GameObject[] getBricks() { return bricks; }
public GameObject getBat() { return bat; }
public void addToScore( int n ) { score += n; }
public int getScore() { return score; }
public void stopGame() { }
/**
* Move the bat dist pixels. (-dist) is left or (+dist) is right
* #param dist - Distance to move
*/
public void moveBat( float dist )
{
// *[2]**********************************************************
// * Fill in code to prevent the bat being moved off the screen *
// **************************************************************
Debug.trace( "Model: Move bat = %6.2f", dist );
bat.moveX(dist);
//modelChanged();
}
/**
* Model has changed so notify observers so that they
* can redraw the current state of the game
*/
public void modelChanged()
{
setChanged(); notifyObservers();
}
}
ViewBreakout class:
package breakout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import static breakout.Global.*;
/**
* Displays a graphical view of the game of breakout
* Uses Garphics2D would need to be re-implemented for Android
* #author Mike Smith University of Brighton
*/
public class ViewBreakout extends JFrame implements Observer
{
private ControllerBreakout controller;
private GameObject ball; // The ball
private GameObject[] bricks; // The bricks
private GameObject bat; // The bat
private int score = 0; // The score
private long timeTaken = 0; // How long
private int frames = 0; // Frames output
private final static int RESET_AFTER = 200;
/**
* Construct the view of the game
*/
public ViewBreakout()
{
setSize( W, H ); // Size of window
addKeyListener( new Transaction() ); // Called when key press
setDefaultCloseOperation(EXIT_ON_CLOSE);
Timer.startTimer();
}
/**
* Code called to draw the current state of the game
* Uses draw: Draw a shape
* fill: Fill the shape
* setPaint: Colour used
* drawString: Write string on display
* #param g Graphics context to use
*/
public void drawActualPicture( Graphics2D g )
{
frames++;
// White background
g.setPaint( Color.white );
g.fill( new Rectangle2D.Float( 0, 0, W, H ) );
Font font = new Font("Monospaced",Font.BOLD,24);
g.setFont( font );
// Blue playing border
g.setPaint( Color.blue ); // Paint Colour
g.draw( new Rectangle2D.Float( B, M, W-B*2, H-M-B ) );
// Display the ball
display( g, ball );
// Display the bricks that make up the game
// *[3]**********************************************************
// * Fill in code to display bricks (A brick may not exist) *
// **************************************************************
// Display the bat
display( g, bat );
// Display state of game
g.setPaint( Color.black );
FontMetrics fm = getFontMetrics( font );
String fmt = "BreakOut: Score = [%6d] fps=%5.1f";
String text = String.format(fmt, score,
frames/(Timer.timeTaken()/1000.0)
);
if ( frames > RESET_AFTER )
{ frames = 0; Timer.startTimer(); }
g.drawString( text, W/2-fm.stringWidth(text)/2, (int)M*2 );
}
private void display( Graphics2D g, GameObject go )
{
switch( go.getColour() )
{
case GRAY: g.setColor( Color.gray );
break;
case BLUE: g.setColor( Color.blue );
break;
case RED: g.setColor( Color.red );
break;
}
g.fill( new Rectangle2D.Float( go.getX(), go.getY(),
go.getWidth(), go.getHeight() ) );
}
/**
* Called from the model when its state has changed
* #param aModel Model to be displayed
* #param arg Any arguments
*/
#Override
public void update( Observable aModel, Object arg )
{
ModelBreakout model = (ModelBreakout) aModel;
// Get from the model the ball, bat, bricks & score
ball = model.getBall(); // Ball
bricks = model.getBricks(); // Bricks
bat = model.getBat(); // Bat
score = model.getScore(); // Score
//Debug.trace("Update");
repaint(); // Re draw game
}
/**
* Called by repaint to redraw the Model
* #param g Graphics context
*/
#Override
public void update( Graphics g ) // Called by repaint
{
drawPicture( (Graphics2D) g ); // Draw Picture
}
/**
* Called when window is first shown or damaged
* #param g Graphics context
*/
#Override
public void paint( Graphics g ) // When 'Window' is first
{ // shown or damaged
drawPicture( (Graphics2D) g ); // Draw Picture
}
private BufferedImage theAI; // Alternate Image
private Graphics2D theAG; // Alternate Graphics
public void drawPicture( Graphics2D g ) // Double buffer
{ // to avoid flicker
if ( theAG == null )
{
Dimension d = getSize(); // Size of curr. image
theAI = (BufferedImage) createImage( d.width, d.height );
theAG = theAI.createGraphics();
}
drawActualPicture( theAG ); // Draw Actual Picture
g.drawImage( theAI, 0, 0, this ); // Display on screen
}
/**
* Need to be told where the controller is
* #param aPongController The controller used
*/
public void setController(ControllerBreakout aPongController)
{
controller = aPongController;
}
/**
* Methods Called on a key press
* calls the controller to process
*/
class Transaction implements KeyListener // When character typed
{
#Override
public void keyPressed(KeyEvent e) // Obey this method
{
// Make -ve so not confused with normal characters
controller.userKeyInteraction( -e.getKeyCode() );
}
#Override
public void keyReleased(KeyEvent e)
{
// Called on key release including specials
}
#Override
public void keyTyped(KeyEvent e)
{
// Send internal code for key
controller.userKeyInteraction( e.getKeyChar() );
}
}
}
ModelActivePart class:
package breakout;
import static breakout.Global.*;
/**
* A class used by the model to give it an active part.
* Which moves the ball every n millesconds and implements
* an appropirate action on a collision involving the ball.
* #author Mike Smith University of Brighton
*/
public class ModelActivePart implements Runnable
{
private ModelBreakout model;
private boolean runGame = true; // Assume write to is atomic
public ModelActivePart(ModelBreakout aBreakOutModel)
{
model = aBreakOutModel;
}
/**
* Stop game, thread will finish
*/
public void stopGame() { runGame = false; }
/**
* Code to position the ball after time interval
* and work out what happens next
*/
#Override
public void run()
{
final float S = 6; // Units to move the ball
try
{
GameObject ball = model.getBall(); // Ball in game
GameObject bricks[] = model.getBricks(); // Bricks
GameObject bat = model.getBat(); // Bat
while (runGame)
{
double x = ball.getX();
double y = ball.getY();
// Deal with possible edge of board hit
if (x >= W - B - BALL_SIZE) ball.changeDirectionX();
if (x <= 0 + B ) ball.changeDirectionX();
if (y >= H - B - BALL_SIZE)
{
ball.changeDirectionY(); model.addToScore( HIT_BOTTOM );
}
if (y <= 0 + M ) ball.changeDirectionY();
ball.moveX(S); ball.moveY(S);
// As only a hit on the bat/ball is detected it is assumed to be
// on the top or bottom of the object
// A hit on the left or right of the object
// has an interesting affect
boolean hit = false;
// *[4]**********************************************************
// * Fill in code to check if a brick has been hit *
// * Remember to remove a brick in the array (if hit) *
// * [remove] - set the array element to null *
// **************************************************************
if (hit)
ball.changeDirectionY();
if (bat.hitBy(ball) == GameObject.Collision.HIT)
ball.changeDirectionY();
model.modelChanged(); // Model changed refresh screen
Thread.sleep(20); // About 50 Hz
}
} catch (Exception e)
{
Debug.error("ModelActivePart - stopped\n%s", e.getMessage() );
}
}
}
Now I don't expect you to do everything for me, I just want to know how to draw one brick on the screen; from there onwards I could probably to the rest myself.
If you want the whole package; the download link to my project is here
Any help is appreciated :)
For a blue brick at position 0, 0 modify the createGameObjects method of the ModelBreakout class:
public void createGameObjects()
{
ball = new GameObject(W / 2, H / 2, BALL_SIZE, BALL_SIZE, Colour.RED);
bat = new GameObject(W / 2, H - BRICK_HEIGHT * 4, BRICK_WIDTH * 3,
BRICK_HEIGHT, Colour.GRAY);
bricks = new GameObject[BRICKS];
// *[1]**********************************************************
// * Fill in code to place the bricks on the board *
// **************************************************************
bricks[0] = new GameObject(0, 0, BRICK_HEIGHT, BRICK_WIDTH, Colour.BLUE);
}
Then draw the bricks in the drawActualPicture method of the ViewBreakout class:
// Display the bricks that make up the game
// *[3]**********************************************************
// * Fill in code to display bricks (A brick may not exist) *
// **************************************************************
for (GameObject brick : bricks)
{
if (null != brick)
{
display ( g, brick );
}
}
This is a great assignment if it's coursework.
im using the Canvas class to make a screensaver as a schoolproject.
But the window generated by Canvas doesnt show my objects on it (current time)
until i minimize it an resize it again. After that all things works fine.
so what is wrong?
thank you for coming answers!
with kind regards
leon
those are the classes, i peronally think that the problem is in the class Start or BufferedCanvas
import java.awt.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Start
{
int fensterX = 900;
int fensterY = 700;
Farbengenerator fg = new Farbengenerator();
BufferedCanvas c =newBufferedCanvas("Bild",fensterX,fensterY);
Zeit z = new Zeit();
SchriftParameter sp = new SchriftParameter();
public void zeichneText(){
double x = 100;
double y = 100;
double fy =0.01;
double fx =0.02;
int red=0;
int green=0;
int blue=0;
double colourGrowRate=0.05;
String uhr;
c.setFont(sp.setzteSchrift());
c.setForegroundColour(Color.BLACK);
c.setBackgroundColour(Color.WHITE);
for(int i=0;i<100;i++){
c.drawString("Starting...",(int)x,(int)y);
c.updateAndShow();
try{Thread.sleep(50);}
catch(Exception e){};
c.updateAndShow();
}
CreateButton d = new CreateButton();
d.run();
while(true) {
c.erase();
uhr = z.erstelleZeit();
c.drawString(uhr,(int)x,(int)y);
if((int)x >fensterX-93 || (int)x <5){
fx = fx * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)y > fensterY-1 || (int)y < 46){
fy = fy * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)colourGrowRate>=1){
fg.generiereFarbe();
colourGrowRate = 0.05;
}
colourGrowRate=colourGrowRate+colourGrowRate;
x = x + fx;
y = y + fy;
c.updateAndShow();
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
public class BufferedCanvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColour;
private Image canvasImage;
BufferStrategy buff;
/**
* Create a BufferedCanvas with default height,
width and background colour
* (300, 300, white).
* #param title title to appear in Canvas Frame
*/
public BufferedCanvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a BufferedCanvas with default background colour (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public BufferedCanvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a BufferedCanvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background colour of the canvas
*/
public BufferedCanvas(String title, int width, int height, Color bgColour)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColour = bgColour;
frame.pack();
frame.createBufferStrategy(2);
buff = frame.getBufferStrategy();
graphic = (Graphics2D)buff.getDrawGraphics();
setVisible(true);
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background colour
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColour);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Update the canvas and show the new image.
*/
public void updateAndShow(){
buff.show();
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
//canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground colour of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
//canvas.repaint();
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.fill(shape); // erase by filling background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.draw(shape); // erase by drawing background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
//canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
//canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.drawString(text, x, y);
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
//canvas.repaint();
}
/**
* Draws a dot/pixel on the Canvas.
* #param x x co-ordinate of dot
* #param y y co-ordinate of dot
*/
public void drawDot(int x, int y)
{
graphic.drawLine(x, y, x, y);
//canvas.repaint();
}
/**
* Sets the foreground colour of the Canvas.
* #param newColour the new colour for the foreground of the Canvas
*/
public void setForegroundColour(Color newColour)
{
graphic.setColor(newColour);
}
/**
* Returns the current colour of the foreground.
* #return the colour of the foreground of the Canvas
*/
public Color getForegroundColour()
{
return graphic.getColor();
}
/**
* Sets the background colour of the Canvas.
* #param newColour the new colour for the background of the Canvas
*/
public void setBackgroundColour(Color newColour)
{
backgroundColour = newColour;
graphic.setBackground(newColour);
}
/**
* Returns the current colour of the background
* #return the colour of the background of the Canvas
*/
public Color getBackgroundColour()
{
return backgroundColour;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (Exception e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Nested class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class CreateButton extends JFrame implements ActionListener{
public void run() {
createAndShowGUI();
}
public CreateButton() {
// set layout for the frame
this.getContentPane().setLayout(new FlowLayout());
JButton button1 = new JButton();
button1.setText("closeApp");
//set actionlisteners for the buttons
button1.addActionListener(this);
// define a custom short action command for the button
button1.setActionCommand("closeApp");
// add buttons to frame
add(button1);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new CreateButton();
//Display the window.
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae) {
String action = ae.getActionCommand();
if (action.equals("closeApp")) {
System.exit(1);
}
}
}
import java.awt.*;
public class SchriftParameter
{
public Font setzteSchrift(){
Font f = new Font("Fixed",1,24);
return (f);
}
}
public class Farbengenerator
{
int r=0;
int g=0;
int b=0;
public void generiereFarbe(){
if (r<255&&g==0&&b==0){
r++;
}
else if (r==255&&g<255&&b==0){
g++;
}
else if (r>0&&g==255&&b==0){
r= r-1;
}
else if (r==0&&g==255&&b<255){
b++;
}
else if (r==0&&g>0&&b==255){
g=g-1;
}
else if (r<255&&g==0&&b==255){
r++;
}
else if (r==255&&g==0&&b>0){
b=b-1;
}
}
public int gibROT () {
return(r);
}
public int gibGRUEN () {
return(g);
}
public int gibBLAU () {
return(b);
}
}
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Zeit
{
public String erstelleZeit(){
DateFormat df = new SimpleDateFormat("HH:mm:ss");
Date d = new Date();
String uhr = df.format(d);
return (uhr);
}
}
I've messed around with Java a little bit and I decided to take a course to learn some more and I have been assigned a fairly easy assignment. I have it mostly done and I know what's left must be simple, but I cannot seem to quite get it. So far I have been able to successfully create a program that has 1 bouncing ball, but I would now like to allow the user to input the amount of balls to bounce. I have tried a few different loops in my Ball class, but none of them work. Would anyone be willing to give a quick hand? I am almost sure it would require either an Array or ArrayList and just storing the balls in it but I have yet to find a solution that works. I have looked at other problems like this on the website but none have quite solved my problem. Thank you if you can help!
Main Class :
public class mainClass {
/**
/**
* Frame to hold a bouncing ball panel, implemented in the BallPanel class.
* Controls the animation of the ball via pauses and calls to BallPanel's move
* method.
*
* #author Michael Peterson modified by Mr O Aug 2012
*/
public static class BallTest extends JFrame {
// size of the window
private static final int WINDOW_WIDTH = 500;
private static final int WINDOW_HEIGHT = 300;
// panel containing the bouncing ball
private BallPanel ballPanel;
/**
* Pause command used to control the speed of the bouncing ball animation.
* Currently pauses for 20 ms. Use smaller values for faster animation and
* vice versa.
*/
public static void pause() {
try {
Thread.sleep(20); // pause for 20 ms
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}//end of catch
}//end of pause method
/**
* Creates a new instance of BallTest
*/
public BallTest() {
super("Bouncing Ball"); // set frame name
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLayout(new BorderLayout());
ballPanel = new BallPanel();
add(ballPanel);
center(this);
setVisible(true);
// infinite animation loop, program halts when window is closed.
while (true) {
pause();
ballPanel.move(ballPanel);
}//end of while loop of animation
} //end of BallTest Constructor
/**
* Helper routine to center a frame on the screen (will cause problems if
* frame is bigger than the screen!)
*/
public static void center(JFrame frame) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Point center = ge.getCenterPoint();
int w = frame.getWidth();
int h = frame.getHeight();
int x = center.x - w / 2, y = center.y - h / 2;
frame.setBounds(x, y, w, h);
frame.validate();
}//end of center method
}//end of BallPanel Class
public static void main(String[] args) {
BallTest t = new BallTest(); //make a BallTest object
}//end of main method
}//end of Fall2012Lab11StarterCode class
Ball Class :
public class Ball extends JPanel {
private int bxCoord; //the ball's x coordinate
private int byCoord; //the ball's y coordinate
private int bHeight; //the ball's height
private int bWidth; //the ball's weight
private int bRise; //the ball's y change
private int bRun; //the ball's x change
private Color bColor; //the ball's color
//Constructor
public Ball() {
bxCoord = setStartBxCoord();
byCoord = setStartByCoord();
bHeight = setStartBHeight();
bWidth = setStartBWidth();
bRise = setStartBRise();
bRun = setStartBRun();
bColor = setStartColor();
}
/**
* The setters, getters, and initial value for the ball's x coordinate
*/
public void setBxCoord(int xCoord) {
bxCoord = xCoord;
}
public int setStartBxCoord() {
int xCoord;
xCoord = (int) (Math.random() * 51);
return xCoord;
}
public int getBxCoord() {
return bxCoord;
}
/**
* The setters, getters, and initial value for the ball's y coordinate
*/
public void setByCoord(int yCoord) {
bxCoord = yCoord;
}
public int setStartByCoord() {
int yCoord;
yCoord = (int) (Math.random() * 51);
return yCoord;
}
public int getByCoord() {
return byCoord;
}
/**
* The setters, getters, and initial value for the ball's x height
*/
public void setBHeight(int height) {
bHeight = height;
}
public int setStartBHeight() {
int height;
height = (int) (10 + Math.random() * 11);
return height;
}
public int getBHeight() {
return bHeight;
}
public void setBWidth(int width) {
bWidth = width;
}
/**
* The setters, getters, and initial value for the ball's x width
*/
public int setStartBWidth() {
int width;
width = (int) (10 + Math.random() * 11);
return width;
}
public int getBWidth() {
return bWidth;
}
/**
* The setters, getters, and initial value for the ball's rise
*/
public void setBRise(int rise) {
bRise = rise;
}
public int setStartBRise() {
int rise;
rise = (int) (Math.random() * 11);
return rise;
}
public int getBRise() {
return bRise;
}
/**
* The setters, getters, and initial value for the ball's run
*/
public void setBRun(int run) {
bRun = run;
}
public int setStartBRun() {
int run;
run = (int) (Math.random() * 11);
return run;
}
public int getBRun() {
return bRun;
}
/**
* The movement of the ball in the x and y direction
*/
public void moveX(){
bxCoord += bRun;
}
public void moveY(){
byCoord += bRise;
}
/**
* The setters, getters, and initial value for the ball's color
*/
public void setColor(Color color) {
bColor = color;
}
public Color setStartColor() {
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
Color ranColor = new Color(red, green, blue);
return ranColor;
}
public Color getbColor() {
return bColor;
}
/**
* Computes the next position for the balls and updates their positions.
*/
public void move(BallPanel ballPanel) {
// If ball is approaching a wall, reverse direction
if ((getBxCoord() < (0 - getBRun())) || (getBxCoord() > (ballPanel.getWidth() - getBWidth()))) {
setBRun(-getBRun());
}
if ((getByCoord() < (0 - getBRise())) || (getByCoord() > (ballPanel.getHeight() - getBHeight()))) {
setBRise(-getBRise());
}
// "Move" ball according to values in rise and run
moveX();
moveY();
} // end method move
}//end of Ball Class
Ball Panel Class :
public class BallPanel extends JPanel {
Ball ball = new Ball(); //creat a ball.
/**
* Creates a new instance of BallPanel
*/
public BallPanel() {
super();
}
/**
* The move method moves the ball and repaints the panel
* PreCondtion: A panel containing a ball has been created
* PostCondition: The position of a ball on the panel has moved. The panell
* is repainted with the ball in the new position.
* #param ballPanel The name of the panel on which the ball is found
*/
public void move(BallPanel ballPanel) {
ball.move(ballPanel);
repaint();
}
/**
* Paints the balls at their current positions within the panel.
* PreCondition: A graphics object has been created and needs to be displayed
* PostCondition: The graphics object g has been displayed
* #param g The graphic object to be displayed
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black); // set color black
g.fillRect(0, 0, getWidth(), getHeight()); // paint background
// Paint the Ball
g.setColor(ball.getbColor());
g.fillOval(ball.getBxCoord(), ball.getByCoord(),
ball.getBWidth(), ball.getBHeight());
}//end of paintComponent method
}//end of BallPanel class
Well I'm answering you purely on previous codes i have done similar to this, because I didn't have the time to test out yours.
Your ballPanel class should look something more like this:
import java.util.ArrayList;
public class BallPanel extends JPanel{
private ArrayList<Ball> BallList = new ArrayList<Ball>();
private int num;
public BallPanel(int numberOfBalls){
super();
num = numberOfBalls;
for(int i = 0; i<num; i++){BallList.add(new Ball());}
}
//the rest of your methods, using for loops for the balls
Also I think you can use this instead of ArrayList (this is easier):
Ball[] BallList = new Ball[numberOfBalls];
then an example of your move method should look like this:
public void move(BallPanel ballPanel){
for(int i = 0; i<num; i++){
BallList[i].move(ballPanel);
}
repaint();
}
I had a similar issues with a Bouncing Ball program. Tried the previously posted code, but the public void move(BallPanel area isn't working. When I access an array in that location the ball stops moving. Here is my current code for move:
public void move(BallPanel ballPanel, ArrayList<Ball> ballList) {
for(int i = 0; i<1; i++){
System.out.println("mmm" + i);
ballList.get(i).move(ballPanel);
}
repaint();
Secondly as shown the paintComponent area above, only ball is used to paint the ball. Is that OK that paintComponent is called multiple times but only has a variable ball in it. Here is what that section looks like:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black); // set color black
g.fillRect(0, 0, getWidth(), getHeight()); // paint background
// Paint the Ball
g.setColor(ball.getbColor());
g.fillOval(ball.getBxCoord(), ball.getByCoord(),
ball.getBWidth(), ball.getBHeight());