Capture/Save JPanel image - java

I am new to java and now like to make an application for drawing images and capturing it through JPanel. I tried a lot but failed. The code I used is given below. Please help
Thanks in advance.
The program draws images by dragging the mouse. And type a character in the textbox provided the press scan
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class SwingPaintDemo3 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
final JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(null);
f.setBounds(0,0,800,600);
JButton scanButton=new JButton("Scan");
scanButton.setBounds(0,0,75, 40);
f.add(scanButton);
JButton eraseButton=new JButton("Erase");
eraseButton.setBounds(0,50,75, 40);
f.add(eraseButton);
JLabel label1=new JLabel("Program developed by Gopakumar in connection with MCA project MCP 60");
label1.setBounds(0, 500, 600,50);
f.add(label1);
final JTextField textBox=new JTextField();
textBox.setBounds(510, 50,50,50);
f.add(textBox);
Font font=new Font(Font.SANS_SERIF,Font.BOLD,50);
textBox.setFont(font);
final JLabel label2=new JLabel("Please type the Character for training");
label2.setBounds(505, 110, 600,50);
f.add(label2);
final MyPanel pan=new MyPanel();
f.add(pan);
f.setVisible(true);
eraseButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
f.repaint();
}
});
scanButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(textBox.getDocument().getLength()<1){
label2.setText("Please type the Character for training");
label2.setForeground(Color.red);
}
else if(textBox.getDocument().getLength()>1){
label2.setText("please Enter only one character");
}
else{
label2.setForeground(Color.BLACK);
label2.setText("Please type the Character for training");
scan(pan);
}
}
});
}
private static void scan(MyPanel pan1) {
int i,j;
pan1.bi.getGraphics();
pan1.paint(pan1.gd);
// Save your screen shot with its label
File outputfile = new File("image.jpg");
try {
ImageIO.write(pan1.bi, "jpg", outputfile);
} catch (IOException ex) {
Logger.getLogger(SwingPaintDemo3.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
class MyPanel extends JPanel {
private int x = 0;
private int y = 0;
private int ox = 0;
private int oy = 0;
private Graphics graphicsForDrawing;
//private boolean dragging;
public BufferedImage bi=new BufferedImage(400,400,BufferedImage.TYPE_INT_RGB);
public Graphics gd;
public MyPanel() {
this.gd = bi.getGraphics();
this.paint(gd);
setBorder(BorderFactory.createLineBorder(Color.black));
this.setBackground(Color.WHITE);
this.setBounds(100, 50,400, 400);
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
ox = x;
oy = y;
// dragging = true;
setUpDrawingGraphics();
}
});
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
graphicsForDrawing.drawLine(ox, oy, x, y);
gd.drawLine(ox, oy, x, y);
ox = x;
oy = y;
}
});
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e){
if(SwingUtilities.isRightMouseButton(e)){
clear();
}
}
});
}
private void setUpDrawingGraphics() {
graphicsForDrawing = getGraphics();
graphicsForDrawing.setColor(Color.black);
gd.setColor(Color.black);
}
public void clear(){
repaint();
}
public Dimension getPreferredSize() {
return new Dimension(400,300);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
gd.drawImage(bi,0, 0, this);
}
}

I would suggest only drawing to your buffered image at the time you draw on the panel.
So you could remove your whole paintComponent(...) method, change your mouse drag listener to this:
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
Graphics g = bi.getGraphics();
g.setColor(Color.green);
g.drawLine(ox, oy, x, y);
getGraphics().drawLine(ox, oy, x, y);
ox = x;
oy = y;
}
});
And then change your scan method to this:
private static void scan(MyPanel pan1) {
int i,j;
// Save your screen shot with its label
File outputfile = new File("image.jpg");
try {
ImageIO.write(pan1.bi, "jpg", outputfile);
} catch (IOException ex) {
ex.printStackTrace();
}
}

Related

Adding a class into a frame and fixing button

