मैं एक स्विंग कार्रवाई वर्ग है जो काम करता है के रूप में इस प्रकार है:
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);
}
}
समस्या यह है कि अब वस्तु कभी नहीं हो जाता है, प्रेत पहुँच से बाहर है, क्योंकि:
Cleaner
ही रखती है एक मजबूत संदर्भ के लिएcleanupLogic
cleanupLogic
धारण करने के लिए एक संदर्भlistener
हटाने के लिए आदेश में श्रोताlistener
धारण करने के लिए एक संदर्भ कार्रवाई, वर्ग, क्रम में करने के लिए कॉलupdateEnabled
पर यह- कार्रवाई वर्ग में रखती है, के लिए एक संदर्भ
FinalizeGuardian
इतना है कि यह नहीं मिलता समय से पहले एकत्र
क्योंकि FinalizeGuardian
खुद को कभी नहीं हो जाता है, प्रेत पहुँच से बाहर है, क्लीनर होना कभी नहीं होगा कहा जाता है ।
तो मैं क्या करना चाहते हैं पता करने के लिए है, वहाँ है एक तरह से पुनर्गठन करने के लिए इस का पालन करने के लिए नियम बनाने के लिए आवश्यक Cleaner
सही ढंग से काम है कि नहीं करता है शामिल है को तोड़ने के encapsulation के द्वारा चलती करने के लिए श्रोता के बाहर मेरी कार्रवाई वर्ग?