I need to draw a circle between 2 lines. When I click on the panel, a line is drawn. When I click a second time, another line is drawn and the color of the line has changed. Also, at the 2nd click, a circle is drawn between the 2 lines. Then, there is a little animation with the circle. Someone helped me yesterday with this code :
List<Integer> yClicks = new ArrayList<>(); {
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
yClicks.add(e.getY());
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
for(int y : yClicks) {
g2d.draw(new Line2D.Double(0, y, getWidth(), y));
}
g2d.dispose();
}
I added this:
for(int y : yClicks) {
line1= new Line2D.Double(0, y, getWidth(), y);
g2d.setColor(Color.blue);
g2d.draw(line1);
int l2= (yClicks.get(1));
int Diameter=l2-y;
g2d.setColor(Color.yellow);
g2d.draw(new Line2D.Double(0,l2,getWidth(),l2));
g2d.draw(new Ellipse2D.Double(getWidth()/2,(Diameter),10,10));
}
g2d.dispose();
}
But there is a problem withe the code and maybe circle are drawn. I never used this form of a for loop, so i don't know. how to add something on the loop. I also tried if(y==2) but it doesn't do anything.
Related
when i use doublebuffering, painted image is expanded with white background.
Is there something wrong?
enter code here
private Image image_buffer;
private Graphics graphics_buffer
public void paint(Graphics g) {
super.paint(g);
buffering(img1, x1, 40, g);
}
public void buffering(Image img, int x, int y, Graphics g){
image_buffer = createImage(100,100);
graphics_buffer = image_buffer.getGraphics();
buffer.drawImage(img, x, y, this);
g.drawImage(image_buffer, x, y, this);
}
Why not replace your code with just:-
public void paint(Graphics g) {
super.paint(g);
g.drawImage(img1, x1, 40, this);
}
The reason you have a white background is because you're creating a 100x100 "canvas", and drawing on that.
This is a current problem I am facing for a game. It is a game of Tic-Tac-Toe the user and a friend can play together. I'm not finished yet, but this is what I've got. Any time the window is minimized or covered up by another window the portion of the graphics drawn (X and O) get deleted. I don't really know what to do about this, it would be nice to have a way where the drawing does not get deleted. My paintComponent() method for my main class just sets up the design of the board.
Any help appreciated, thank you!
private class DrawXO implements MouseListener {
public void mousePressed(MouseEvent evt) {
int x = evt.getX();
int y = evt.getY();
Graphics gContext = getGraphics();
Graphics2D graphics = (Graphics2D) gContext;
graphics.setStroke(new BasicStroke(8));
if (playerOneTurn) {
Player1.drawCircle(gContext, x, y );
checkForWinner();
if(playerOneWins) {
System.out.println("Player one wins");
}
playerTwoTurn = false;
} else {
// Still need to implement drawing for this ~
checkForWinner();
}
}
public void mouseExited(MouseEvent evt) {}
public void mouseEntered(MouseEvent evt) {}
public void mouseClicked(MouseEvent evt) {}
public void mouseReleased(MouseEvent evt) {}
}
Don't use getGraphics();
You need to learn how custom painting is done in Swing. Run through Performing Custom Painting. You will notice that paint required the use of a paintComponent method (in your JPanel or JComponent class) which takes in a Graphics (created for you) context that you use to perform your custom painting. All painting should be done within that context.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
// do painting here
}
Note: Never call this method explicitly, it is automatically called
To update the graphics, you will make some update to some paint variables, then call repaint(). Maybe something like:
#Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.fillRect(x, y, width, height);
}
If you want to add/draw multiple object, say with the click of a mouse, then keep a List of objects and iterate through the list int the paintComponent method. When the mouse is clicked, add another object to the list and repaint. Something like
List<Rectangle2D> rectangles;
...
#Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
rectangles.add(new Rectangle2d.Double(x, y, width, height);
repaint();
}
...
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for (Rectangle2D rect: rectangles) {
g2.fill(rect);
}
}
i'm trying to write a jigsaw puzzle application where an image is cut in pieces, scrambled, and the user have to rearrange them with drag&drop to reassemble the original image. (something like this: http://www.jigzone.com/puzzles/74055D549FF0?z=5).
i have to write this in java with Graphics2d.
so, at first i'm trying to make some kind of component which can show a part of the image (a rectangle for now), and can be dragged with mouse.
the code below works well when there is only one one such component. the problem is, when i add the second component, the first one is no longer visible.
i'm really stuck here. i have a feeling i'm missing something really basic. or maybe i'm on a wrong way. any help will be greatly appreciated.
edit: i changed a bit the code according to suggestions, however, still not working as expected.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
public class GraphicDragAndDrop extends JPanel {
Rectangle rect;
Image img;
public GraphicDragAndDrop(String imgFile, int x0, int y0){
rect = new Rectangle(x0, y0, 150, 75);
img = new ImageIcon(imgFile).getImage();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setClip(rect);
int x = rect.x;
int y = rect.y;
g2d.drawImage(img, x, y, this);
}
public void setRect(int x, int y) {
rect.setLocation(x, y);
repaint();
}
public static void main(String[] args) {
// first piece
GraphicDragAndDrop piece1 = new GraphicDragAndDrop("a.png", 0, 0);
piece1.setRect(0, 0);
new GraphicDragController(piece1);
// second piece --> only this will be visible
GraphicDragAndDrop piece2 = new GraphicDragAndDrop("a.png", 200, 200);
//GraphicDragAndDrop piece2 = new GraphicDragAndDrop("b.png", 200, 200); // does'n work either
piece2.setRect(150, 150);
new GraphicDragController(piece2);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(piece1);
f.add(piece2);
f.setSize(500,500);
f.setLocation(300,100);
f.setVisible(true);
}
}
class GraphicDragController extends MouseInputAdapter {
GraphicDragAndDrop component;
Point offset = new Point();
boolean dragging = false;
public GraphicDragController(GraphicDragAndDrop gdad) {
component = gdad;
component.addMouseListener(this);
component.addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Rectangle r = component.rect;
if(r.contains(p)) {
offset.x = p.x - r.x;
offset.y = p.y - r.y;
dragging = true;
}
}
public void mouseReleased(MouseEvent e) {
dragging = false;
}
public void mouseDragged(MouseEvent e) {
if(dragging) {
int x = e.getX() - offset.x;
int y = e.getY() - offset.y;
component.setRect(x, y);
}
}
}
Your code above is written to draw only one image:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setClip(rect);
int x = rect.x;
int y = rect.y;
// here
g2d.drawImage(new ImageIcon("a.png").getImage(), x, y, this);
}
If you need to draw more than one image, then consider creating a collection of images and iterating through the collection in paintComponent using a for loop:
also, never read in the image from within paintComponent since this method should be lean, mean and fast, and should concern itself with painting only. Also, there's no need to read the image in each time your program has to draw it as that's very inefficient and will slow the program unnecessarily. Instead read the image in once in the constructor or a similar init method.
For example,
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (Image img: myImageCollection) {
g2d.drawImage(img, 0, 0, this);
}
}
Edit
You state:
also, my plan was to have more objects of GraphicDragAndDrop class, each of them showing a different piece of the original image. is my approach wrong?
You could use components, but I have a feeling that it would be easy to drag images. I think it would be easier to rotate them for instance if you want your program to have this functionality. If not, though then sure use a component, but if you go this route, I would recommend using a JLabel and simply setting its ImageIcon rather than dragging JPanels.
I am trying to allow the user to select what shape they want to draw on my GUI. I have a selection of buttons: circle, square and rectangle. My actionListener works as it prints a string to my console, but it won't show the shape on my GUI. How can I use the actionCommand to draw that shape on my panel.
public void paintComponent(Graphics g) {
g2D = (Graphics2D) g;
//Rectangle2D rect = new Rectangle2D.Double(x, y, x2-x, y2-y);
//g2D.draw(rect);
repaint();
}
public void actionPerformed(ActionEvent arg0) {
if(arg0.getActionCommand().equals("Rect")){
System.out.println("hello");
Rectangle2D rect = new Rectangle2D.Double(x, y, x2-x, y2-y);
g2D.draw(rect); //can only be accessed within paintComponent method
repaint();
}
If you firstly paint your rectangle and then ask for a repaint the rectangle will disappear.
You should store your new shape in a temp variable and render it inside paintComponent.
private Rectangle2D temp;
// inside the actionPerformed
temp = new Rectangle2D.Double(x, y, x2-x, y2-y);
repaint();
// inside the paintComponent
if(temp != null) {
g2D.draw(temp);
}
Make the rect to be field nto local variable. In the actionPerformed create proper rect and call repaint(). Then paintComponent() will be called. It should be like this
public void paintComponent(Graphics g) {
g2D = (Graphics2D) g;
g2D.draw(rect);
}
I have a problem with drawing horizontal and vertical lines from the cursor position while the cursor is moving. The cursor seem to disappear.
I've attached a MouseInputAdapter to my swing component, which has a mouseMoved method which call repaint();
Calling repaint will cause a paintComponent(Graphics g) to be called. In paintComponent i paint the horizontal and vertical line:
Dimension dim = getSize();
g2.setColor(Color.white);
g2.fillRect(0, 0, dim.width, dim.height);
g2.setColor(Color.black);
Point pos = this.getMousePosition();
g2.draw(new Line2D.Double(0, pos.y, dim.getWidth(), pos.y));
g2.draw(new Line2D.Double(pos.x, 0, pos.x, dim.getHeight()));
Here is a screenshot:
The cursor should be in the white area that exists between the big horizontal line and the vertical one and should be at the left of the big number 1.2434307...
When i move the cursor with my mouse i can see the cursor (crosshair) flickering which makes me believe my paint method is painting over the cursor.
Anyone know where the problem may lie?
As requested i've added a little test code.
public class TestApp extends JFrame {
public TestApp() {
super("TestApp");
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(new CustomComponent(), BorderLayout.CENTER);
this.setSize(300, 300);
this.setVisible(true);
}
class CustomComponent extends JComponent {
public CustomComponent() {
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
MouseInputAdapter mia = new MouseInputAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
repaint();
}
};
addMouseMotionListener(mia);
addMouseListener(mia);
}
#Override
public void paintComponent(Graphics g) {
Dimension dim = getSize();
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.white);
g2.fillRect(0, 0, dim.width, dim.height);
g2.setColor(Color.black);
Point pos = this.getMousePosition();
if (pos != null) {
g2.draw(new Line2D.Double(0, pos.y, dim.getWidth(), pos.y));
g2.draw(new Line2D.Double(pos.x, 0, pos.x, dim.getHeight()));
g2.drawString("where is my cursor?", pos.x, pos.y);
}
}
}
public static void main(String[] args) {
new TestApp();
}
}