2016-03-25 5 views
3

Этот код предназначен для рисования на JPanel. В paintComponent(Graphics) я пытаюсь рисовать кривые через повторяющиеся Graphics2D#fillOval(x, y, with, height).Как нарисовать непрерывную кривую повторяющихся овалов на быстром перемещении курсора мыши?

Приложение работает нормально, и когда я медленно курсор мыши; он рисует непрерывную кривую по мере необходимости. Но когда я ускоряю перетаскивание курсора мыши, результатом являются выделенные точки, а не непрерывная кривая.

Итак, как заставить его нарисовать непрерывную кривую, даже если я ускоряю перетаскивание?

import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 
import javax.swing.*; 

public class Painter extends JPanel { 

    int x, y; 
    ArrayList<Point> points; 

    public Painter() { 

     setBackground(Color.white); 
     points = new ArrayList<>(); 

     MouseHandler listener = new MouseHandler(); 
     this.addMouseMotionListener(listener); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(600, 600); 
    } 

    private class MouseHandler extends MouseAdapter implements MouseMotionListener { 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      Point point = new Point(e.getX(), e.getY()); 
      points.add(point); 
      repaint(); 
     } 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     for (Point point : points) { 
      g2d.fillOval(point.x, point.y, 15, 15); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame f = new JFrame(); 
       f.setContentPane(new Painter()); 
       f.pack(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 
+2

Нарисуйте овал с точки на линии к следующей точке – MadProgrammer

+0

Пожалуйста, смотрите редактирование ответить. –

ответ

3

Как уже говорилось в комментарии к предыдущему аналогичному вопросу:

  • Не привлекайте дискретные овалы в методе paintComponent.
  • Вместо этого подключите точки в списке в paintComponent, нарисуя линии между соседними точками.
  • Если вам нужно сделать линию толще, измените свойство Stroke объекта Graphics2D, используя ту, которая имеет более широкую толщину.
  • Будьте осторожны с штрихами, так как часто вы не хотите, чтобы изменение свойства распространялось по цепочке красок. Это означает, что иногда вы захотите скопировать объект Graphics и установить Stroke на новый объект Graphics и нарисовать его, а затем избавиться от него.
  • Самый простой способ создания обводки - использовать класс BasicStroke, например, new BasicStroke(6f), даст вам хорошую толстую кривую.

Например:

import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 

import javax.swing.*; 

public class Painter2 extends JPanel { 

    private static final float STROKE_WIDTH = 15f; 
    private static final Stroke STROKE = new BasicStroke(STROKE_WIDTH, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 
    int x, y; 
    ArrayList<Point> points; 

    public Painter2() { 

     setBackground(Color.white); 
     points = new ArrayList<>(); 

     MouseHandler listener = new MouseHandler(); 
     this.addMouseMotionListener(listener); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(600, 600); 
    } 

    private class MouseHandler extends MouseAdapter implements MouseMotionListener { 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      Point point = new Point(e.getX(), e.getY()); 
      points.add(point); 
      repaint(); 
     } 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     g2d.setStroke(STROKE); 
     for (int i = 1; i < points.size(); i++) { 
      int x1 = points.get(i - 1).x; 
      int y1 = points.get(i - 1).y; 
      int x2 = points.get(i).x; 
      int y2 = points.get(i).y; 
      g2d.drawLine(x1, y1, x2, y2); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame f = new JFrame(); 
       f.setContentPane(new Painter2()); 
       f.pack(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

Или еще лучше:

import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class Painter2 extends JPanel { 

    private static final float STROKE_WIDTH = 15f; 
    private static final Stroke STROKE = new BasicStroke(STROKE_WIDTH, BasicStroke.CAP_ROUND, 
      BasicStroke.JOIN_ROUND); 
    private static final Color CURVES_COLOR = Color.BLUE; 
    private static final Color TEMP_CURVE_COLOR = Color.PINK; 
    private List<List<Point>> curvesList = new ArrayList<>(); 
    private List<Point> tempCurve = null; 

    public Painter2() { 
     setBackground(Color.white); 
     MouseHandler listener = new MouseHandler(); 
     addMouseListener(listener); 
     addMouseMotionListener(listener); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(600, 600); 
    } 

    private class MouseHandler extends MouseAdapter implements MouseMotionListener { 
     @Override 
     public void mousePressed(MouseEvent e) { 
      tempCurve = new ArrayList<>(); 
      tempCurve.add(e.getPoint()); 
      repaint(); 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      tempCurve.add(e.getPoint()); 
      repaint(); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      tempCurve.add(e.getPoint()); 
      curvesList.add(tempCurve); 
      tempCurve = null; 
      repaint(); 
     } 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2 = (Graphics2D) g.create(); 
     g2.setStroke(STROKE); 
     g2.setColor(CURVES_COLOR); 
     for (List<Point> curve : curvesList) { 
      drawCurve(g2, curve); 
     } 

     if (tempCurve != null) { 
      g2.setColor(TEMP_CURVE_COLOR); 
      drawCurve(g2, tempCurve); 
     } 

     g2.dispose(); 
    } 

    private void drawCurve(Graphics2D g2, List<Point> ptList) { 
     for (int i = 1; i < ptList.size(); i++) { 
      int x1 = ptList.get(i - 1).x; 
      int y1 = ptList.get(i - 1).y; 
      int x2 = ptList.get(i).x; 
      int y2 = ptList.get(i).y; 
      g2.drawLine(x1, y1, x2, y2); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame f = new JFrame(); 
       f.setContentPane(new Painter2()); 
       f.pack(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^