The problem is that my gif called "grrass" in the program was supposed to move automatically, however it only moves when I press a button.
This is my main class which creates the Frame and things I need to create a window:
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class mainCalss {
public static void main (String args[]) {
JFrame f = new JFrame();
second d = new second();
f.add(d);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1200 , 900);
}
}
This is my method class, which contains my gif image and my main running process:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.Random;
public class second extends JPanel implements ActionListener , KeyListener {
Image img = Toolkit.getDefaultToolkit().createImage("images/grrass.gif");
Timer t = new Timer(90, this);
int x = 0 , y = 0 , velx = 0 , vely = 0 ;
public second () {
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(img, 0,0, null);
g2.fill(new Ellipse2D.Double(100+x , 100+y, 30 , 30));
g2.drawRect(x+100, y+100, 30, 30);
g2.fillRect(x+115, y+112, 50 , 2);
g2.fillRect(x+115, y+118, 50 , 2);
g2.setColor(Color.yellow);
g2.fillOval(x-10, 10+y, 50, 50);
g2.fillRect(x-10, y+8, 70, 40);
g2.setColor(Color.black);
g2.drawRect(x-10, y+8, 70, 40);
g2.drawOval(x-10, 10+y, 50, 50);
g2.setColor(Color.yellow);
g2.fillOval(x, y, 200, 100);
g2.setColor(Color.black);
g2.drawOval(x, y, 200, 100);
g2.drawLine(x+0,y+50,x+200,y+50);
g2.drawOval(x, 20+y, 200, 60);
}
public void actionPerformed(ActionEvent e) {
if(x<0)
x+=35;
if(y<0)
y+=35;
if(x>1100)
x-=135;
if(y>650)
y-=30;
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN: y += 20; break;
case KeyEvent.VK_UP: y += -20; break;
case KeyEvent.VK_LEFT: x += -20; break;
case KeyEvent.VK_RIGHT: x += 20; break;
}
repaint();
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
}
}
Related
For an assignment we were asked to modify existing code to include more than one shape, more than one color, and to have the shapes move. I got a little carried away and started adding in more things but now we have an issue. All was going well until I added the left arm(as viewed on the screen). I am having a problem with a piece of the arm remaining in the previous place when moving the figure to the right. Up, down, and left are all working well, it is only to the right where I hit the problem. I have added a screenshot of what it looks like after I move the figures to the right two times. Thanks for any assistance you may be able to provide.
roboMan output
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.Color;
import java.awt.Polygon;
import java.util.Scanner;
import java.awt.geom.Ellipse2D;
public class SwingBot1 {
public static void main(String[] args) {
// contruction of new JFrame object
JFrame frame = new JFrame();
// mutators
frame.setSize(400,400);
frame.setTitle("SwingBot");
// program ends when window closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Robot r = new Robot();
frame.add(r);
// voila!
frame.setVisible(true);
// your Scanner-based command loop goes here
Scanner in = new Scanner(System.in);
boolean active = true;
while(active){
System.out.println("Enter \"up\", \"down\", \"left\", or \"right\" "
+ "to move.\nClose the window to quit.");
String direction = in.nextLine();
switch(direction){
case "up":
r.moveBot(0, -20);
break;
case "down":
r.moveBot(0, 20);
break;
case "right":
r.moveBot(20, 0);
break;
case "left":
r.moveBot(-20, 0);
break;
}
}
}
public static class Robot extends JComponent
{
private Rectangle rect = new Rectangle(45, 30, 20, 20);
int x = 30;
int y = 50;
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// set the color
g2.setColor(Color.RED);
// draw the shape`
g2.fill(rect);
Graphics2D g3 = (Graphics2D) g;
g3.setColor(Color.BLUE);
g3.draw(new Ellipse2D.Double(30, 50, 50, 100));
g3.fillOval(30, 50, 50, 100);
Graphics2D g4 = (Graphics2D) g;
g4.setColor(Color.GREEN);
g4.draw(new Line2D.Double(70, 141, 90, 190));
g4.draw(new Line2D.Double(39, 141, 30, 191));
Graphics2D g5 = (Graphics2D) g;
g5.setColor(Color.RED);
g5.draw(new Line2D.Double(80, 85, 125, 70));
//arm, left as viewed
g5.draw(new Line2D.Double(0, 70, 30, 85));
}
public void moveBot(int x, int y)
{
setX(getX()+x);
setY(getY()+y);
repaint();
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
/* public void moveBot(int x, int y)
{
// move the rectangle
rect.translate(x,y);
// redraw the window
poly.translate(x, y);
repaint();
}*/
}
}
It looks like you need to repaint the frame.
I want to create a continuous animation of a moving truck in java applets. In this the truck should reappear from the other side as soon as it disappears.
I tried using one truck but then it appears on the other side only after completely disappearing from one side. Hence, I used two.
Following is my code:
public class prc1 extends Applet implements Runnable{
Thread t;
int x=0;
int y=0;
int i;
public void start(){
t = new Thread(this);
t.start();
}
public void paint(Graphics g){
g.setColor(Color.gray);
g.fillRect(x,10,70,45);
g.setColor(Color.yellow);
g.fillRoundRect(50+x,15,35,35,10,10);
g.setColor(Color.black);
g.fillArc(5+x,50,10,10,0,360);
g.fillArc(55+x,50,10,10,0,360);
g.setColor(Color.gray);
g.fillRect(y,10,70,45);
g.setColor(Color.yellow);
g.fillRoundRect(50+y,15,35,35,10,10);
g.setColor(Color.black);
g.fillArc(5+y,50,10,10,0,360);
g.fillArc(55+y,50,10,10,0,360);
}
public void run(){
try{
y=-90;
x=0;
for(; ;){
Thread.sleep(100);
repaint();
run();
x=x+5;
if(x==400){
for(; ;){
y=y+5;
Thread.sleep(100);
repaint();
run();
x=x-5;
if(x==0){
y=-90;
break;
}
}
}
}
}catch(InterruptedException e){ }
}
}
Now the problem is that the truck does not move at all.
So the basic idea is, you need to determine when the truck begins to leave the viewable area and then calculate the amount of "overflow", which would then allow you to paint the truck a second time at a new position subtracted from the overflow.
I've broken you code down so the Truck is it's own class, this makes it easier to deal with and allows a little more control over the painting process.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Truck truck;
public TestPane() {
truck = new Truck();
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
truck.update(getSize());
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
truck.paint(g2d);
g2d.dispose();
}
}
public class Truck {
private int x, y;
// I had to calculate these
private int width = 85;
private int height = 65;
private int xDelta = 4;
private int xOverFlow = 0;
public void update(Dimension bounds) {
x += xDelta;
if (x > bounds.width) {
x = 0;
}
if (x + width > bounds.width) {
xOverFlow = (x + width) - bounds.width;
} else {
xOverFlow = -1;
}
}
public void paint(Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.translate(x, y);
paintTruck(g2d);
g2d.dispose();
if (xOverFlow > 0) {
g2d = (Graphics2D) g.create();
g2d.translate(xOverFlow - width, y);
paintTruck(g2d);
g2d.dispose();
}
}
protected void paintTruck(Graphics2D g2d) {
g2d.setColor(Color.gray);
g2d.fillRect(0, 10, 70, 45);
g2d.setColor(Color.yellow);
g2d.fillRoundRect(50, 15, 35, 35, 10, 10);
g2d.setColor(Color.black);
g2d.fillArc(5, 50, 10, 10, 0, 360);
g2d.fillArc(55, 50, 10, 10, 0, 360);
g2d.setColor(Color.gray);
g2d.fillRect(0, 10, 70, 45);
g2d.setColor(Color.yellow);
g2d.fillRoundRect(50, 15, 35, 35, 10, 10);
g2d.setColor(Color.black);
g2d.fillArc(5, 50, 10, 10, 0, 360);
g2d.fillArc(55, 50, 10, 10, 0, 360);
}
}
}
Another option might be to have more than one instance of truck, so as the second one begins to leave the viewable you could create another one
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Truck> trucks;
public TestPane() {
trucks = new ArrayList<>(2);
trucks.add(new Truck());
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Truck[] truckArray = trucks.toArray(new Truck[trucks.size()]);
for (Truck truck : truckArray) {
truck.update(getSize());
if (truck.getX() > getWidth()) {
trucks.remove(truck);
} else if (truck.getX() + truck.getWidth() > getWidth() && trucks.size() == 1) {
trucks.add(new Truck());
}
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Truck truck : trucks) {
truck.paint(g2d);
}
g2d.dispose();
}
}
public class Truck {
// I had to calculate these
private int width = 85;
private int height = 65;
private int x = -width;
private int y;
private int xDelta = 4;
public void update(Dimension bounds) {
x += xDelta;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void paint(Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.translate(x, y);
paintTruck(g2d);
g2d.dispose();
}
protected void paintTruck(Graphics2D g2d) {
g2d.setColor(Color.gray);
g2d.fillRect(0, 10, 70, 45);
g2d.setColor(Color.yellow);
g2d.fillRoundRect(50, 15, 35, 35, 10, 10);
g2d.setColor(Color.black);
g2d.fillArc(5, 50, 10, 10, 0, 360);
g2d.fillArc(55, 50, 10, 10, 0, 360);
g2d.setColor(Color.gray);
g2d.fillRect(0, 10, 70, 45);
g2d.setColor(Color.yellow);
g2d.fillRoundRect(50, 15, 35, 35, 10, 10);
g2d.setColor(Color.black);
g2d.fillArc(5, 50, 10, 10, 0, 360);
g2d.fillArc(55, 50, 10, 10, 0, 360);
}
}
}
I am currently experimenting with the Graphics2D and the KeyListener, and I am currently testing out rotating objects (in this case a pentagon). Now, it's working in the sense that it rotates, except it is supposed to rotate by 1 radian each time VK_RIGHT or VK_LEFT are pressed.
However, currently it does that for the first key press only. From then on, it creates a pattern of rotating it by 1, 2, 3, 4, 5... and so on radians each time (the nth keypress rotates it by nth radians) instead of just 1 radian per keypress.
Creating the JFrame:
import javax.swing.JFrame;
public class Main {
public Main() {
JFrame window = new JFrame("Rotating Hexagons");
window.setSize(800,600);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setContentPane(new RotatingHexagon());
window.pack();
window.setVisible(true);
}
public static void main(String[]args) {
new Main();
}
}
RotatingHexagon Class:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
public class RotatingHexagon extends JPanel implements KeyListener {
private Polygon poly;
private int[] xpoints = { 0, -10, -7, 7, 10 };
private int[] ypoints = { -10, -2, 10, 10, -2 };
private int rotation = 0;
public RotatingHexagon() {
setPreferredSize(new Dimension(800,600));
setFocusable(true);
requestFocus();
}
public void init() {
poly = new Polygon(xpoints, ypoints, xpoints.length);
addKeyListener(this);
}
public void paint(Graphics g) {
init();
Graphics2D g2d = (Graphics2D) g;
int width = getSize().width;
int height = getSize().height;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.WHITE);
g2d.drawString(rotation + " radians", 10, 20);
g2d.translate(width / 2, height / 2);
g2d.scale(20, 20);
g2d.rotate(Math.toRadians(rotation));
g2d.setColor(new Color(255, 100, 100));
g2d.fill(poly);
g2d.setColor(Color.WHITE);
g2d.draw(poly);
}
public void keyPressed(KeyEvent k) {
switch(k.getKeyCode()) {
case KeyEvent.VK_LEFT:
rotation--;
if (rotation < 0) rotation = 359;
repaint();
break;
case KeyEvent.VK_RIGHT:
rotation++;
if (rotation > 360) rotation = 0;
repaint();
break;
}
}
public void keyReleased(KeyEvent k) {}
public void keyTyped(KeyEvent k) {}
}
I really don't have any idea why it isn't just rotating 1 radian each time, so any help is appreciated.
Thanks.
the reason is calling the init() function in the paint() method again and again. So the KeyListener is added multiple times, causing that it is called multiple times, incrementing your counter more every time you press the key.
Move it to the constructor:
public RotatingHexagon() {
setPreferredSize(new Dimension(800,600));
setFocusable(true);
requestFocus();
addKeyListener(this);
}
public void init() {
poly = new Polygon(xpoints, ypoints, xpoints.length);
}
Andy
You should probally just use a persistant AffineTransform to do the rotation. They are a lot more powerfull.
I also saw several issues in your code, you are calling the init method each frame - this could be 60 times per second. In this you are adding a new keylistener each frame. You are also creating a new polygon which would slow down performance.
I've made some changes to your code and and i've used AffineTransforms as an example. Have a look and see if this helps.
package com.joey.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AffineTransformTest extends JPanel implements KeyListener {
private Polygon poly;
private int[] xpoints = { 0, -10, -7, 7, 10 };
private int[] ypoints = { -10, -2, 10, 10, -2 };
private int rotation = 0;
AffineTransform transform;
AffineTransform rotationTransform;
AffineTransform translateTransform;
public AffineTransformTest() {
setPreferredSize(new Dimension(800,600));
setFocusable(true);
requestFocus();
//Do Init here - no point in creating new polygon each frame.
//It also adds the key listener each time
init();
updateTransforms();
}
public void init() {
poly = new Polygon(xpoints, ypoints, xpoints.length);
transform = new AffineTransform();
rotationTransform = new AffineTransform();
translateTransform = new AffineTransform();
addKeyListener(this);
}
//Use Paint Compoent
#Override
public void paintComponent(Graphics g) {
//Always call super to clear the screen
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int width = getSize().width;
int height = getSize().height;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.WHITE);
g2d.drawString(rotation + " radians", 10, 20);
//Store old transform so we can apply it
AffineTransform old = g2d.getTransform();
//Add Transform and move polygon
g2d.setTransform(transform);
g2d.setColor(new Color(255, 100, 100));
g2d.fill(poly);
g2d.setColor(Color.WHITE);
g2d.draw(poly);
g2d.setTransform(old);
}
public void keyPressed(KeyEvent k) {
switch(k.getKeyCode()) {
case KeyEvent.VK_LEFT:
rotation--;
if (rotation < 0) rotation = 359;
repaint();
break;
case KeyEvent.VK_RIGHT:
rotation++;
if (rotation > 360) rotation = 0;
repaint();
break;
}
updateTransforms();
}
public void updateTransforms(){
//Resets transform to rotation
rotationTransform.setToRotation(Math.toRadians(rotation));
translateTransform.setToTranslation(getWidth()/2, getHeight()/2);
//Chain the transforms (Note order matters)
transform.setToIdentity();
transform.concatenate(translateTransform);
transform.concatenate(rotationTransform);
}
public void keyReleased(KeyEvent k) {}
public void keyTyped(KeyEvent k) {}
public static void main(String input[]){
JFrame f= new JFrame("AffineTransform");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(100, 100);
f.setResizable(true);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(new AffineTransformTest());
f.show();
}
}
I want to display a GameOver image in a pacman game after lives are over. But I call the paintGameOverScreen(Graphics g) and then I need to initialize g. Is there any other way to do this?
This is my Lives class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class Lives{
private int lives;
public Lives() {
lives = 1;
}
public void removeLife() {
lives--;
if(lives==0){
System.out.println("END GAME");
paintGameOverScreen(g);
System.exit(0);
}
}
public void paintGameOverScreen(Graphics g) {
ImageIcon i = new ImageIcon("src\image");
Image image = i.getImage();
int x = 0;
int y = 0;
g.drawImage(image, x, y, 100,100,null);
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(5*20, 25*20, 100, 30);
g.setColor(Color.BLACK);
String result = "Lives: " + lives;
g.drawString(result, 6*20, 26*20);
}
}
You never call paint() or paintComponent() yourself, you always go through repaint() which will take care of setting up the appropriate Graphics
Just to show what #mKorbel is referring to:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Lives extends JPanel {
private int lives;
private ImageIcon gameOverImage;
public Lives() {
try {
gameOverImage = new ImageIcon(new URL("http://imgup.motion-twin.com/dinorpg/0/f/77acf80b_989624.jpg"));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lives = 5;
}
public void removeLife() {
if (lives > 0) {
lives--;
System.out.println("Left lives: " + lives);
repaint();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (lives > 0) {
System.out.println("Still have " + lives + " lives");
g.setColor(Color.WHITE);
g.fillRect(5 * 20, 25 * 20, 100, 30);
g.setColor(Color.BLACK);
String result = "Lives: " + lives;
g.drawString(result, 6 * 20, 26 * 20);
} else if (gameOverImage != null) {
System.out.println("Game over");
int x = (getWidth() - gameOverImage.getIconWidth()) / 2;
int y = (getHeight() - gameOverImage.getIconHeight()) / 2;
g.drawImage(gameOverImage.getImage(), x, y, gameOverImage.getIconWidth(), gameOverImage.getIconHeight(), this);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame(Lives.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Lives lives = new Lives();
frame.add(lives);
frame.pack();
frame.setVisible(true);
// Dummy timer that reduces the lives every second. For demo purposes only of course
Timer t = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
lives.removeLife();
}
});
t.start();
}
});
}
}
for public void paint(Graphics g) { is there missed container,
JPanel (in some cases JComponent) could be container for todays Java
have to use paintComponent instead of paint()
inside paintComponent you can to flag for paintGameOverScreen, then there paint only BufferedImage
prepare all Objects before, as local variable, do not load any FileIO (load images) inside paint(), paintComponent()
Here is how I did:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
public class InitializeGraphics
{
static BufferedImage buffer = null;
static int height = 10;
static int width = 10;
static Graphics2D g2;
public InitializeGraphics() {
buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
g2 = buffer.createGraphics();
g2.fillOval(2, 2, 2, 2);
g2.dispose();
}
protected void paintComponent(Graphics g) {
int x = 0;
int y = 0;
g.drawImage(buffer, x, y, width, height, null);
}
public Graphics2D getGraphics(){
return g2;
}
}
Then somewhere:
InitializeGraphics instance=new InitializeGraphics();
Graphics2D gG2 = instance.getGraphics();
So I have 4 classes, in my paint program and I am trying to add scrollbars to the canvas so that I can scroll around, When I make my buffered Image it is set to the size of the desktop, but the JFrame is only I think 700 or so pixels so as you expand or resize you are still on canvas. But I cant figure out how to add a JScrollPane to the buffered image so I can scroll around.
//MAIN//
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Main
{
public static int choice;
public static void main(String[] args)
{
Board.getInstance();
}
}
//FRAME//
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
*
* #author Calvin Moss
*/
public class Board extends JFrame implements ActionListener
{
public static Board inst;
Board()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.add(Menu.getInstance(), BorderLayout.NORTH);
getContentPane().add(Drawing.getInstance(), BorderLayout.CENTER);
Drawing.getInstance().add(new JScrollPane());
setSize(1200, 800);
setBackground(Color.WHITE);
setVisible(true);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu help = new JMenu("Help");
menuBar.add(help);
JMenuItem about = new JMenuItem("About");
help.add(about);
about.addActionListener(this);
}
public static Board getInstance()
{
if(inst == null)
inst = new Board();
return inst;
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("About"))
{
JFrame about = new JFrame("About");
about.setSize(300, 300);
JButton picture = new JButton(new ImageIcon("C:/Users/TehRobot/Desktop/Logo.png"));
about.add(picture);
about.setVisible(true);
}
}
}
//MENUPANEL//
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.TitledBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.image.BufferedImage;
/**
*
* #author Calvin Moss
*/
public class Menu extends JPanel implements MouseListener, ActionListener{
public static Color bgColor = null;
public static int stroke = 0;
public static Menu instance;
private JButton clear;
private JButton line;
private JButton color;
private JButton erase;
private JButton pen;
public static boolean once = true;
public static BufferedImage buf = new BufferedImage(50,25,2);
public static Graphics2D gr = buf.createGraphics();
public static BufferedImage buf2 = new BufferedImage(50,25,2);
public static Graphics2D gr2 = buf2.createGraphics();
public static BufferedImage buf3 = new BufferedImage(50,25,2);
public static Graphics2D gr3 = buf3.createGraphics();
public static BufferedImage buf1 = new BufferedImage(50,25,2);
public static Graphics2D gr1 = buf1.createGraphics();
Menu()
{
setBackground(Color.GRAY);
TitledBorder titledBorder = BorderFactory.createTitledBorder("Toolbox");
setBorder(titledBorder);
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
;
clear = new JButton("Clear");
clear.setActionCommand("Clear");
clear.addActionListener(this);
pen = new JButton("Pen");
pen.setActionCommand("Pen");
pen.addActionListener(this);
erase = new JButton("Erase");
erase.setActionCommand("e");
erase.addActionListener(this);
color = new JButton("Color");
color.setActionCommand("Color");
color.addActionListener(this);
ImageIcon ir2 = new ImageIcon(buf3);
JButton emptyR = new JButton(ir2);
emptyR.addActionListener(this);
emptyR.setActionCommand("ER");
ImageIcon ir1 = new ImageIcon(buf2);
JButton emptyO = new JButton(ir1);
emptyO.addActionListener(this);
emptyO.setActionCommand("EO");
ImageIcon ir = new ImageIcon(buf);
JButton fillR = new JButton(ir);
fillR.addActionListener(this);
fillR.setActionCommand("FR");
ImageIcon io = new ImageIcon(buf1);
JButton fillO = new JButton(io);
fillO.addActionListener(this);
fillO.setActionCommand("FO");
line = new JButton("Line");
line.setActionCommand("L");
line.addActionListener(this);
JButton button6 = new JButton("Line");
button6.addActionListener(this);
JRadioButton thin = new JRadioButton("Thin Line");
thin.addActionListener(this);
JRadioButton medium = new JRadioButton("Medium Line");
medium.addActionListener(this);
JRadioButton thick = new JRadioButton("Thick Line");
thick.addActionListener(this);
ButtonGroup lineOption = new ButtonGroup( );
lineOption.add(thin);
lineOption.add(medium);
lineOption.add(thick);
add(clear);
add(erase);
add(color);
add(pen);
add(line);
add(thin);
add(medium);
add(thick);
add(emptyR);
add(emptyO);
add(fillR);
add(fillO);
buttonGraphics();
once = false;
}
public static Menu getInstance()
{
if(instance == null)
instance = new Menu();
return instance;
}
public static void buttonGraphics()
{
if (once == true)
{
gr.setColor(Color.RED);
gr1.setColor(Color.RED);
gr2.setColor(Color.RED);
gr3.setColor(Color.RED);
}else
gr3.setColor(bgColor);
gr3.drawRect(0, 0, 48, 23);
gr2.setColor(bgColor);
gr2.drawOval(0, 0, 47, 23);
gr.setColor(bgColor);
gr.fillRect(0, 0, 50, 23);
gr1.setColor(bgColor);
gr1.fillOval(0, 0, 50, 25);
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Clear"))
{
Drawing.getInstance().clear();
repaint();
}
if (e.getActionCommand().equals("e"))
{
Main.choice = 8;
Drawing.getInstance().draw();
}
if (e.getActionCommand().equals("Color"))
{
bgColor = JColorChooser.showDialog(this,"Choose Background Color", getBackground());
gr.setColor(bgColor);
gr1.setColor(bgColor);
gr2.setColor(bgColor);
gr3.setColor(bgColor);
Main.choice = 7;
buttonGraphics();
repaint();
Drawing.getInstance().draw();
}
if (e.getActionCommand().equals("L"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 1;
repaint();
}
if (e.getActionCommand().equals("FR"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 2;
repaint();
}
if (e.getActionCommand().equals("EO"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 3;
repaint();
}
if (e.getActionCommand().equals("FO"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 4;
repaint();
}
if(e.getActionCommand().equals("ER"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 5;
repaint();
}
if (e.getActionCommand().equals("Thin Line"))
{
stroke = 0;
Drawing.getInstance().eraserHeight = 5;
Drawing.getInstance().eraserWidth = 5;
}
if (e.getActionCommand().equals("Medium Line"))
{
stroke = 1;
Drawing.getInstance().eraserHeight = 15;
Drawing.getInstance().eraserWidth = 15;
}
if (e.getActionCommand().equals("Thick Line"))
{
stroke = 2;
Drawing.getInstance().eraserHeight = 25;
Drawing.getInstance().eraserWidth = 25;
}
if(e.getActionCommand().equals("Pen"))
{
Main.choice = 10;
Drawing.getInstance().draw();
}
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
}
//DRAWING CANVAS PANEL//
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.event.*;
import java.awt.image.BufferedImage;
/**
*
* #author Calvin Moss
*/
public class Drawing extends JPanel implements MouseListener, ActionListener, MouseMotionListener
{
public int x1, x2 ,y1, y2;
public static Drawing instance;
public int FoE;
public int eraserWidth = 15;
public int eraserHeight = 15;
BufferedImage grid;
static Graphics2D gc;
Drawing()
{
setBackground(Color.RED);
addMouseListener(this);
}
public static Drawing getInstance()
{
if(instance == null)
instance = new Drawing();
return instance;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
if(grid == null)
{
Toolkit toolkit = Toolkit.getDefaultToolkit ();
Dimension dim = toolkit.getScreenSize();
grid = (BufferedImage)(this.createImage(dim.width,dim.height));
gc = grid.createGraphics();
gc.setColor(Color.RED);
BufferedImage grid;
Graphics2D gc;
}
g2.drawImage(grid, null, 0, 0);
}
public void draw()
{
Graphics2D g = (Graphics2D)getGraphics();
int w = x2 - x1;
if (w<0)
w = w *(-1);
int h = y2-y1;
if (h<0)
h= h*(-1);
gc.setColor(Menu.bgColor);
switch(Main.choice)
{
case 1:
{
removeMouseMotionListener(instance);
if (Menu.stroke == 0)
gc.setStroke(new BasicStroke (1));
if (Menu.stroke == 1)
gc.setStroke(new BasicStroke (3));
if (Menu.stroke == 2)
gc.setStroke(new BasicStroke (6));
gc.drawLine(x1, y1, x2, y2);
repaint();
break;
}
case 2:
{
removeMouseMotionListener(instance);
check();
gc.drawRect(x1, y1, w, h);
gc.fillRect(x1, y1, w, h);
repaint();
break;
}
case 3:
{
removeMouseMotionListener(instance);
check();
gc.drawOval(x1, y1, w, h);
repaint();
break;
}
case 4:
{
removeMouseMotionListener(instance);
check();
gc.drawOval(x1, y1, w, h);
gc.fillOval(x1, y1, w, h);
repaint();
break;
}
case 5:
{
removeMouseMotionListener(instance);
check();
gc.drawRect(x1, y1, w, h);
repaint();
break;
}
case 6:
{
removeMouseMotionListener(instance);
repaint();
Color temp = gc.getColor();
gc.setColor(Color.WHITE);
gc.fillRect(0, 0, getWidth(), getHeight());
gc.setColor(temp);
repaint();
break;
}
case 7:
{
removeMouseMotionListener(instance);
gc.setColor(Menu.bgColor);
break;
}
case 8:
{
FoE = 0;
addMouseMotionListener(instance);
break;
}
case 10:
{
FoE = 1;
addMouseMotionListener(instance);
break;
}
}
}
public void check()
{
if (Menu.stroke == 0)
gc.setStroke(new BasicStroke (1));
if (Menu.stroke == 1)
gc.setStroke(new BasicStroke (3));
if (Menu.stroke == 2)
gc.setStroke(new BasicStroke (6));
if (x1 > x2)
{
int z = 0;
z = x1;
x1 = x2;
x2 =z;
}
if (y1 > y2)
{
int z = 0;
z = y1;
y1 = y2;
y2 = z;
}
}
public void clear()
{
repaint();
Color temp = gc.getColor();
gc.setColor(Color.WHITE);
gc.fillRect(0, 0, getWidth(), getHeight());
gc.setColor(temp);
repaint();
}
public void mouseExited(MouseEvent e){ }
public void mouseEntered(MouseEvent e){}
public void mouseClicked(MouseEvent e){
}
public void mousePressed(MouseEvent evt)
{
x1 = evt.getX();
y1= evt.getY();
}
public void mouseReleased(MouseEvent evt)
{
x2 = evt.getX();
y2 = evt.getY();
removeMouseMotionListener(instance);
draw();
}
public void mouseDragged(MouseEvent me)
{
check();
if (FoE == 0)
{
Color c = gc.getColor();
gc.setColor(Color.WHITE);
gc.drawOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
gc.fillOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
gc.setColor(c);
repaint();
}
else if (FoE == 1)
{
gc.setColor(gc.getColor());
gc.drawOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
gc.fillOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
repaint();
}
else
{
}
}
public void mouseMoved(MouseEvent arg0)
{
}
public void actionPerformed(ActionEvent arg0) {
}
}
I haven't tested your code but it looks like you're trying to add add JScrollPane to your JPanel (Drawing). It should be the other way around you should add the JPanel to the JScrollPane and then add the JScrollPane to the content pane of the frame:
JScrollPane scrollPane = new JScrollPane(Drawing.getInstance());
getContentPane().add(scrollPane, BorderLayout.CENTER);
How to use JScrollPane
You need to override the getPreferredSize() method of your Drawing class to return the size of the BufferedImages.
Scrollbars only appear when the preferred size of the component added to the scroll pane is greater than the size of the scroll pane.