What I'm trying to do is to draw circles and lines.
When the mouse is first pressed, I draw a small circle. Then, I need
to draw a line connecting the original point to the current
position of the mouse. When the mouse is released, the line
remains, but when I click again, everything disappears and I draw a
circle and a line all over again.
This is the code I have so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Canvas4 extends JComponent implements MouseListener, MouseMotionListener {
//constructor
public Canvas4() {
super();
addMouseListener(this);
addMouseMotionListener(this);
}
//some variables I may or may not use
int pressedX;
int pressedY;
int currentX;
int currentY;
int startDragX;
int startDragY;
int endDragX;
int endDragY;
int mouseReleasedX;
int mouseReleasedY;
//mouse events
public void mouseClicked(MouseEvent event) { }
public void mouseEntered(MouseEvent event) { }
public void mouseExited(MouseEvent event) { }
public void mousePressed(MouseEvent event) {
pressedX = event.getX();
pressedY = event.getY();
drawCircle();
startDragX = pressedX;
startDragY = pressedY;
}
public void mouseReleased(MouseEvent event) {
mouseReleasedX = event.getX();
mouseReleasedY = event.getY();
//repaint() here maybe???
}
//mouse motion events
public void mouseDragged(MouseEvent event) {
System.out.println("You dragged the mouse.");
endDragX = event.getX();
endDragY = event.getY();
drawLine();
}
public void mouseMoved(MouseEvent event) { }
//draw circle when mouse pressed
//this method works fine
public void drawCircle() {
Graphics g1 = this.getGraphics();
g1.setColor(Color.CYAN);
g1.fillOval(pressedX, pressedY, 10, 10);
}
//draw line when mouse dragged
//this is where I need help
public void drawLine() {
Graphics g2 = this.getGraphics();
g2.setColor(Color.RED);
g2.drawLine(pressedX, pressedY, mouseReleasedX, mouseReleasedY);
}
}
Then of course, there's a main method that creates the class object and adds it to a frame and whatnot.
My two specific questions are:
how do I draw a line as it's dragged? The code I have currently only draws a line to the last point of mouse release.
When do I repaint? If I repaint in the drawCircle() method, the circle blinks in and out instead of disappearing on the next click.
If you want to draw circles and lines then you need to keep an ArrayList of Shapes to draw. You would add an Ellipse2D.Double for the circle and a Line2D.Double for the line.
In the mousePressed event you add the Ellipse2D.Double object to the ArrayList, then you set up a temporary Line2D.Double object to contain your line information.
In the mouseDragged event you update Line2D.Double object with the new end point and then invoke repaint().
In the mouseReleased event you add the Line2D.Double object to the ArrayList and clear the variable referencing the Line2D.Double object.
Then in the paintComponent() method you add logic to:
iterate through the ArrayList to paint each Shape.
draw the Line2D.Double object when not null
Check out the Draw On Component example found in Custom Painting Approaches. This will show you the basic concept of this approach.
In the example the ArrayList only contains information on Rectangles so you will need to make it more generic to hold a Shape object. Both Ellispse2D.Double and Line2D.Double implement the Shape interface.
For drawing lines i have this.When you click mouse left you retain a point next click will retain another point making a line between them , and with mouse right you make the line between first point and last point (you can delete this "if (isClosed)" if you dont want)
Another thing : it's not a good precision because pointlocation return a double and drawline need an integer and the cast loses precision.
public class PolygonOnClick extends JPanel implements MouseListener, MouseMotionListener {
ArrayList<Point> points = new ArrayList<>();
static boolean isClosed = false;
PolygonOnClick() {
JFrame frame = new JFrame("Polygon ON CLICK");
frame.addMouseListener(this);
frame.setLocation(80, 50);
frame.setSize(1000, 700);
frame.add(this);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics.drawString("Click stanga pentru a incepe a desena , click dreapta pentru a inchide poligonul ", 15, 15);
for (int i = 1; i < points.size(); i++) {
graphics.drawLine((int) points.get(i - 1).getX(), (int) points.get(i - 1).getY(), (int) points.get(i).getX(), (int) points.get(i).getY());
}
if (isClosed) {
graphics.drawLine((int) points.get(points.size() - 1).getX(), (int) points.get(points.size() - 1).getY(), (int) points.get(0).getX(), (int) points.get(0).getY());
}
}
#Override
public void mousePressed(MouseEvent e) {
if (!isClosed) {
if (e.getButton() == MouseEvent.BUTTON1) {
points.add(e.getPoint().getLocation());
}
}
if (e.getButton() == MouseEvent.BUTTON3) {
isClosed = true;
}
repaint();
}
Related
This program is about creating components and moving them randomly in JApplet and removing the components if required. Every mouse click creates a new component. After creating component we can click on it and drag it where ever we want. Double clicking on the component removes it. I was successful in creating, moving and removing components.
For example i created three components on the JApplet by clicking three times randomly at different places on the JApplet.Please click here to view created components I moved them randomly around the screen. Please click here to view JApplet after randomly moving them around screen My goal is to write the final coordinates(x,y) of their position on the screen for all components created in to a text file by clicking a write button. I have no idea about mouseReleased method. Please help me with this. Thank you. Your help is very much appreciated.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
import javax.swing.*;
This is my main class
public class MouseTest extends JApplet
{
public void init()
{
EventQueue.invokeLater(new Runnable() {
public void run()
{
MousePanel panel = new MousePanel();
add(panel);
}
});
}
public static void main(String[] args)
{
EventQueue.invokeLater(new mainThread());
}
}
class mainThread implements Runnable
{
public void run()
{
JPanel panel = new MousePanel();
JFrame frame = new JFrame("MouseTest");
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,200);
frame.setVisible(true);
}
}
class MousePanel extends JPanel
{
public MousePanel()
{
squares = new ArrayList<Rectangle2D>();
current = null;
addMouseListener(new MouseHandler());
addMouseMotionListener(new MouseMotionHandler());
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw all squares
for (Rectangle2D r : squares)
g2.draw(r);
}
/**
* Finds the first square containing a point.
* #param p a point
* #return the first square that contains p
*/
public Rectangle2D find(Point2D p)
{
for (Rectangle2D r : squares)
{
if (r.contains(p)) return r;
}
return null;
}
/**
* Adds a square to the collection.
* #param p the center of the square
*/
public void add(Point2D p)
{
double x = p.getX();
double y = p.getY();
current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH,
SIDELENGTH);
squares.add(current);
repaint();
}
/**
* Removes a square from the collection.
* #param s the square to remove
*/
public void remove(Rectangle2D s)
{
if (s == null) return;
if (s == current) current = null;
squares.remove(s);
repaint();
}
private static final int SIDELENGTH = 10;
private ArrayList<Rectangle2D> squares;
private Rectangle2D current;
// the square containing the mouse cursor
these are methods for defining and dragging and removing the object
private class MouseHandler extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
// add a new square if the cursor isn't inside a square
current = find(event.getPoint());
if (current == null) add(event.getPoint());
}
public void mouseClicked(MouseEvent event)
{
// remove the current square if double clicked
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2) remove(current);
}
}
private class MouseMotionHandler implements MouseMotionListener
{
public void mouseMoved(MouseEvent event)
{
// set the mouse cursor to cross hairs if it is inside
// a rectangle
if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
public void mouseDragged(MouseEvent event)
{
if (current != null)
{
int x = event.getX();
int y = event.getY();
// drag the current rectangle to center it at (x, y)
current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
repaint();
}
}
}
}
Why do you keep changing the requirement???? See original question: How to find final coordinates(x & y) of the objects position in JApplet and write them to a text file
First you wanted to write out the location of the moved component after the drag was finished.
Then you wanted to write out the location of "all" components after the drag was finished.
Now you want to write out the location of all the components after a "button" is clicked.
I have no idea about mouseReleased method.
What does this have to do with anything? That was the suggestion for your requirement in your last question. Since your requirement has changed it is no longer needed.
My goal is to write the final coordinates(x,y) of their position on the screen for all components created in to a text file by clicking a write button.
Then you need to add an ActionListener to the button. You have already been given a link to the Swing tutorial on How to Write an ActionListener so I guess the question is what code should be included in the ActionListener?
In you last question you stated:
I know how to get the location of a component
I know how to write data to a file
So the only remaining problem is how to get all the components on the panel? To do this you can use the Container.getComponents() method on your panel containing all the dragged components. The basic code for your ActionListener would be something like:
for (Component component: panel.getComponents())
{
Point location = component.getLocation();
// write the location to the file
}
I'll let you add the code for opening/closing the file.
Hey Everyone I am trying to create a somewhat dynamic program in which you can add shapes or images to a JPanel and then select and move the shapes after you have added them. The problem is that when I click on the specific JComponent nothing happens. In fact clicking on any of the components I have created to test the project returns false for all JComponents. However it seems that if I click inside the bounds of my JComponent in the top left corner I will get returned true for all JComponents, ie click in the area bounded by (0,0,50,68).
The idea is that if I click one of the JComponents it will set that specific JComponent to be movable however I cannot get past the part of actually selecting a specific JComponent.
Here is a basic SSCE that I built to recreate the problem:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class SSCE1 extends JPanel {
private ArrayList<Shape> shapeList = new ArrayList<Shape>();
SSCE1() {
setLayout(null);
/* Debug Stuff */
System.out.println("Debug:");
/* Add The First Shape To The List */
shapeList.add(0, new Shape(100, 100));
add(shapeList.get(0));
shapeList.add(1, new Shape(610, 0));
add(shapeList.get(1));
shapeList.add(2, new Shape(500, 900));
add(shapeList.get(2));
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
for (Shape shape : shapeList) {
if (shape.contains(e.getPoint())) {
System.out.println("Hello");
} else {
System.out.println("Goodbye");
}
}
}
});
}
}
class Shape extends JComponent {
int xLocation, yLocation, xBounds1, yBounds1;
Shape(int xLocation, int yLocation) {
this.xLocation = xLocation;
this.yLocation = yLocation;
this.xBounds1 = 50;
this.yBounds1 = 68;
setBounds(xLocation, yLocation, xBounds1, yBounds1);
setLocation(xLocation, yLocation);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.blue);
g.fillRect(0, 0, 100, 100);
}
}
class Run {
public static void main(String[] args) {
JFrame main = new JFrame();
SSCE1 p1 = new SSCE1();
main.setSize(new Dimension(1000, 1000));
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setLocation(new Point(0, 0));
main.setVisible(true);
main.add(p1);
}
}
Basically, the problem is, Shape is expecting any mouse coordinates you pass it to be defined within the context of the Shape. That is, the top, left corner of Shape is always 0x0
The mouse point you are processing is within the context of the parent container, therefore, unless Shape is positioned at 0x0 within the parent container, Shape will never contain the mouse point.
You need to translate the mouse point to the context of the Shape before checking it
For example...
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
for (Shape shape : shapeList) {
Point shapePoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), shape);
if (shape.contains(shapePoint) {
System.out.println("Hello");
} else {
System.out.println("Goodbye");
}
}
}
});
Use next mouseListener it works:
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
for (Shape shape : shapeList) {
Point convertPoint = SwingUtilities.convertPoint(SSCE1.this, e.getPoint(), shape);
if (shape.contains(convertPoint)) {
System.out.println("Hello");
} else {
System.out.println("Goodbye");
}
}
}
});
The reason is next according docs in contains method the point's x and y coordinates are defined to be relative to the coordinate system of this component. because of that works for (0,0,50,68). All what you need convert point from JPanel to Shape with help of SwingUtilities.convertPoint(...)
Hey guys I need help I am trying to make a program where I can draw in a window with the mouse. So far I have it to where when I click a dot appears but I need to add a drag method so that when I drag the mouse across the page it draws stuff. Can someone look at my code and help me out where you can?
Here is my code:
import javax.swing.*;
import java.awt.event.*;
public class mouse {
private static int x,y;
private static draw object = new draw ();
public static void main(String[] args){
JFrame frame = new JFrame ("Mouse");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
frame.add(object);
object.addMouseListener(new AL());
}
static class AL extends MouseAdapter{
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
object.drawing(x, y);
}
public void mouseDragged( MouseEvent e) {
x= e.getX();
y= e.getY();
object.drawing(x, y);
}
}
}
and
import javax.swing.*;
import java.awt.*;
public class draw extends JPanel {
private static int x,y;
public void drawing (int xx, int yy){
x=xx;
y=yy;
repaint();
}
public void paintComponent (Graphics g){
g.setColor(Color.black);
g.fillOval(x, y, 10, 10);
}
}
One idea that I have is to add your mouse coordinates each to a separate list whenever the mouse is clicked and draw based on the size of the lists, however since you are using mouse dragged you could just use Path2D.lineTo(x, y) and use e.getX() and e.getY() for the x and y coords. After this use Path2D.moveTo(x, y) to make sure line path is appended for each pixel the mouse moves (this makes sure that each movement doesn't look like a straight line, but rather like a line moving whatever direction you're "drawing" in). Also, a few tips:
The void mouseDragged usually works better when used in mouseMotionAdapter because from my experience it usually doesn't register the event in just mouseAdapter.
Since this is a drawing program, personally I'd set a variable for the size of your circle to be used in the future if you actually are planning to expand this into something bigger (example: g.fillOval(x, y, brushSize, brushSize)).
I've got a problem in Java using a "canvas" class I created, which is an extended JPanel, to draw an animated ring chart. This chart is using a MouseListener to fetch click events.
The problem is that the mouse position does not seem to be accurate, meaning it does not seem to be relative to the "canvas" but instead relative to the window (in the left, upper corner I got about 30px for y coord).
This is my code:
I created a class, that extends JPanel and does have a BufferedImage as member.
public class Canvas extends JPanel {
public BufferedImage buf;
private RingChart _parent;
public Canvas(int width, int height, RingChart parent){
buf = new BufferedImage(width, height, 1);
...
In the paint component method I just draw the buffered image, so I am able to paint on the canvas from 'outside' by painting on the buffered image, which is public.
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(buf, null, 0, 0);
}
Now there's a class RingChart which contains a "canvas":
public class RingChart extends JFrame{
public Canvas c;
...
And I create a Graphics2D from the bufferedImage in the canvas class. This g2d is used for painting:
public RingChart(){
c = new Canvas(1500,980,this);
add(c);
setSize(1500, 1000);
setTitle("Hans");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g2d = (Graphics2D)c.buf.createGraphics();
...
What I now was trying to achieve, was a mouse listener that listened to mouse events happening on the canvas. So when the user clicks on the canvas I could retrieve the position he clicked on, upon the canvas, through the event variable.
So I created a mouse listener:
class MouseHandler implements MouseListener {
#Override
public void mouseClicked(MouseEvent e){
RingChart r = ((Canvas)e.getSource()).getParent();
r.mouseClick(e);
}
...
...and added this mouse listener to the canvas of the RingChart class (myChart is an instance of RingChart and c is the canvas it contains):
...
MouseHandler mouse = new MouseHandler();
myChart.c.addMouseListener(mouse);
...
But as I mentioned above, the mouse position, that's returned when the click event is called, does not seem to be accurate. I think the mistake must be somehow in the way I created that mouseListener or maybe assigned it to the wrong element or something like that. But I've tried quite a couple of things and it didn't change. Can maybe someone tell me, what I've done wrong?
UPDATE:
The code of the function "mouseClick" that is a member of RingChart and is called in the mouse listener:
public void mouseClick(MouseEvent evt){
//evt = SwingUtilities.convertMouseEvent(this, evt, c);
if(evt.getButton() == MouseEvent.BUTTON1 && animation == null){
for(Element e : elements){
if(e.getShape() != null && e.getShape().contains(evt.getPoint())){
//do some stuff
}
}
}
}
Again, the hierarchy of my classes:
RingChart --contains a--> Canvas --got a--> MouseListener.
The shapes in this function are shapes that have been painted on the canvas c. Now I want to check, if the user has clicked on one of them. So as I thought, the shapes should be in canvas-coordinates and the event position should be in canvas-coordinates and everything should fit together. But it doesn't.
Now user MadProgrammer told me, to use the ConvertMouseEvent function. But I currently don't see which exact way I should use this sensibly.
UPDATE:
I found a solution: All I had to do is adding the canvas not directly to the JFrame but to the ContentPane of the JFrame instead:
So instead:
public RingChart(){
c = new Canvas(1500,980,this);
add(c);
...
I do:
public RingChart(){
c = new Canvas(1500,980,this);
getContentPane().add(c);
...
Then I give the MouseListener to the ContentPane.
getContentPane().addMouseListener(new MouseHandler());
getContentPane().addMouseMotionListener(new MouseMoveHandler());
I don't know, if this is an elegant solution, but it works.
The mouse event is automatically converted to be relative to the component that it occurred in that is, point 0x0 is always the top left corner of the component.
By using RingChart r = ((Canvas)e.getSource()).getParent(), you've effectively changed the reference, which now means the location is no longer valid.
You need to convert the location so that its coordinates are in the context of the parent component. Take a look at SwingUtilities.convertMouseEvent(Component, MouseEvent, Component)
UPDATE with PICTURES
Lets take this example...
The blue box has a relative position of 50px x 50px to the red box. If you click in the blue box, lets say at 25x25, the mouse coordinates will be relative to the blue box (0x0 will be the top left of the blue box).
If you then pass this event to the red box and try and use the coordinates from it, you will find that the coordinates will now be half way between the top left of the red box and the blue box, because the coordinates are context sensitive.
In order to get it to work, you need to translate the mouse events location from the blue box to the red box, which would make it 75x75
Now, I don't know what you're doing when you pass the mouse event to the RingChart so I'm only guessing that this is the issue you're facing.
UPDATED with Click Code
Okay, lets say, you have a Canvas at 100x100. You click on that Canvas at 50x50. You then pass that value back up the chain.
public void mouseClick(MouseEvent evt){
//evt = SwingUtilities.convertMouseEvent(this, evt, c);
if(evt.getButton() == MouseEvent.BUTTON1 && animation == null){
for(Element e : elements){
// Here, we are asking the shape if it contains the point 50x50...
// Not 150x150 which would be the relative position of the click
// in the context to the RingChart, which is where all your objects
// are laid out.
// So even the original Canvas you clicked on will return
// false because it's position + size (100x100x width x height)
// does not contain the specified point of 50x50...
if(e.getShape() != null && e.getShape().contains(evt.getPoint())){
//do some stuff
}
}
}
}
UPDATED
I think you have your references around the wrong way...
public static MouseEvent convertMouseEvent(Component source,
MouseEvent sourceEvent,
Component destination)
I think it should read something like
evt = SwingUtilities.convertMouseEvent(evt.getComponent(), evt, this);
UPDATE with Code Example
Okay, so, I put this little example together...
public class TestMouseClickPoint extends JFrame {
private ContentPane content;
public TestMouseClickPoint() throws HeadlessException {
setSize(600, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
content = new ContentPane();
add(content);
}
protected void updateClickPoint(MouseEvent evt) {
content.updateClickPoint(evt);
}
protected class ContentPane extends JPanel {
private Point relativePoint;
private Point absolutePoint;
public ContentPane() {
setPreferredSize(new Dimension(600, 600));
setLayout(null); // For testing purpose only...
MousePane mousePane = new MousePane();
mousePane.setBounds(100, 100, 400, 400);
add(mousePane);
}
protected void updateClickPoint(MouseEvent evt) {
absolutePoint = new Point(evt.getPoint());
evt = SwingUtilities.convertMouseEvent(evt.getComponent(), evt, this);
relativePoint = new Point(evt.getPoint());
System.out.println(absolutePoint);
System.out.println(relativePoint);
repaint();
}
protected void paintCross(Graphics2D g2d, Point p) {
g2d.drawLine(p.x - 5, p.y - 5, p.x + 5, p.y + 5);
g2d.drawLine(p.x - 5, p.y + 5, p.x + 5, p.y - 5);
}
/*
* This is not recommended, but I want to paint ontop of everything...
*/
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
if (relativePoint != null) {
g2d.setColor(Color.BLACK);
paintCross(g2d, relativePoint);
}
if (absolutePoint != null) {
g2d.setColor(Color.RED);
paintCross(g2d, absolutePoint);
}
}
}
protected class MousePane extends JPanel {
private Point clickPoint;
public MousePane() {
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
clickPoint = e.getPoint();
TestMouseClickPoint.this.updateClickPoint(e);
repaint();
}
});
setBorder(new LineBorder(Color.RED));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
if (clickPoint != null) {
g2d.drawLine(clickPoint.x, clickPoint.y - 5, clickPoint.x, clickPoint.y + 5);
g2d.drawLine(clickPoint.x - 5, clickPoint.y, clickPoint.x + 5, clickPoint.y);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
new TestMouseClickPoint().setVisible(true);
}
}
Basically, it will paint three points. The point that the mouse was clicked (relative to the source of the event), the unconverted point in the parent container and the converted point with the parent container.
The next thing you need to do is determine the mouse location is actually been converted, failing that. I'd probably need to see a working example of your code to determine what it is you're actually doing.
For custom rendering, I've created a class that extends JPanel and overrides the paintComponent method. In the custom paintComponent I rendering multiple shape objects held in a array. What I would like to add is the ability to drag and select 1 or more of the shapes. While dragging I would like to show a translucent rectangle defining the selection region akin to what is seen in Windows Explorer. Can any provide a starting point for accomplishing this?
Thanks.
I saw an interesting way of doing this in JFreeChart's source code. You can draw a marquee over a section of the chart, and when you release the mouse the chart zooms in on the selected are. Re-rending the chart is expensive and unfortunately JFreeChart doesn't support partial paints of a chart. So to draw the marquee they do some sort of bitwise operation to the colors of the component, in a reversible fashion. Every time the mouse moves while selecting a marquee, you reverse the previous bitwise operation on the old coordinates, then redo it on the new coordinates.
Take a look at ChartPanel.java in JFreeChart
private void drawZoomRectangle(Graphics2D g2) {
// Set XOR mode to draw the zoom rectangle
g2.setXORMode(Color.gray);
if (this.zoomRectangle != null) {
if (this.fillZoomRectangle) {
g2.fill(this.zoomRectangle);
}
else {
g2.draw(this.zoomRectangle);
}
}
// Reset to the default 'overwrite' mode
g2.setPaintMode();
}
You could use JXLayer. Span it across the whole form and do the painting in a custom LayerUI.
All,
Thanks for the suggestions. Ended up resolving this by adapting some the code used in this rather clever demo. http://forums.sun.com/thread.jspa?threadID=5299064&start=19
public class ExamplePanel extends JPanel
{
Rectangle2D.Double selectionRect;
Point mouseDown, mouseHere;
...
protected void paintComponent(Graphics g)
{
AlphaComposite ta = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
g2d.setComposite(ta);
g2d.setColor(Color.BLUE);
g2d.fill(selectionRect);
g2d.setComposite(AlphaComposite.SrcOver);
g2d.setColor(Color.BLACK);
g2d.draw(selectionRect);
}
}
public class ExammpleMouseListener extends MouseAdapter
{
#Override
public void mousePressed(MouseEvent e)
{
super.mousePressed(e);
// store the mouse down location
pnl.mouseDown = e.getPoint();
}
/**
* #see java.awt.event.MouseAdapter#mouseDragged(java.awt.event.MouseEvent)
*/
#Override
public void mouseDragged(MouseEvent e)
{
super.mouseDragged(e);
// check for left mouse button
if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) == 0)
{
return;
}
// store the current location
pnl.mouseHere = e.getPoint();
// calculate the size of the selection rectangle
double downX = pnl.mouseDown.getX();
double downY = pnl.mouseDown.getY();
double hereX = pnl.mouseHere.getX();
double hereY = pnl.mouseHere.getY();
double l = Math.min(downX, hereX);
double t = Math.min(downY, hereY);
double w = Math.abs(downX - hereX);
double h = Math.abs(downY - hereY);
pnl.selectionRect = new Rectangle2D.Double(l, t, w, h);
// queue a repaint of the panel
pnl.repaint();
}
#Override
public void mouseReleased(MouseEvent e)
{
super.mouseReleased(e);
// clear the selection rectangle
pnl.selectionRect = null;
// queue a repaint of the panel
pnl.repaint();
}
}
}
Sure, here's an simple example with methods for creating and moving the shape.
class MyShape implements Shape {
private Shape shape;
public void createShape(Point p1, Point p2, ShapeType t) {
switch(t) {
case RECTANGLE: {
shape = new Rectangle2D.Double(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
break;
}
... (other shapes)
}
}
public void moveShape(Point lastPoint, Point newPoint, ShapeType t) {
int xOffset = newPoint.x - lastPoint.x;
int yOffset = newPoint.y - lastPoint.y;
switch(t) {
case RECTANGLE: {
double x1 = shape.getBounds().getX() + xOffset;
double y1 = shape.getBounds().getY() + yOffset;
double w = shape.getBounds().getWidth();
double h = shape.getBounds().getHeight();
shape = new Rectangle2D.Double(x1, y1, w, h);
break;
}
... (other shapes)
}
}
}
For some components ( I don't know if this apply to your components while being dragged ) you can set the background and use a "transparent color"
The Color class does implements Transparency.
To use it you may specify the alpha value in the Color constructor.
For instance this is a semi transparent black background:
// 0: totally transparent
// 255: totally opaque,
// 192 semy transparent.
this.setBackground(new Color( 0, 0, 0, 192 ));
See the [constructor][1]
Again, I'm not sure if this applies to you. Give it a try
[1]: http://java.sun.com/javase/6/docs/api/java/awt/Color.html#Color(int, int, int, int)