我有一个绘画程序,我已完成所有按钮和滑块但是我对实际绘画本身有问题。当我将光标拖过屏幕而不是一条连续线时,我几乎得到了一条我不想要的虚线。以下是MouseListener
和JPanel
中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();
}
答案 0 :(得分:5)
mousePressed(...)
代替mouseClicked(...)
。还有一个补充,因为你需要Graphics2D
对象
BufferedImage
所以不要总是使用getGraphics()
createGraphics()
返回Graphics2D
对象,因此你
我真的不必担心Cast中的东西。
请看下面的示例:
======================
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();
}
});
}
}
答案 1 :(得分:2)
30个像素是一条非常宽的线,我可以想象,在没有抗锯齿的情况下绘制时,它会看起来非常锯齿状;这可能就是你所看到的。你可能想尝试像
这样的东西graph.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
另一方面,也许你已经已经获得了抗锯齿功能,而你想要将其关闭;然后
graph.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
其中一个可以保证改变图像的外观;希望它更符合你的喜好。
答案 2 :(得分:2)
如果我正确理解您的问题,那么您将遇到的主要问题是拖动鼠标时会收到的更新次数。
即使您慢慢拖动,也不会始终通知您每个像素的移动,而是系统等待“空闲”状态(或阈值)通知您,使其“显示”为平滑移动。
我能够通过稍微修改你的代码把它放在一起
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();
}
}
};
基本上,我们的想法是从最后一个“已知位置”到当前位置画一条线。
希望这是在球场