.drawLine()问题和缓冲图像

我有一个绘画程序,我已完成所有按钮和滑块,但我对实际绘画本身有问题。 当我将光标拖过屏幕而不是一条连续线时,我几乎得到了一条我不想要的虚线。 这是JPanelBufferedImage MouseListener的代码:

  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(); } 

  • 为了certificate我的评论是正确的,我正在添加这个答案,尽管这里的注释略有改变,即使用mousePressed(...)而不是mouseClicked(...)
  • 还有一个补充,因为你想要BufferedImageGraphics2D对象而不是使用getGraphics()总是使用返回Graphics2D对象的createGraphics() ,因此你不必担心这里的Cast thingy。

    请看下面的例子:

======================

 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(); } }); } } 

三十个像素是一条非常宽的线,我可以想象,在没有抗锯齿的情况下绘制时,它看起来会非常锯齿状; 这可能就是你所看到的。 你可能想尝试类似的东西

 graph.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

另一方面,也许你已经得到了抗锯齿function,而你想要关闭它; 然后

 graph.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); 

其中一个保证可以改变图像的外观; 希望它更符合你的喜好。

如果我正确理解您的问题,那么您将遇到的主要问题是拖动鼠标时会收到的更新数量。

即使您慢慢拖动,也不会始终通知您每个像素的移动,而是系统等待“空闲”状态(或阈值)通知您,使其“显示”为平稳移动。

我能够通过稍微修改你的代码把它放在一起

你好 ;)

 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(); } } }; 

基本上,我们的想法是从最后的“已知位置”到当前位置绘制一条线。

希望这是在球场