Ok so i made this program that moves the picture to the end and when you click on a button, it draws a line from the picture to this point. I am able to make the whole button thing, however, I suck at layouts and stuff. So when i run my program, it opens 2 java programs, one where the animation is happening and one for button.. I dont want that.. I want the button to be on the same java program as the animation. Also, I am trying to set the background color but it isn't working.. I am sure it has to do with frames or something.. idk. Please help. Here is my class for main method:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class example extends JFrame implements Runnable, ActionListener{
private int W=1000;
private int H=1500;
private Thread thread;
private int c=1;
int q=0;
Image image= new ImageIcon("Pictures/car.png").getImage();
private move greenCar;
public example(){
setBounds(100,100,W,H);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setBackground(Color.CYAN);
thread= new Thread(this);
greenCar=new move(image,30,70,98,40);
thread.start();
}
public void paint(Graphics g){
super.paint(g);
//draws the image on the screen
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), this);
//c becomes 2 if the image has reached x=699 and if the button is pressed, q becomes greater than 0
if(c==2 &&q>0)
{
//and when that happens, a line gets created from stretching from the picture to a point
g.drawLine(greenCar.getX(), greenCar.getY(), 10, 20);
g.setColor(Color.BLACK);
}
}
public static void main(String[] args) {
//new example();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new example().createGui();
}
});
}
protected void createGui() {
JFrame frame = new JFrame("Button");
frame.setSize(30, 30);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
frame.add(panel);
frame.getContentPane().add(panel, BorderLayout.WEST);
GridBagConstraints c = new GridBagConstraints();
JButton button1 = new JButton("Profile");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(40, 40, 40, 40);
panel.add(button1, c);
button1.addActionListener(this);
}
public void run() {
while(true)
{
//starting the animation
greenCar.animate();
repaint();
//if the picture is above 698, set c as 2
if(greenCar.getX()>698)
{
c=2;
}
try{
thread.sleep(13);
}
catch(InterruptedException e){
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
//q, which was initially 0, gets incremented
q++;
}
}
and for the animation of image:
import java.awt.Image;
public class move {
private Image img;
private int x,y,width,height;
public move(Image img, int x,int y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
this.img=img;
}
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = img;
}
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 int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void animate(){
if(getX()<700)
setX(getX()+1);
if(getX()>700)
x=701;
}
}

Why are drawn lines automatically erased?

I am building up a system with a canvas where user can draw lines by dragging the mouse in Java. I want all the strokes to be stored and displayed. However, when I press the mouse to draw a new line, previous lines are automatically erased, which is not what I was expecting. How can I solve this problem?
Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FreeDrawing extends JPanel implements MouseListener, MouseMotionListener {
private int indexOfStroke = 0;
private int indexOfPoint = 0;
private Stroke[] strokes = new Stroke[50];
private Point[] currentPoints = new Point[500];
public FreeDrawing(String name) {
super();
this.addMouseListener(this);
this.addMouseMotionListener(this);
JFrame fr = new JFrame(name);
fr.add(this);
fr.setSize(500, 500);
setBackground(Color.GRAY);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setVisible(true);
}
public void paintComponent(Graphics g) {
System.out.println("Paint");
super.paintComponents(g);
strokes[indexOfStroke] = new Stroke();
for (int i = 0; i < indexOfPoint - 1; i++) {
System.out.println("Really draw");
g.drawLine(currentPoints[i].x, currentPoints[i].y, currentPoints[i + 1].x, currentPoints[i + 1].y);
}
}
public void mouseDragged(MouseEvent e) {
System.out.println("Drag");
currentPoints[indexOfPoint] = new Point(e.getX(), e.getY());
indexOfPoint++;
repaint();
}
public void mousePressed(MouseEvent e) {
System.out.println("Press");
currentPoints[indexOfPoint] = new Point(e.getX(), e.getY());
indexOfPoint = 0;
repaint();
}
public void mouseReleased(MouseEvent e) {
indexOfPoint = 0;
indexOfStroke++;
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public static void main(String[] args) {
FreeDrawing canvas = new FreeDrawing("Mouse");
}
}
class Stroke {
public Stroke() {
System.out.println("Stroke initiated");
points = new Point[500];
}
Point[] points;
}
Because, that's how painting works, see Painting in AWT and Swing and Performing Custom Painting for more details.
Basically, painting is destructive, meaning that each time paintComponent is called, you are expected to repaint the entire state of the component from scratch
One thing you might consider doing, is creating a class which contains the stroke, color and points you need to each line and store that in a List each time you click
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
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<Drawing> drawings;
private Drawing current;
private Random rnd = new Random();
public TestPane() {
drawings = new ArrayList<>(25);
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Stroke stroke = new BasicStroke(rnd.nextInt(9) + 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
Color color = new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255));
current = new Drawing(stroke, color);
current.addPoint(e.getPoint());
drawings.add(current);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
current.addPoint(e.getPoint());
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawing drawing : drawings) {
drawing.paint(g2d);
}
g2d.dispose();
}
}
public class Drawing {
private Stroke stroke;
private Color color;
private List<Point> points;
public Drawing(Stroke stroke, Color color) {
this.stroke = stroke;
this.color = color;
this.points = new ArrayList<>(25);
}
public void addPoint(Point p) {
points.add(p);
}
public void paint(Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(color);
g2d.setStroke(stroke);
if (!points.isEmpty()) {
Point from = points.get(0);
for (Point to : points.subList(1, points.size())) {
g2d.draw(new Line2D.Double(from, to));
from = to;
}
}
g2d.dispose();
}
}
}

