'SwingUtilities.updateComponentTreeUI(this)' removes custom Document from JComboBox

早过忘川 提交于 2019-12-12 05:18:36

问题


I have an editable JComboBox and JTextField. Both with custom Documents. Here is the code:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class SwingUtilStrangeBehav extends JFrame {

    public SwingUtilStrangeBehav() {
       JComboBox<String> combo = new JComboBox<>(new String[]{"a", "b", "c"});
       combo.setEditable(true); 

       ((JTextField)combo.getEditor().getEditorComponent()).setDocument(new PlainDocument() {
            private static final long serialVersionUID = 1L;

            @Override
            public void insertString(int offs, String str, AttributeSet a)
                        throws BadLocationException {

                    System.out.println("New text inserted into combo!");
                    super.insertString(offs, str, a);
            }
      });

      JTextField field = new JTextField();
      field.setDocument(new PlainDocument() {
          private static final long serialVersionUID = 1L;

          @Override
          public void insertString(int offs, String str, AttributeSet a)
                        throws BadLocationException {

                  System.out.println("New text inserted into text!");
                  super.insertString(offs, str, a);
          }
    });

    Container c = getContentPane();
    c.setLayout(new BoxLayout(c, BoxLayout.PAGE_AXIS));

    c.add(combo);
    c.add(Box.createRigidArea(new Dimension(0, 5)));
    c.add(field);

    //SwingUtilities.updateComponentTreeUI(this);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
  }

  public static void main(String arg[]) {
     java.awt.EventQueue.invokeLater(new Runnable() {

         @Override
         public void run() {
             new SwingUtilStrangeBehav();
         }
     });
  }
}

Then I input some text in JComboBox or JTextField I get the following output in my console, for example:

New text inserted into combo!
New text inserted into text!

That's great! When I uncomment the following line SwingUtilities.updateComponentTreeUI(this); and run this programm, I can only get this output:

New text inserted into text!

It seems that JComboBox's Document was removed. Why was custom Document removed and how to solve this problem? I want that custom Document would still be in JComboBox after executing SwingUtilities.updateComponentTreeUI(this);.

FYI: I use SwingUtilities.updateComponentTreeUI(this); to apply new Font to Container.


回答1:


This happens because the JComboBox's editor is controlled by its UI-Delegate, that is XXComboBoxUI: as updateUI sets a new ui, the controlled editor is replaced as well. A couple of options:

  • register a propertyChangeListener on the comboBox to get notified when the editor is replaced and set the custom document again
  • install a custom editor (instead of only a custom document)
  • (probably not an option, just in case) don't use updateUI, instead walk the container to set the font


来源:https://stackoverflow.com/questions/17345673/swingutilities-updatecomponenttreeuithis-removes-custom-document-from-jcombo

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