import javax.swing.*; import java.awt.*; import java.awt.event.*; public class CirclePanelDemo { public static void main(String[] args) { SwingUtilities.invokeLater(() -> new CirclePanelDemo().createAndShowGUI()); } /* ----------------------------- */ /* 1. Finestra principale */ /* ----------------------------- */ private void createAndShowGUI() { JFrame frame = new JFrame("Circle – click, drag & delete"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); CirclePanel circlePanel = new CirclePanel(); frame.add(circlePanel, BorderLayout.CENTER); JButton clearBtn = new JButton("Cancella cerchio"); clearBtn.addActionListener(e -> circlePanel.clearCircle()); JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); btnPanel.add(clearBtn); frame.add(btnPanel, BorderLayout.SOUTH); frame.setSize(600, 400); frame.setLocationRelativeTo(null); // centra la finestra frame.setVisible(true); } /* ----------------------------- */ /* 2. JPanel che disegna il cerchio */ /* ----------------------------- */ private static class CirclePanel extends JPanel { private final int RADIUS = 30; // raggio fisso private int circleX = -1; // centro X (-1 → nessun cerchio) private int circleY = -1; // centro Y /* variabili per il drag */ private boolean dragging = false; private int offsetX, offsetY; CirclePanel() { setBackground(Color.WHITE); MouseAdapter ma = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int mx = e.getX(); int my = e.getY(); /* Se il cerchio esiste */ if (circleX != -1 && circleY != -1) { /* Se il click è dentro il cerchio → inizia drag */ if (isInsideCircle(mx, my)) { dragging = true; offsetX = mx - circleX; offsetY = my - circleY; } else { // Click fuori dal cerchio: non fare nulla dragging = false; } } else { /* Nessun cerchio → creiamo un nuovo */ setCircle(mx, my); } } @Override public void mouseReleased(MouseEvent e) { dragging = false; } @Override public void mouseDragged(MouseEvent e) { if (dragging && circleX != -1) { int mx = e.getX(); int my = e.getY(); setCircle(mx - offsetX, my - offsetY); } } }; addMouseListener(ma); addMouseMotionListener(ma); } /* ---------------------------------- */ /* 3. Utilità */ /* ---------------------------------- */ /** Verifica se il punto (x,y) è dentro il cerchio */ private boolean isInsideCircle(int x, int y) { if (circleX == -1 || circleY == -1) return false; int dx = x - circleX; int dy = y - circleY; return dx * dx + dy * dy <= RADIUS * RADIUS; } /** Imposta il centro del cerchio e ridisegna */ private void setCircle(int x, int y) { circleX = x; circleY = y; repaint(); } /** Cancella il cerchio (se presente) */ public void clearCircle() { circleX = -1; circleY = -1; repaint(); } /* ---------------------------------- */ /* 4. Disegno del pannello */ /* ---------------------------------- */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (circleX == -1 || circleY == -1) return; // nessun cerchio da disegnare Graphics2D g2 = (Graphics2D) g.create(); try { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int topLeftX = circleX - RADIUS; int topLeftY = circleY - RADIUS; g2.setColor(Color.RED); g2.fillOval(topLeftX, topLeftY, 2 * RADIUS, 2 * RADIUS); // bordo bianco g2.setStroke(new BasicStroke(2f)); g2.setColor(Color.WHITE); g2.drawOval(topLeftX, topLeftY, 2 * RADIUS, 2 * RADIUS); } finally { g2.dispose(); } } } }