JAVA drawing graphic

I want to draw a rectangle on an image when the mouse button is pressed and released. And this part works just fine. Now I want to be able to see the rectangle while I drag the mouse, what I get is lots of rectangles being drawn please help.
class ActionTemp implements ActionListener {
public void actionPerformed(ActionEvent e) {
myPanel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent event) {
letsdraw = tempimage.createGraphics();
Point panelPoint = event.getPoint();
sX = panelPoint.x;
sY = panelPoint.y;
}
#Override
public void mouseReleased(MouseEvent event) {
letsdraw.draw(new Rectangle2D.Float(Math.min(sX, curX),
Math.min(sY, curY), Math.abs(sX - curX),
Math.abs(sY - curY)));
letsdraw.dispose();
myPanel.repaint();
}
});
myPanel.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
Point panelPoint = event.getPoint();
curX = panelPoint.x;
curY = panelPoint.y;
letsdraw.draw(new Rectangle2D.Float(Math.min(sX, curX),
Math.min(sY, curY), Math.abs(sX - curX),
Math.abs(sY - curY)));
myPanel.repaint();
}
});
}
}
Start by having a look at Painting in AWT and Swing and Performing Custom Painting.
The basic problem is, you painting directly to the image, which means, unless you have a separate copy, you're just compounding each successive rectangle on top of the last.
Instead, you want to paint each of them separately, something like...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SelectionExample {
public static void main(String[] args) {
new SelectionExample();
}
public SelectionExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Rectangle selection = new Rectangle();
private Point clickPoint;
private BufferedImage tempimage;
public TestPane() {
try {
tempimage = ImageIO.read(new File("/Users/shane/Dropbox/MegaTokyo/thumnails/2.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
int minX = Math.min(e.getX(), clickPoint.x);
int minY = Math.min(e.getY(), clickPoint.y);
int maxX = Math.max(e.getX(), clickPoint.x);
int maxY = Math.max(e.getY(), clickPoint.y);
selection.x = minX;
selection.y = minY;
selection.width = maxX - minX;
selection.height = maxY - minY;
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
clickPoint = new Point(e.getPoint());
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
#Override
public Dimension getPreferredSize() {
return tempimage == null ? new Dimension(200, 200) : new Dimension(tempimage.getWidth(), tempimage.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - tempimage.getWidth()) / 2;
int y = (getHeight() - tempimage.getHeight()) / 2;
g2d.drawImage(tempimage, x, y, this);
if (selection.width > 0 && selection.height > 0) {
g2d.setColor(new Color(0, 0, 255, 64));
g2d.fill(selection);
g2d.setColor(Color.BLUE);
g2d.draw(selection);
}
g2d.dispose();
}
}
}

Use MouseListener to draw circles?

I'm trying to write a program that allows user to specify a circle with 2 mouse presses, the first one on the center and the second on a point on the periphery, and the program I wrote is this.
import javax.swing.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.*;
public class CircleFrame extends JFrame
{
public CircleFrame()
{
circle = new Ellipse2D.Double();
hasCenter = false;
createComponent();
setSize(400, 400);
}
private void createComponent()
{
class CircleComponent extends JComponent
{
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
circle.setFrame(xTop, yTop, radius*2, radius*2);
g2.draw(circle);
}
}
class MousePressListener1 extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
if(!hasCenter)
{
xCenter = event.getX();
yCenter = event.getY();
hasCenter = true;
}
}
}
class MousePressListener2 extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
if (hasCenter)
{
xOut = event.getX();
yOut = event.getY();
xTop = xCenter - Math.abs(xOut - xCenter);
yTop = yCenter - Math.abs(yOut - yCenter);
radius =
Math.sqrt((xOut - xCenter)*(xOut - xCenter) + (yOut - yCenter)*(yOut - yCenter));
hasCenter = false;
}
}
}
addMouseListener(new MousePressListener1());
addMouseListener(new MousePressListener2());
CircleComponent component = new CircleComponent();
add(component);
}
private double xTop;
private double yTop;
private int xCenter;
private int yCenter;
private int xOut;
private int yOut;
private Ellipse2D.Double circle;
private double radius;
private boolean hasCenter;
}
And this is the main class
import javax.swing.JFrame;
public class CircleFrameViewer
{
public static void main(String[] args)
{
JFrame frame = new CircleFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Somehow it only shows a blank frame, and no clicks make anything happen.
Anyone can help me?
Don't use two listeners, use one, both listeners will be called whenever a mouse event occurs.
MouseEvents are contextual to the component which generated them. This means you should be adding your listener to the CircleComponent
Make sure you are calling repaint when you want the UI to be updated.
Something like...for example
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test2 {
public static void main(String[] args) {
new Test2();
}
public Test2() {
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 Point centerPoint;
private Shape circle;
public TestPane() {
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (centerPoint == null) {
centerPoint = e.getPoint();
repaint();
} else {
double xTop = Math.min(e.getPoint().x, centerPoint.x);
double yTop = Math.min(e.getPoint().y, centerPoint.y);
double xBottom = Math.max(e.getPoint().x, centerPoint.x);
double yBottom = Math.max(e.getPoint().y, centerPoint.y);
double radius = Math.max(xBottom - xTop, yBottom - yTop);
xTop = centerPoint.x - radius;
yTop = centerPoint.y - radius;
radius *= 2;
circle = new Ellipse2D.Double(xTop, yTop, radius, radius);
repaint();
}
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (circle != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.draw(circle);
g2d.dispose();
}
}
}
}

Java - redraw background

I want to redraw background with different image. Here's a SSCCE example - I'd like to add an action to Listener that will repaint with another image.
package painting;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;
public class SwingPaintDemo3 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private int squareX = 50;
private int squareY = 50;
private int squareW = 20;
private int squareH = 20;
Image img;
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
}
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX!=x) || (squareY!=y)) {
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
squareX=x;
squareY=y;
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
}
}
public Dimension getPreferredSize() {
return new Dimension(250,200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
try {
img = ImageIO.read(new File("graphics/close_0.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.drawImage(img, 0, 0, null);
g.drawString("This is my custom Panel!",10,20);
g.setColor(Color.RED);
g.fillRect(squareX,squareY,squareW,squareH);
g.setColor(Color.BLACK);
g.drawRect(squareX,squareY,squareW,squareH);
}
}
So what method should I call to redraw background with different image?
As much as I understand the question (which is 'very little') this source might lead you forward. Note that code should never attempt a potentially blocking operation (like loading an image) within the paint or paintComponent method.
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.util.Random;
public class SwingPaintDemo3 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private int squareX = 50;
private int squareY = 50;
private int squareW = 20;
private int squareH = 20;
Image img;
Random r = new Random();
public MyPanel() {
img = new BufferedImage(40,40,BufferedImage.TYPE_INT_RGB);
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
img = new BufferedImage(
r.nextInt(getWidth())+1,
r.nextInt(getHeight())+1,
BufferedImage.TYPE_INT_RGB);
moveSquare(e.getX(),e.getY());
}
});
}
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX!=x) || (squareY!=y)) {
squareX=x;
squareY=y;
repaint();
}
}
public Dimension getPreferredSize() {
return new Dimension(250,200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
g.drawString("This is my custom Panel!",10,20);
g.setColor(Color.RED);
g.fillRect(squareX,squareY,squareW,squareH);
g.setColor(Color.BLACK);
g.drawRect(squareX,squareY,squareW,squareH);
}
}

Categories