001package jmri.jmrix.openlcb.swing; 002 003import java.awt.Toolkit; 004import java.awt.datatransfer.*; 005import java.awt.event.*; 006 007import javax.swing.*; 008 009import jmri.util.swing.*; 010import jmri.jmrix.can.CanSystemConnectionMemo; 011import jmri.jmrix.openlcb.OlcbAddress; 012import jmri.jmrix.openlcb.OlcbEventNameStore; 013 014import org.openlcb.EventID; 015import org.openlcb.swing.EventIdTextField; 016 017/** 018 * This is an entry field for Event IDs that also 019 * accepts event names 020 * 021 * @author Bob Jacobsen (C) 2024 022 */ 023public class NamedEventIdTextField extends OvertypeTextArea { 024 025 public NamedEventIdTextField(CanSystemConnectionMemo memo) { 026 this(23, memo); // heuristically-found default size 027 } 028 029 public NamedEventIdTextField(int size, CanSystemConnectionMemo memo) { 030 super(size); 031 this.memo = memo; 032 033 // set up semi-automatic tool tip 034 addMouseListener(JmriMouseListener.adapt(new JmriMouseListener() { 035 @Override 036 public void mouseEntered(JmriMouseEvent arg0) { 037 // Generate dynamic tooltip text here 038 setToolTipText(makeToolTipText(getText())); 039 } 040 041 @Override public void mouseClicked(JmriMouseEvent e) {} 042 @Override public void mouseExited(JmriMouseEvent arg0) {} 043 @Override public void mousePressed(JmriMouseEvent arg0) {} 044 @Override public void mouseReleased(JmriMouseEvent arg0) {} 045 })); 046 047 // Add a focus listener to update the tooltip dynamically 048 addFocusListener(new FocusListener() { 049 @Override 050 public void focusGained(FocusEvent e) { 051 setToolTipText(makeToolTipText(getText())); 052 } 053 054 @Override public void focusLost(FocusEvent e) {} 055 }); 056 057 var popup = EventIdTextField.createPopupMenu(this); 058 // add a custom copy operator to capture the numerical value 059 JMenuItem menuItem = new JMenuItem("Copy Numerical Event ID"); 060 popup.add(menuItem); 061 var self = this; 062 menuItem.addActionListener(new ActionListener() { 063 @Override 064 public void actionPerformed(ActionEvent e) { 065 String s = new OlcbAddress(self.getText(), memo).toDottedString(); 066 SwingUtilities.invokeLater(new Runnable() { 067 @Override 068 public void run() { 069 self.selectAll(); 070 } 071 }); 072 StringSelection eventToCopy = new StringSelection(s); 073 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 074 clipboard.setContents(eventToCopy, new ClipboardOwner() { 075 @Override 076 public void lostOwnership(Clipboard clipboard, Transferable transferable) { 077 } 078 }); 079 } 080 }); 081 // add a custom operator to set an event name 082 menuItem = new JMenuItem("Name This Event"); 083 popup.add(menuItem); 084 menuItem.addActionListener(new ActionListener() { 085 @Override 086 public void actionPerformed(ActionEvent e) { 087 String name = JmriJOptionPane.showInputDialog( 088 self, 089 "Enter a Name for the Event ID", 090 "" ) ; 091 092 if (name == null || name.isEmpty() ) return; // no new name entered 093 094 memo.get(OlcbEventNameStore.class).addMatch(getEventID(), name); 095 // and update the NEITF object to get name displayed 096 self.setText(name); 097 self.repaint(); 098 } 099 }); 100 101 // and set the updated popup menu 102 this.setComponentPopupMenu(popup); 103 } 104 105 final CanSystemConnectionMemo memo; 106 107 protected String makeToolTipText(String fieldText) { 108 var address = new OlcbAddress(fieldText, memo); 109 if (address.isFromName()) { 110 return fieldText+" is "+address.toDottedString(); 111 } 112 return "Enter an event ID or event name"; 113 } 114 115 public EventID getEventID() { 116 return new EventID(new OlcbAddress(getText(), memo).toDottedString()); 117 } 118 119 public String getEventIDAsDottedString() { 120 return new OlcbAddress(getText(), memo).toDottedString(); 121 } 122 123 // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NamedEventIdTextField.class); 124}