'SwingUtilities.updateComponentTreeUI(this)'从JComboBox中删除自定义文档

时间:2013-06-27 14:18:55

标签: java swing jcombobox swingutilities

我有一个可编辑的JComboBox和JTextField。两者都有自定义文档。这是代码:

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

然后我在JComboBox或JTextField中输入一些文本我在控制台中得到以下输出,例如:

插入组合中的新文字!
新文字插入文字!

太棒了!当我取消注释以下行 SwingUtilities.updateComponentTreeUI(this); 并运行此程序时,我只能获得此输出:

新文字插入文字!

似乎JComboBox的文档被删除了。为什么删除了自定义文档以及如何解决此问题?我希望在执行 SwingUtilities.updateComponentTreeUI(this); 之后,自定义文档仍然在JComboBox中。

仅供参考:我使用 SwingUtilities.updateComponentTreeUI(this); 将新字体应用于容器。

1 个答案:

答案 0 :(得分:2)

这是因为JComboBox的编辑器由其UI-Delegate控制,即XXComboBoxUI:因为updateUI设置了一个新的ui,所以也会替换受控编辑器。有两种选择:

  • 在comboBox上注册propertyChangeListener,以便在替换编辑器时获得通知并再次设置自定义文档
  • 安装自定义编辑器(而不仅仅是自定义文档)
  • (可能不是一个选项,以防万一)不要使用updateUI,而是走容器来设置字体