FocusListener on editable JCombobox not firing

后端 未结 2 1186
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-22 14:02

First of all: Sorry that I cannot provide a SSCCE. I tried to recreate this problem on a small project, but without success, or should I say with success, because its working th

相关标签:
2条回答
  • 2021-01-22 14:28

    The fact that the same code causes problems in some circumstances but not others leads me to suspect your code may not be executing on the AWT event dispatch thread.

    0 讨论(0)
  • 2021-01-22 14:32
    • I'd to suggest don't to mixing FocusListener with Item & DocumentListener added to the JComboBox'es Editor, can to created endless loop

    for example,

    import java.awt.*;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.util.Vector;
    import javax.swing.*;
    import javax.swing.UIManager;
    import javax.swing.plaf.ColorUIResource;
    import javax.swing.plaf.metal.MetalComboBoxButton;
    
    public class MyComboBox {
    
        private Vector<String> listSomeString = new Vector<String>();
        private JComboBox someComboBox = new JComboBox(listSomeString);
        private JComboBox editableComboBox = new JComboBox(listSomeString);
        private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
        private JFrame frame;
    
        public MyComboBox() {
            listSomeString.add("-");
            listSomeString.add("Snowboarding");
            listSomeString.add("Rowing");
            listSomeString.add("Knitting");
            listSomeString.add("Speed reading");
    //
            someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
            someComboBox.setEditable(true);
            someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
            ((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
            someComboBox.getEditor().getEditorComponent().addFocusListener(fcsListener);
    //
            editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
            editableComboBox.setEditable(true);
            JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
            text.setBackground(Color.YELLOW);
            JComboBox coloredArrowsCombo = editableComboBox;
            Component[] comp = coloredArrowsCombo.getComponents();
            for (int i = 0; i < comp.length; i++) {
                if (comp[i] instanceof MetalComboBoxButton) {
                    MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
                    coloredArrowsButton.setBackground(null);
                    break;
                }
            }
            editableComboBox.getEditor().getEditorComponent().addFocusListener(fcsListener);
    //
            non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
            non_EditableComboBox.addFocusListener(fcsListener);
    //
            frame = new JFrame();
            frame.setLayout(new GridLayout(0, 1, 10, 10));
            frame.add(someComboBox);
            frame.add(editableComboBox);
            frame.add(non_EditableComboBox);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocation(100, 100);
            frame.pack();
            frame.setVisible(true);
        }
    
        //
        private FocusListener fcsListener = new FocusListener() {
    
            @Override
            public void focusGained(FocusEvent e) {
                dumpInfo(e);
            }
    
            @Override
            public void focusLost(FocusEvent e) {
                dumpInfo(e);
            }
    
            private void dumpInfo(FocusEvent e) {
                final Component c = e.getComponent();
                System.out.println("Source  : " + name(e.getComponent()));
                System.out.println("Opposite : " + name(e.getOppositeComponent()));
                System.out.println("Temporary: " + e.isTemporary());
                if (c instanceof JFormattedTextField) {//works for editable JComboBox too
                    SwingUtilities.invokeLater(new Runnable() {
    
                        @Override
                        public void run() {
                            ((JFormattedTextField) c).selectAll();
                        }
                    });
                } else if (c instanceof JTextField) {
                    SwingUtilities.invokeLater(new Runnable() {
    
                        @Override
                        public void run() {
                            ((JTextField) c).selectAll();
                        }
                    });
                } else if (c instanceof JTextField) {
                    SwingUtilities.invokeLater(new Runnable() {
    
                        @Override
                        public void run() {
                            ((JComboBox) c).getEditor().selectAll();
                        }
                    });
                }
            }
    
            private String name(Component c) {
                return (c == null) ? null : c.getName();
            }
        };
    
        public static void main(String[] args) {
            UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow));
            UIManager.put("JTextField.background", new ColorUIResource(Color.yellow));
            UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
            UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue));
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    MyComboBox aCTF = new MyComboBox();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题