Java Swing圆形持久化程序文本文件重复对象问题求助
Hey there! Let's tackle that duplicate circle issue you're facing when saving to your text file. I've run into similar persistence quirks before, so let's break down the most likely causes and actionable fixes:
1. Accidental Multiple Save Triggers in Your Controller/View
It’s easy to accidentally call your save method multiple times without noticing—especially with Swing event handling. For example:
- You might have registered the same
ActionListenerto a button more than once, so a single click generates and saves two identical circles. - Your future Timer logic could be firing save calls prematurely before you’ve properly constrained it.
Fix:
- Double-check your controller code to ensure each new
Circleobject is passed toWriteFileexactly once. For example, in your button click handler:// Make sure this block only runs once per button click generateCircleBtn.addActionListener(e -> { Circle newRandomCircle = createRandomCircle(); writeFile.saveCircle(newRandomCircle); }); - Add a quick guard clause in your save method to reject duplicate object references (check if the circle is already in an in-memory list before writing).
2. No Duplicate Check Before Appending to File
If your WriteFile class just appends new circles to the file without verifying if they’re already present, you’ll get duplicates—either from identical random properties (low probability, but possible) or accidental re-saves of the same object.
Fix:
First, add a unique identifier to your Circle class to distinguish objects even if their properties match. Then, check existing entries before writing:
- Update the
Circleclass with a unique ID and proper equality checks:import java.util.Objects; import java.util.UUID; import java.awt.Color; public class Circle { private final UUID id; // Unique identifier private int x, y, diameter, dx, dy; private Color color; public Circle() { this.id = UUID.randomUUID(); // Initialize random properties here } // Override equals/hashCode to use the unique ID @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Circle circle = (Circle) o; return id.equals(circle.id); } @Override public int hashCode() { return Objects.hash(id); } // Update toString to include the ID for easy parsing later @Override public String toString() { return String.format("Circle{id=%s, x=%d, y=%d, diameter=%d, color=%d, dx=%d, dy=%d}", id, x, y, diameter, color.getRGB(), dx, dy); } } - Modify
WriteFileto check existing circles before appending:import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.awt.Color; public class WriteFile { private static final String FILE_PATH = "circles.txt"; public void saveCircle(Circle newCircle) throws IOException { List<Circle> existingCircles = loadExistingCircles(); // Only save if the circle isn't already in the file if (!existingCircles.contains(newCircle)) { try (FileWriter writer = new FileWriter(FILE_PATH, true)) { writer.write(newCircle.toString() + System.lineSeparator()); } } } private List<Circle> loadExistingCircles() throws IOException { List<Circle> circles = new ArrayList<>(); File file = new File(FILE_PATH); if (!file.exists()) return circles; try (BufferedReader reader = new BufferedReader(new FileReader(file))) { String line; while ((line = reader.readLine()) != null) { circles.add(parseCircleFromLine(line)); } } return circles; } // Parse the toString output back into a Circle object private Circle parseCircleFromLine(String line) { // Extract values using regex or string splitting (adjust based on your toString format) String[] parts = line.replace("Circle{", "").replace("}", "").split(", "); UUID id = UUID.fromString(parts[0].split("=")[1]); int x = Integer.parseInt(parts[1].split("=")[1]); int y = Integer.parseInt(parts[2].split("=")[1]); int diameter = Integer.parseInt(parts[3].split("=")[1]); Color color = new Color(Integer.parseInt(parts[4].split("=")[1])); int dx = Integer.parseInt(parts[5].split("=")[1]); int dy = Integer.parseInt(parts[6].split("=")[1]); Circle circle = new Circle(); // Set all parsed properties (you'll need to add setters or adjust the Circle constructor) return circle; } }
3. Unintended Object Reuse
If you’re reusing the same Circle object instance (instead of creating a new one each time) and modifying its properties, you might be saving the same object multiple times with updated values—leading to duplicate entries that look different but share the same unique ID.
Fix:
Ensure every time you generate a random circle, you create a brand new Circle instance:
private Circle createRandomCircle() { Circle circle = new Circle(); // Set random x, y, diameter, color, dx, dy here return circle; }
内容的提问来源于stack exchange,提问作者TryingToGetBetter

