On Wed, 30 Jul 2025 09:53:13 GMT, Prasanta Sadhukhan <psadhuk...@openjdk.org> wrote:
>>>> You can serialize a lambda expression if its target type and its captured >>>> arguments are serializable >> >> I think that means `propListener` is NOT going to serialize, because >> `PropertyChangeListener` isn't `Serializable`. I'm unfamiliar with these >> details; I found this link helpful: >> https://www.baeldung.com/java-serialize-lambda >> >> Alternatively: if we put `propListener` in BasicPopupMenuUI: then I think >> serialization will be less of an issue. `JComponent#ui` is transient, so we >> don't try to serialize it (and all of its other listeners). This way the >> JPopupMenu will come out on the other side of deserialization using whatever >> the L&F is in that setup. This feels good-ish to me. >> >> (I'm assuming most L&F's extend BasicPopupMenuUI?) >> >> This is all just an idea/suggestion; as long as the deserialized JPopupMenu >> behaves like the original JPopupMenu I think that should be fine. > > Yes, it seems deserialized JPopupMenu fails hiding the popup menu owing to > `propListener` not getting serialized. > > Tried with modified testcase of yours and fixed in latest PR > > > import java.awt.*; > import java.awt.event.*; > import javax.swing.*; > import java.beans.PropertyChangeListener; > import java.io.*; > > public class JPopupMenuSerializationTest { > > public static class MyThread implements Runnable { > static Container box; > static Component invo; > > public MyThread(Container cont, Component comp) { > this.invo = comp; > this.box = cont; > } > > public void run() { > System.out.println("Starting 3 second countdown..."); > try{ > Thread.currentThread().sleep(3000); > } catch (Exception e) {} > System.out.println("Removing popup invoker from the container."); > box.remove(invo); > box.repaint(); > } > } > > public static void main(String[] args) throws Exception { > JPopupMenuSerializationTest test = new JPopupMenuSerializationTest(); > test.testSerialization(); > } > > public void testSerialization() throws Exception { > JPopupMenu popupMenu = new JPopupMenu(); > byte[] data = serialize(popupMenu); > JPopupMenu copy = deserialize(data); > > test(copy); > } > > private void test(JPopupMenu jpm) { > JFrame frame = new JFrame("My frame"); > final Container pane = frame.getContentPane(); > pane.setLayout(new BorderLayout()); > pane.add(new JTextField("", 20), BorderLayout.NORTH); > JButton btn = new JButton("Exit"); > final Thread[] thr = new Thread[] { null }; > btn.setAction(new AbstractAction() { > public void actionPerformed(ActionEvent ev) { > System.exit(0); > } > }); > btn.setText("Exit"); > pane.add(btn, BorderLayout.SOUTH); > final JLabel label = new JLabel("Click here to invoke popup"); > label.addMouseListener(new MouseAdapter() { > public void mouseReleased(MouseEvent e) { > jpm.add("One"); > jpm.add("Two"); > jpm.add("Three"); > jpm.show(label, > label.getLocationOnScreen().x, > label.getLocationOnScreen().y); > } > > public void mousePressed(MouseEvent e) { > Thread thr = new Thread(new MyThread(pane, label)); > thr.st... Do we even care about serialisation as much? What would be the use case? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26407#discussion_r2242601894