ฉันต้องตีกอล์ฟออกนอกการเรียนซึ่งทำงานเป็นตาม:
package org.trypticon.hex.gui.datatransfer;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorListener;
import java.awt.event.ActionEvent;
import javax.annotation.Nonnull;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
import org.trypticon.hex.gui.Resources;
import org.trypticon.hex.gui.util.FinalizeGuardian;
import org.trypticon.hex.gui.util.FocusedComponentAction;
public class PasteAction extends FocusedComponentAction {
private final FlavorListener listener = (event) -> {
// this method in the superclass calls back `shouldBeEnabled`
updateEnabled();
};
@SuppressWarnings({"UnusedDeclaration"})
private final Object finalizeGuardian = new FinalizeGuardian(() -> {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.removeFlavorListener(listener);
});
public PasteAction() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.addFlavorListener(listener);
}
@Override
protected boolean shouldBeEnabled(@Nonnull JComponent focusOwner) {
TransferHandler transferHandler = focusOwner.getTransferHandler();
if (transferHandler == null) {
return false;
}
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
DataFlavor[] flavorsInClipboard = clipboard.getAvailableDataFlavors();
return transferHandler.canImport(focusOwner, flavorsInClipboard);
}
@Override
protected void doAction(@Nonnull JComponent focusOwner) throws Exception {
Action action = TransferHandler.getPasteAction();
action.actionPerformed(new ActionEvent(
focusOwner, ActionEvent.ACTION_PERFORMED, (String) action.getValue(Action.NAME)));
}
}
คน FinalizeGuardian
อ้างตัวว่าที่นี่คือปัจจุบันใช้การจัดเตรียมไว้ finalize()
:
package org.trypticon.hex.gui.util;
public final class FinalizeGuardian {
private final Runnable cleanupLogic;
public FinalizeGuardian(Runnable cleanupLogic) {
this.cleanupLogic = cleanupLogic;
}
@Override
protected final void finalize() throws Throwable {
try {
cleanupLogic.run();
} finally {
super.finalize();
}
}
}
ดังนั้นสำหรับเหตุผลที่ชัดเจนฉันอยากจะเปลี่ยนไปใช้ Cleaner
สำหรับเรื่องนี้
คนแรกลองบางอย่างเหมือนนี้:
package org.trypticon.hex.gui.util;
import java.lang.ref.Cleaner;
public final class FinalizeGuardian {
private static final Cleaner cleaner = Cleaner.create();
public FinalizeGuardian(Runnable cleanupLogic) {
cleaner.register(this, cleanupLogic);
}
}
ปัญหาคือตอนนี้วัตถุที่ไม่เคยกลายเป็นท่อนอ็อ reachable เพราะ:
Cleaner
ตัวมันเองถือเป็นแข็งแกร่งอ้างอิงไปcleanupLogic
cleanupLogic
ถือเป็นการอ้างอิงไปlistener
เพื่อที่จะเอาเป็นนักฟังที่listener
ถือเป็นการอ้างอิงไปที่ชั้นเรียนการกระทำเพื่อที่จะเรียกupdateEnabled
มัน- กการเรียนถือเป็นการอ้างอิงไป
FinalizeGuardian
ดังนั้นมันไม่ได้สะสม prematurely
เพราะว่า FinalizeGuardian
ตัวมันเองไม่เคยกลายเป็นท่อนอ็อ reachable ที่เครื่องมือทำความสะอาดไม่เคยโทรมา
ดังนั้นสิ่งที่ฉันอยากจะรู้คือมันมีหนทางที่จะ restructure นี่เพื่อตามกฏต้องการที่จะทำให้ Cleaner
ทำงานอย่างถูกต้องที่ ไม่ เกี่ยวข้องกัทำ encapsulation โดยการย้ายที่เป็นนักฟังที่ต้องออกการกระทำของผมห้องเรียนด้วยได้ไม๊?