问题
I have a paint programme and i have all the buttons and sliders done however i am having a problem with the actual painting itself. When I drag the cursor across the screen instead of an unbroken line I am getting almost a dotted line which i dont want. Here's the code for the MouseListener
in the JPanel
and BufferedImage
:
public void mouseDragged(MouseEvent e) {
Graphics g=buffered.getGraphics();
g.setColor(mycol);
Graphics2D graph=(Graphics2D)g;
BasicStroke stroke=new BasicStroke(30);
graph.setStroke(stroke);
// g.fillRect(xcor, ycor, 20, 20);
/ /varx=e.getX();
ycor=e.getY();
xcor=e.getX();
int bad=xcor;
int good=ycor;
graph.drawLine(xcor, ycor, bad, good);
// buffered.setRGB(xcor, ycor, mycol.getRGB());
repaint();
// g.drawLine(xcor, ycor, x, x)
repaint();
}
回答1:
- Just to justify my comment, I am adding this answer, though a slight
change from the comment is here, which being the use of
mousePressed(...)
instead ofmouseClicked(...)
. One more addition being, since you wanted the
Graphics2D
object of theBufferedImage
so instead of usinggetGraphics()
always usecreateGraphics()
which returns theGraphics2D
object, hence you don't really have to worry about the Cast thingy in this.Please do have a look at the example below :
======================
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.net.URL;
import javax.swing.*;
import javax.imageio.ImageIO;
public class PaintingExample {
private BufferedImage bImage;
private ImageIcon image;
private JLabel imageLabel;
private int xClicked = 0;
private int yClicked = 0;
private int xDragged = 0;
private int yDragged = 0;
private MouseAdapter mouseListener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent me) {
xClicked = me.getX();
yClicked = me.getY();
}
@Override
public void mouseDragged(MouseEvent me) {
xDragged = me.getX();
yDragged = me.getY();
Graphics2D g2 = bImage.createGraphics();
g2.setColor(Color.WHITE);
BasicStroke stroke=new BasicStroke(30);
g2.setStroke(stroke);
g2.drawLine(xClicked, yClicked, xDragged, yDragged);
g2.dispose();
imageLabel.setIcon(new ImageIcon(bImage));
}
};
public PaintingExample() {
try {
bImage = ImageIO.read(new URL(
"http://i.imgur.com/fHiBMwI.jpg"));
image = new ImageIcon(bImage);
} catch(Exception e) {
e.printStackTrace();
}
}
private void displayGUI() {
JFrame frame = new JFrame("Painting on Image");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
imageLabel = new JLabel(image);
imageLabel.addMouseListener(mouseListener);
imageLabel.addMouseMotionListener(mouseListener);
contentPane.add(imageLabel);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new PaintingExample().displayGUI();
}
});
}
}
回答2:
Thirty pixels is a very wide line, and I can imagine that when drawn without antialiasing, it's going to look very jagged; that's probably what you're seeing. You might want to try something like
graph.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
On the other hand, maybe you're already getting antialiasing, and you want to turn it off; then
graph.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
One of these is guaranteed to change the appearance of your image; hopefully it will be more to your liking.
回答3:
If I'm understanding your problem correctly, the major issue you are going to have is the number of updates you will receive when the mouse is dragged.
Even if you drag slowly, you will not always be notified of EVERY pixel movement, instead the system waits for a "idle" state (or threshold) to notify you so it "appears" to be a smooth movement.
I was able to put this together by modifying your code slightly
private MouseAdapter mouseListener =
new MouseAdapter() {
private boolean paint = false;
@Override
public void mousePressed(MouseEvent me) {
xClicked = me.getX();
yClicked = me.getY();
xDragged = xClicked;
yDragged = yClicked;
paint = true;
}
@Override
public void mouseReleased(MouseEvent e) {
xClicked = -1;
xClicked = -1;
xDragged = -1;
yDragged = -1;
paint = false;
}
@Override
public void mouseMoved(MouseEvent me) {
}
@Override
public void mouseDragged(MouseEvent me) {
if (paint) {
xClicked = xDragged;
yClicked = yDragged;
xDragged = me.getX();
yDragged = me.getY();
xDragged = me.getX();
yDragged = me.getY();
Graphics2D g2 = bImage.createGraphics();
g2.setColor(Color.WHITE);
g2.drawLine(xClicked, yClicked, xDragged, yDragged);
g2.dispose();
imageLabel.setIcon(new ImageIcon(bImage));
me.getComponent().invalidate();
me.getComponent().repaint();
}
}
};
Basically, the idea is to draw a line from the last "known location" to the current location.
Hope this is in the ball park
来源:https://stackoverflow.com/questions/11886866/drawline-issues-and-buffered-image