Rozwiązad problem z pustym polem pomiędzy kolejnymi owalami (można wykorzystad
obiekty klas BasicStroke i Graphics2D),
Problem polega na tym ze jak rysuje wolno to painter rysuje ciagla linie a gdy pociagne szybko to ja kropkuje jak temu zaradzic?
oto kod:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.EventListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;

import javax.swing.JFrame;

public class Painter extends JFrame implements MouseListener, MouseMotionListener, ActionListener, ChangeListener {

    private JButton clearButton; //Pole danych do przechowywania przycisku czyszczacego
    private JPanel menu;
    private JPanel workspace;

    private JSlider suwak;
    int size;
    private JButton klik;
    private Color kolor;

    public ArrayList<Integer> points = new ArrayList<>();

    public void mouseMoved(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
//usunalem maina, bo tu nic nie robil a dawal bledy

    public Painter(int sz, int w) {
        //Stworzenie interfejsu graficznego (GUI)
        this.setLayout(new BorderLayout()); //Ustawienie sposobu ukladania komponentow
        menu = new JPanel(); //Stworzenie panelu menu
        menu.setLayout(new FlowLayout()); //Ustawienie layout dla tego panelu
        menu.setBackground(Color.LIGHT_GRAY); //Ustawienie koloru tła
        clearButton = new JButton("Clear"); //Stworzenie nowego przycisku
        menu.add(clearButton); // Dodanie przycisku do panelu menu
        this.add(menu, BorderLayout.NORTH); // Dodanie menu na górze okna
        workspace = new JPanel(); //Stworzenie panelu pola do rysowania
        // dodanie obsługi zdarzeń kliknięcia i ruchu po panelu
        workspace.addMouseListener(this);
        workspace.addMouseMotionListener(this);
        this.add(workspace, BorderLayout.CENTER); // Dodanie pola do rysowania w środku okna
        this.setSize(sz,w); // Ustawienie wymiarów okna
        this.setTitle("Painter"); // Nazwa okna
        clearButton.addActionListener(this); //Aktywowanie obslugi przycisku

        suwak = new JSlider(JSlider.HORIZONTAL, 5, 25, 10);
        suwak.setMajorTickSpacing(10);
        suwak.setMinorTickSpacing(1);
        suwak.setPaintTicks(true);
        suwak.setPaintLabels(true);
        suwak.addChangeListener(this);
        menu.add(suwak);
        size=10;

        klik = new JButton("Set Color");
        klik.addActionListener(this);
        menu.add(klik);
    }

    public void paint(Graphics g)
    {
    // wywołanie metody paint klasy JFrame
    super.paint(g);
    }

    public void actionPerformed(ActionEvent e)
    {
    // TODO Auto-generated method stub
    if(e.getSource() == clearButton) //Sprawdzenie czy zrodlem zdarzenia jest przycisk
    {
    //Czyszczenie pola roboczego
    workspace.getGraphics().clearRect(0, 0, workspace.getWidth(), workspace.getHeight());

    } 
    if(e.getSource() == klik) //Sprawdzenie czy zrodlem zdarzenia jest przycisk
    {

    kolor = JColorChooser.showDialog(null,  "Choose a color", kolor);

    }
    }
    //Rysowanie w momencie przeciagania myszy (przycisniety przycisk + mysz w ruchu)
    @Override
    public void mouseDragged(MouseEvent e) {
    Graphics g = workspace.getGraphics();
    g.setColor(kolor);
    g.fillOval(e.getX()-5, e.getY()-(size/2), size, size);
    e.consume();
    }

    //Rysowanie w momencie przycisniecia przycisku myszy
    @Override
    public void mousePressed(MouseEvent e) {
    Graphics g = workspace.getGraphics();
    g.setColor(kolor);
    g.fillOval(e.getX()-5, e.getY()-(size/2), size, size);
    e.consume();

        points.add(e.getX());
        points.add(e.getY());

        if(points.size()==4)
        {

            g.fillRect( points.get(2)-((points.get(2)-points.get(0))),points.get(3)-(points.get(3)-points.get(1)) , points.get(2)-points.get(0), points.get(3)-points.get(1));

                //prostokat

                    g.fillOval( points.get(2)-((points.get(2)-points.get(0))),points.get(3)-(points.get(3)-points.get(1)) , points.get(2)-points.get(0), points.get(3)-points.get(1));
                //owal
                    points.clear();
        }

    }

    public static void main(String[] args)
    {
    Painter paint = new Painter(500,500); //Ustawienia rozmiarów okna
    //Ustalenie operacji po kliknięciu na X
    paint.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    paint.setVisible(true); // Ustawienie widoczności okna

    }

    public void stateChanged(ChangeEvent e)
    {
    if(e.getSource() == suwak) //Sprawdzenie czy zrodlem zdarzenia jest przycisk
    {

        size = suwak.getValue();
    } 
    }

}