FocusListener on editable JCombobox not firing

心不动则不痛 提交于 2019-12-20 03:46:40

问题


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 there!

So here is my Problem: I have an editable JCombobox, which should listen to a focus event by clicking in the editor component. But it doesn´t.

Here is a code snippet where I attach the listener:

cmbZoom.setToolTipText(locale.getString("GUI_ZoomFactor"));
cmbZoom.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));
cmbZoom.setPreferredSize(new Dimension(88, 29));
cmbZoom.setEditable(true);
((JTextField)cmbZoom.getEditor().getEditorComponent()).setHorizontalAlignment(JTextField.CENTER);
cmbZoom.getEditor().getEditorComponent().addFocusListener(
  new FocusListener(){
    public void focusGained(FocusEvent arg0) {
      System.out.println("GAINED");
    }

    public void focusLost(FocusEvent arg0) {
      System.out.println("LOST");
    }
  });

I have already tried to remove all other listener on the combobox, remove the observer pattern, make the combobox protected and attach the listener on each child,...

I have also tried to reimplement it like written on this post: JCombobox focusLost is not firing-why is that?

Is there a good way to debug events?

The whole project can be viewed on Github: https://github.com/nexxx/Database-Analyzer

The toolbar class can be found here (code starting on line 98): https://github.com/nexxx/Database-Analyzer/blob/master/src/dba/gui/auxClasses/toolBars/ToolBar.java


回答1:


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.




回答2:


  • 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();
            }
        });
    }
}


来源:https://stackoverflow.com/questions/15542410/focuslistener-on-editable-jcombobox-not-firing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!