Java swing draw multiple click able shapes - java

I need to make a program that will draw multiple circles/squares, and when they are clicked, the colours change to another random colour. I am unsure how to do this. At the moment I have one circle on a JPanel which has a mouse listener to repaint when the panel is clicked within the bounds of the circle (although this creates a rectangular area to click in, not circular) and I need to extend this to add more shapes that have their own area to be clicked. Any help appreciated. Thanks.
public class CircleGUI extends JFrame {
int ovalWidth = 100;
int ovalHeight = 100;
int ovalX = 100;
int ovalY = 100;
public CircleGUI() {
super("Circle GUI");
this.setSize(500, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go();
this.setVisible(true);
}
public void go() {
CPanel panel = new CPanel();
Container container = getContentPane();
container.add(panel);
panel.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
int radius = ovalWidth / 2;
int centerX = ovalX + radius;
int centerY = ovalY + radius;
if (((e.getX() >= centerX - radius && e.getX() <= centerX + radius) && e.getX() >= centerX - radius
&& e.getX() <= centerX + radius)) {
repaint();
}
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
}
public class CPanel extends JPanel {
public void paint(Graphics g) {
// random colour
g.setColor(new Color(Math.round(Math.random()), Math.round(Math.random()), Math.round(Math.random())));
g.fillOval(ovalX, ovalY, ovalWidth, ovalHeight);
}
}
}

I need to extend this to add more shapes that have their own area to be clicked
You need to keep a List of Objects that you want to paint. That object would contain information like shape and color.
In your paintComponent() method you iterate through the List and paint each shape.
You then add a MouseListener to your panel. When the mouse is clicked you then iterate through the List to find a shape that contains the point that was generated and you update the color of that object and then repaint the panel.
Check out the Draw On Component example from Custom Painting Approaches for an example of this approach. The example only paints Rectangles but should get you started.

Related

How is it possible to make an image follow the framesize in Java? [duplicate]

When a user clicks on the corner of a JFrame to resize and drags the mouse around, the JFrame redraws based on the current position of the mouse as the user drags. How can you listen to these events?
Below is the what I have currently tried:
public final class TestFrame extends JFrame {
public TestFrame() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
// These methods do not appear to be called at all when a JFrame
// is being resized.
#Override
public void setSize(int width, int height) {
System.out.println("setSize");
}
#Override
public void setBounds(Rectangle r) {
System.out.println("setBounds A");
}
#Override
public void setBounds(int x, int y, int width, int height) {
System.out.println("setBounds B");
}
}
How can I determine and constrain how the user resizes a window (based on the current aspect ratio of the window) as they are dragging around the mouse around?
You can add a component listener and implement the componentResized function like that:
JFrame component = new JFrame("My Frame");
component.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
//........
}
});
EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.
One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.
I know, this isn't the most elegant solution, but it works!
Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:
public final class TestFrame extends JFrame {
public TestFrame() {
this.getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
}
Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.
You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.
public class MouseDrag extends Component implements MouseListener,
MouseMotionListener {
/** The Image we are to paint */
Image curImage;
/** Kludge for showStatus */
static Label status;
/** true if we are in drag */
boolean inDrag = false;
/** starting location of a drag */
int startX = -1, startY = -1;
/** current location of a drag */
int curX = -1, curY = -1;
// "main" method
public static void main(String[] av) {
JFrame f = new JFrame("Mouse Dragger");
Container cp = f.getContentPane();
if (av.length < 1) {
System.err.println("Usage: MouseDrag imagefile");
System.exit(1);
}
Image im = Toolkit.getDefaultToolkit().getImage(av[0]);
// create a MouseDrag object
MouseDrag j = new MouseDrag(im);
cp.setLayout(new BorderLayout());
cp.add(BorderLayout.NORTH, new Label(
"Hello, and welcome to the world of Java"));
cp.add(BorderLayout.CENTER, j);
cp.add(BorderLayout.SOUTH, status = new Label());
status.setSize(f.getSize().width, status.getSize().height);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// "Constructor" - creates the object
public MouseDrag(Image i) {
super();
curImage = i;
setSize(300, 200);
addMouseListener(this);
addMouseMotionListener(this);
}
public void showStatus(String s) {
status.setText(s);
}
// Five methods from MouseListener:
/** Called when the mouse has been clicked on a component. */
public void mouseClicked(MouseEvent e) {
}
/** Called when the mouse enters a component. */
public void mouseEntered(MouseEvent e) {
}
/** Called when the mouse exits a component. */
public void mouseExited(MouseEvent e) {
}
// And two methods from MouseMotionListener:
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
// System.err.println("mouse drag to " + p);
showStatus("mouse Dragged to " + p);
curX = p.x;
curY = p.y;
if (inDrag) {
repaint();
}
}
public void paint(Graphics g) {
int w = curX - startX, h = curY - startY;
Dimension d = getSize();
g.drawImage(curImage, 0, 0, d.width, d.height, this);
if (startX < 0 || startY < 0)
return;
System.err.println("paint:drawRect #[" + startX + "," + startY
+ "] size " + w + "x" + h);
g.setColor(Color.red);
g.fillRect(startX, startY, w, h);
}
}

Java - Drawing shape with mouse and drag after clicking button

I would like to do this without the use of the JComponent. The idea is to have multiple buttons for each a shape, by clicking a button, I can then draw the shape for that button. Unfortunately, I can't even draw the shapes right now.
public static void main(String[] args) {
JFrame frame = new JFrame();
JButton rect = new JButton("Rectangle");
ActionListener rListener = new RectangleNode();
rect.addActionListener(rListener);
MouseListener rMListener = new RectangleNode();
rect.addMouseListener(rMListener);
MouseMotionListener rMMListener = new RectangleNode();
rect.addMouseMotionListener(rMMListener);
JButton ellipse = new JButton("Ellipse");
JPanel panel = new JPanel();
panel.add(rect);
panel.add(ellipse);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setTitle("Graph Draw");
frame.setVisible(true);
}
The RectangleNode class
public class RectangleNode implements ActionListener,MouseListener,MouseMotionListener {
private Point p1;
private Rectangle r;
private boolean rdraw;
#Override
public void actionPerformed(ActionEvent e) {
rdraw = true;
}
#Override
public void mousePressed(MouseEvent e) {
if(rdraw = true){
p1 = e.getPoint();
r = new Rectangle(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
}
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
if(rdraw = true){
int x = Math.min(p1.x, e.getX());
int y = Math.min(p1.y, e.getY());
int width = Math.abs(p1.x - e.getX());
int height = Math.abs(p1.y - e.getY());
r.setBounds(x, y, width, height);
repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.draw(r); ;
}
}
I'm not sure how to use repaint, and the paintComponent method in this situation.
Check out Custom Painting Approaches for an example of how to dynamically draw Rectangles.
In your case you want the ability to draw a Rectangle or an Ellipse so you would need to make some changes:
The Java API supports a Shape class. A Shape can be a Rectangle, Ellipse, Polygon etc. So you would need to change the "ColoredRectangle" class to a "ColoredShape" class. This would allow you to store a Rectangle or an Ellipse.
Then in the paintComponent() code you would need to change the drawRect(..) method to be a draw( Shape ) so you can draw both Rectangles and Ellipses.
In the mouseDragged() logic you would need to modify the logic to check if you want to draw a Rectangle or an Ellispse. Then you would create the proper Shape and again use the draw( Shape ) method instead of the drawRect(...) method.
Then you would need to add a property to the class to control which Shape you want to paint. Then when you click the button you set the property. Or maybe instead of using a button you set up radio buttons for each Shape.
Anyway, play with the original code to understand how it works. That is start by converting the code to use the ColoredShape class just for Rectangles. Then once that works you can add the support for the Ellipse.

e.getY() return value higher than expected

When I press somewhere near Top-Left of the window, for some reason the output result for e.getY() is higher by about 40 than e.getX(). I don't see why... do you? Something is not clear to me regarding e.getY().
//BBDemo.java - The main program and window creation
import javax.swing.*;
public class BBDemo extends JApplet{ //this isn't Applet !
public int offset=400;
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame win = new JFrame("Bouncing Ball Demo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setContentPane(new BBPanel());
win.pack();
win.setVisible(true);
}
}//endclass BBDemo
//BBPanel.java - The JPanel which organizes the GUI
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/////////////////////////////////////////////////////////////////// BBPanel
public class BBPanel extends JPanel {
BallInBox m_bb; // The bouncing ball panel ///in order to take the Timer->setAnimation from m_bb
Ball BallN;
//========================================================== constructor
/** Creates a panel with the controls and bouncing ball display. */
BBPanel() {
//... Create components
m_bb = new BallInBox();
BallN=new Ball(400,400,400);
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
//... Add Listeners
startButton.addActionListener(new StartAction());
stopButton.addActionListener(new StopAction());
addMouseListener(new PressBall());
//... Layout inner panel with two buttons horizontally ///why inner and outer?
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout()); ///Flow???
buttonPanel.add(startButton);
buttonPanel.add(stopButton);
//... Layout outer panel with button panel above bouncing ball ///???
this.setLayout(new BorderLayout()); ///this ??? ///Board???
this.add(buttonPanel, BorderLayout.NORTH); ///this, NORTH, ???
this.add(m_bb , BorderLayout.CENTER); ///this, CENTER, ???
}//end constructor
////////////////////////////////////// inner listener class StartAction
class StartAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
m_bb.setAnimation(true);
}
}
//////////////////////////////////////// inner listener class StopAction
class StopAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
m_bb.setAnimation(false);
}
}
public class PressBall implements MouseListener {
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
//System.out.print(BallN.m_x-BallN.getDiameter()/2+" ");
System.out.print(e.getX()+" ");
//System.out.print(BallN.m_x+BallN.getDiameter()/2+" ");
//System.out.print(BallN.m_y-BallN.getDiameter()/2+" ");
System.out.print(e.getY()+" ");
//System.out.println(BallN.m_y+BallN.getDiameter()/2+" ");
if ((e.getButton() == 1)
&& (e.getX() >= BallN.m_x-BallN.getDiameter()/2 && e.getX() <=
BallN.m_x+BallN.getDiameter()/2 && e.getY() >= BallN.m_y-BallN.getDiameter()/2 && e.getY() <=
BallN.m_y+BallN.getDiameter()/2 ))
{ m_bb.setAnimation(false);
}else{}
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
}//endclass BBPanel
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/////////////////////////////////////////////////////////////// BouncingBall
public class BallInBox extends JPanel {
//============================================== fields
public Ball m_ball = new Ball(400,400,400);
private int m_interval = 40; // Milliseconds between updates.
private Timer m_timer; // Timer fires to animate one step.
//=================================================== constructor
public BallInBox() {
setPreferredSize(new Dimension(800, 800));
setBorder(BorderFactory.createLineBorder(Color.BLACK));
m_timer = new Timer(m_interval, new TimerAction());
}
//========================================================= setAnimation
public void setAnimation(boolean turnOnOff) {
if (turnOnOff) {
m_timer.start(); // start animation by starting the timer.
} else {
m_timer.stop(); // stop timer
}
}
//======================================================= paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g); // Paint background, border
m_ball.draw(g); // Draw the ball.
// m_ball.changeColor(g);
}
class TimerAction implements ActionListener {
//================================================== actionPerformed
public void actionPerformed(ActionEvent e) {
m_ball.setBounds(getWidth(), getHeight()); ///???
m_ball.move(); // Move the ball.
repaint(); // Repaint indirectly calls paintComponent. ///why "indirectly"?
}
/* public void mousePressed(MouseEvent e) {
System.out.println("dfvsd");
if ((e.getButton() == 1)
&& (e.getX() >= 400- m_ball.m_x && e.getX() <= 400+ m_ball.m_x && e.getY() >=
400- m_ball.m_x && e.getY() <= 400+ m_ball.m_x)) {m_timer.stop();
// System.out.println("dfvsd");
}else{}
}*/
}
//////////////////////////////////////// inner listener class StopAction
}//endclass
import java.awt.*;
///////////////////////////////////////////////////////////////// BallModel
public class Ball {
//... Constants
final static int DIAMETER = 50;
//... Instance variables
static int m_x; // x and y coordinates upper left
static int m_y;
/*
private int m_velocityX; // Pixels to move each time move() is called.
private int m_velocityY;*/
private int m_rightBound; // Maximum permissible x, y values.
private int m_bottomBound;
public int i=0;
public int offset=400;
//======================================================== constructor
public Ball(int x, int y, int offset) {
m_x = x;
m_y = y;
//offset=400;
}
//======================================================== setBounds
public void setBounds(int width, int height) {
m_rightBound = width - DIAMETER;
m_bottomBound = height - DIAMETER;
}
//============================================================== move
public void move() {
double degrees=(double) i;
double radians=Math.toRadians(degrees);
double Sinu=Math.sin(radians);
double Sinu200=Math.sin(radians)*300;
int SinuInt=(int) Sinu200;
m_y=offset+SinuInt;
//z=offset-SinuInt;
double Cos=Math.cos(radians);
double Cos200=Math.cos(radians)*300;
int CosInt=(int) Cos200;
m_x=offset+CosInt;
i++; // j--;
if (i==360) i=0;
//w=offset-CosInt;
/*
//... Bounce the ball off the walls if necessary.
if (m_x < 0) { // If at or beyond left side
m_x = 0; // Place against edge and
m_velocityX = -m_velocityX; // reverse direction.
} else if (m_x > m_rightBound) { // If at or beyond right side
m_x = m_rightBound; // Place against right edge.
m_velocityX = -m_velocityX; // Reverse direction.
}
if (m_y < 0) { // if we're at top
m_y = 0;
m_velocityY = -m_velocityY;
} else if (m_y > m_bottomBound) { // if we're at bottom
m_y = m_bottomBound;
m_velocityY = -m_velocityY;
}*/
}
//============================================================== draw
public void draw(Graphics g) {
g.setColor(Color.green);
g.fillOval(m_x, m_y, DIAMETER, DIAMETER);
}
//======================================================== setPosition
public void setPosition(int x, int y) {
m_x = x;
m_y = y;
}
}
If the window is decorated, then you have to take into account the title bar height.
This is probably due to the blue strip (title bar, not sure if that's the right term) which most GUI programs have at their top.

Graphics are too slow when using drawRect

I'm making a drawing board, and I have a few questions.
Whenever I try to draw on it, it doesn't automatically update. Ad I usually have to resize the screen for it to update.
How can I do something like a mouseDragged function, in which i can continually get the x and y coords?
Here is the code:
import java.awt.geom.*;
class griddedInput extends JComponent implements MouseListener
{
int SIZE = 10;
int scSize = 300;
int sSize = scSize/SIZE;
boolean [][] grid = new boolean[sSize][sSize];
public griddedInput(boolean grid[][])
{
grid=grid;
setPreferredSize(new Dimension(scSize,scSize));
addMouseListener(this);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int x, y;
for(y = 0; y < sSize; y ++) {
for(x = 0; x < sSize; x ++) {
if(grid[y][x])
g2.setColor(Color.BLACK);
else
g2.setColor(Color.WHITE);
g2.fillRect((x * SIZE), (y * SIZE), sSize, sSize);
}
}
}
#Override
public void mouseClicked(MouseEvent e) {
int squareX = (int)e.getX() / SIZE;
int squareY = (int)e.getY() / SIZE;
grid[squareY][squareX] = !grid[squareY][squareX];
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
You'll want to call repaint() on the drawing component any time you want to suggest to the JVM that it be painted -- most likely in your MouseListener method(s).
e.g.,
#Override
public void mouseClicked(MouseEvent e) {
int squareX = (int)e.getX() / SIZE;
int squareY = (int)e.getY() / SIZE;
grid[squareY][squareX] = !grid[squareY][squareX];
repaint();
}
To speed up repainting, you can also call the overload method that allows you to repaint a select rectangle of your GUI, but I'll bet that you don't need to do that for this GUI.
You'll also want to be a little less "creative" with your code indentation if you want others to better be able to understand it and help you.
Edit
Regarding:
2.How can I do something like a mouseDragged function, in which i can continually get the x and y coords?
Also add a MouseMotionListener. It can be the same class, and in fact usually I use an anonymous inner class for this, one that extends MouseAdapter, and one whose single instance I use for both MouseListener and MouseMotionListener. I have examples of using this in several posts in this very forum.
I would structure this a bit differently:
private BufferedImage bi = new BufferedImage(getWidth(), getHeight());
private Graphics2D big = bi.createGraphics();
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(bi, 0, 0, this);
}
#Override
public void mouseClicked(MouseEvent e) {
int squareX = (int)e.getX() / SIZE;
int squareY = (int)e.getY() / SIZE;
boolean b = !grid[squareY][squareX];
grid[squareY][squareX] = b;
if(b)
big.setColor(Color.BLACK);
else
big.setColor(Color.WHITE);
big.fillRect((x * SIZE), (y * SIZE), sSize, sSize);
repaint();
}
The mouseClicked performs a single fillRect and the paintComponent a single drawImage. Compare this with the original code that performs 900 fillRects on every repaint.
You will also need to detect changes to the size and recreate the BufferedImage at that time.

Listen to JFrame resize events as the user drags their mouse?

When a user clicks on the corner of a JFrame to resize and drags the mouse around, the JFrame redraws based on the current position of the mouse as the user drags. How can you listen to these events?
Below is the what I have currently tried:
public final class TestFrame extends JFrame {
public TestFrame() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
// These methods do not appear to be called at all when a JFrame
// is being resized.
#Override
public void setSize(int width, int height) {
System.out.println("setSize");
}
#Override
public void setBounds(Rectangle r) {
System.out.println("setBounds A");
}
#Override
public void setBounds(int x, int y, int width, int height) {
System.out.println("setBounds B");
}
}
How can I determine and constrain how the user resizes a window (based on the current aspect ratio of the window) as they are dragging around the mouse around?
You can add a component listener and implement the componentResized function like that:
JFrame component = new JFrame("My Frame");
component.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
//........
}
});
EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.
One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.
I know, this isn't the most elegant solution, but it works!
Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:
public final class TestFrame extends JFrame {
public TestFrame() {
this.getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
}
Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.
You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.
public class MouseDrag extends Component implements MouseListener,
MouseMotionListener {
/** The Image we are to paint */
Image curImage;
/** Kludge for showStatus */
static Label status;
/** true if we are in drag */
boolean inDrag = false;
/** starting location of a drag */
int startX = -1, startY = -1;
/** current location of a drag */
int curX = -1, curY = -1;
// "main" method
public static void main(String[] av) {
JFrame f = new JFrame("Mouse Dragger");
Container cp = f.getContentPane();
if (av.length < 1) {
System.err.println("Usage: MouseDrag imagefile");
System.exit(1);
}
Image im = Toolkit.getDefaultToolkit().getImage(av[0]);
// create a MouseDrag object
MouseDrag j = new MouseDrag(im);
cp.setLayout(new BorderLayout());
cp.add(BorderLayout.NORTH, new Label(
"Hello, and welcome to the world of Java"));
cp.add(BorderLayout.CENTER, j);
cp.add(BorderLayout.SOUTH, status = new Label());
status.setSize(f.getSize().width, status.getSize().height);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// "Constructor" - creates the object
public MouseDrag(Image i) {
super();
curImage = i;
setSize(300, 200);
addMouseListener(this);
addMouseMotionListener(this);
}
public void showStatus(String s) {
status.setText(s);
}
// Five methods from MouseListener:
/** Called when the mouse has been clicked on a component. */
public void mouseClicked(MouseEvent e) {
}
/** Called when the mouse enters a component. */
public void mouseEntered(MouseEvent e) {
}
/** Called when the mouse exits a component. */
public void mouseExited(MouseEvent e) {
}
// And two methods from MouseMotionListener:
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
// System.err.println("mouse drag to " + p);
showStatus("mouse Dragged to " + p);
curX = p.x;
curY = p.y;
if (inDrag) {
repaint();
}
}
public void paint(Graphics g) {
int w = curX - startX, h = curY - startY;
Dimension d = getSize();
g.drawImage(curImage, 0, 0, d.width, d.height, this);
if (startX < 0 || startY < 0)
return;
System.err.println("paint:drawRect #[" + startX + "," + startY
+ "] size " + w + "x" + h);
g.setColor(Color.red);
g.fillRect(startX, startY, w, h);
}
}

Categories