/* * Copyright ©1998-2020 by Richard A. Wilkes. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, version 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This Source Code Form is "Incompatible With Secondary Licenses", as * defined by the Mozilla Public License, version 2.0. */ package com.trollworks.gcs.menu; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import javax.swing.Action; import javax.swing.JMenuItem; import javax.swing.KeyStroke; class DynamicJMenuItemPropertyChangeListener implements PropertyChangeListener { private static ReferenceQueue<JMenuItem> QUEUE = new ReferenceQueue<>(); private WeakReference<JMenuItem> mTarget; private Action mAction; private PropertyChangeListener mChainedListener; DynamicJMenuItemPropertyChangeListener(JMenuItem menuItem, Action action, PropertyChangeListener chainedListener) { OwnedWeakReference ref; while ((ref = (OwnedWeakReference) QUEUE.poll()) != null) { DynamicJMenuItemPropertyChangeListener old = (DynamicJMenuItemPropertyChangeListener) ref.getOwner(); Action oldAction = old.mAction; if (oldAction != null) { oldAction.removePropertyChangeListener(old); } } mTarget = new OwnedWeakReference(menuItem, QUEUE, this); mAction = action; mChainedListener = chainedListener; } @Override public void propertyChange(PropertyChangeEvent event) { JMenuItem mi = mTarget.get(); if (mi == null) { Action action = (Action) event.getSource(); action.removePropertyChangeListener(this); } else { if (event.getPropertyName().equals(Action.ACCELERATOR_KEY)) { mi.setAccelerator((KeyStroke) event.getNewValue()); mi.invalidate(); mi.repaint(); } } mChainedListener.propertyChange(event); } private static class OwnedWeakReference extends WeakReference<JMenuItem> { private DynamicJMenuItemPropertyChangeListener mOwner; OwnedWeakReference(JMenuItem target, ReferenceQueue<JMenuItem> queue, DynamicJMenuItemPropertyChangeListener owner) { super(target, queue); mOwner = owner; } public Object getOwner() { return mOwner; } } }