使用“System”LookAndFeel时,Java组合框setSelectedItem出现故障

时间:2015-03-15 17:01:32

标签: java jcombobox

我正在使用keyTyped listerner来模拟Windows的组合框功能,以便在用户键入编辑框时自动滚动组合列表框。当使用默认的跨平台LookAndFeel时,它运行良好。 我发现当LookAndFeel更改为系统LookAndFeel时,JComboBox.setSelectedItem出现故障:

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

以下代码使用针对末尾的setSelectedItem(OrigTypeface)调用来恢复编辑框中的原始文本。

使用跨平台LookAndFeel,当用户键入“abc”时,列表框会逐渐显示与列表框中键入的文本匹配的第一个项目。但是,使用System LookAndFeel,编辑框中的文本从“a”变为“b”变为“c”,最后在文本框中仅显示字母“c”,并显示带有条目的列表框第一个字母'c'。实际上,setSelectedItem失败了,并在文本框中放了一个空白。

任何人都知道解决这个问题的方法吗?

   getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {  
       @Override public void keyTyped(KeyEvent ev) {
              String OrigTypeface=(String)cb.getEditor().getItem();
              if (OrigTypeface==null) OrigTypeface=""; 
              char CurChar=ev.getKeyChar();
              String typeface=OrigTypeface + CurChar;  character
              typeface=typeface.toLowerCase();
              if (typeface.length()==0 || (int)CurChar==8) return;  // exclude the backspace key

               int i,count=cb.getItemCount();
               for (i=0;i<count;i++) {
                  String item=(String)cb.getItemAt(i);
                  if (item!=null) {
                     item=item.toLowerCase();
                     if (item.startsWith(typeface) && cb.getSelectedIndex()!=i) {

                        int BumpUp=cb.getMaximumRowCount()/2;  // normally list-bolx would position the item the end of the list, so we bump its position to the middle
                        if ((i+BumpUp)<count) cb.setSelectedIndex(i+BumpUp);    
                        cb.setSelectedIndex(i);  // select this item
                        cb.hidePopup();     // hide/show to actually display this item in the scroll list
                        cb.showPopup();

                        cb.setSelectedItem(OrigTypeface);  // put this item back in the edit box since it gets overridden by the above setSelectedIndex call

                        break;
                     } 
                    } 
                 }
              } 
          }               
   });

这是一个小的java文件,您可以编译并运行它来重新创建此问题。只需在两个组合框中键入“abc”即可。你会看到左边的那个工作正常,但右边没有。

import java.awt.*;
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.print.*;
import java.lang.reflect.Method;
import java.awt.font.*;                    // to get TextAttribute class
import java.awt.geom.*;                    // to get AffilineTransform
import java.lang.reflect.Array;
import java.nio.charset.*;
import java.text.*;                       // to get SimpleDateFormat
import javax.swing.event.*;
import java.awt.datatransfer.*;
import java.awt.image.*;
import javax.print.attribute.standard.*;
import javax.print.attribute.standard.Media.*;
import javax.swing.border.*;
import java.awt.Robot;
import java.util.prefs.*;
import java.awt.dnd.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.BasicComboBoxUI;

public class demo extends JPanel {
    OurComboBox cb1;
    OurComboBox cb2;
    JLabel lbl1;
    JLabel lbl2;

    public demo() {
        super(new GridLayout(2,2));

        JLabel lbl1=new  JLabel();
        lbl1.setPreferredSize(new Dimension(250, 15));
        lbl1.setText("ComboBox using cross-platform L&F");
        add(lbl1);

        JLabel lbl2=new  JLabel();
        lbl2.setPreferredSize(new Dimension(250, 15));
        lbl2.setText("ComboBox using System L&F");
        add(lbl2);

        cb1=new OurComboBox();
        cb1.setPreferredSize(new Dimension(200, 15));
        cb1.setLightWeightPopupEnabled(false);
        cb1.setEditable(true);  // allow edit box

        AddComboItems(cb1);

        add(cb1);

        // change to System LookAndFeel temporarily
        try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} 
        catch (Exception ex) {}

        cb2=new OurComboBox();
        cb2.setPreferredSize(new Dimension(200, 15));
        cb2.setLightWeightPopupEnabled(false);
        cb2.setEditable(true);  // allow edit box
        AddComboItems(cb2);
        add(cb2);

        // rever back LookAndFeel
        try {UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); }
        catch (Exception ex) {}

    }

    // add items to the combo-box
    void AddComboItems(OurComboBox cb) {
       for (int i=0;i<20;i++) cb.addItem("a"+((Integer)i).toString());
       for (int i=0;i<20;i++) cb.addItem("ab"+((Integer)i).toString());
       for (int i=0;i<20;i++) cb.addItem("abc"+((Integer)i).toString());
       for (int i=0;i<20;i++) cb.addItem("bc"+((Integer)i).toString());
    } 

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Add content to the window.
        frame.add(new demo());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                //Turn off metal's use of bold fonts
            UIManager.put("swing.boldMetal", Boolean.FALSE);
            createAndShowGUI();
            }
        });
    }
}

 class OurComboBox extends JComboBox {
    public boolean locked;
    public OurComboBox cb;

    OurComboBox() {
       cb=this;  // save so it can be accessed inside the key listerner below

       getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {  // add key listenr to the editor component
           @Override public void keyTyped(KeyEvent ev) {
               String OrigTypeface=(String)cb.getEditor().getItem();
               if (OrigTypeface==null) OrigTypeface="";  // 20150313  
               char CurChar=ev.getKeyChar();
               String typeface=OrigTypeface + CurChar;  // getItem() returns the prviously typed text, getKeyChar()) returns the latest character
               typeface=typeface.toLowerCase();
               if (typeface.length()==0 || (int)CurChar==8) return;  // exclude the backspace key

               if ((int)CurChar==0xa) return;    // just return for now
               else {     // scroll the combo-box to show the currently typed typefacee
                  int i,count=cb.getItemCount();
                  for (i=0;i<count;i++) {
                     String item=(String)cb.getItemAt(i);
                     if (item!=null) {
                        item=item.toLowerCase();
                        if (item.startsWith(typeface) && cb.getSelectedIndex()!=i) {
                           cb.locked=true;  // don't process item state changed for this change

                           if ((i+cb.getMaximumRowCount()/2)<count) cb.setSelectedIndex(i+cb.getMaximumRowCount()/2);  // try to move the actual index in the middle because java by default shows the selected index at the bottom  
                           cb.setSelectedIndex(i);  // select this item
                           cb.hidePopup();     // hide/show to actually display this item in the scroll list
                           cb.showPopup();

                           cb.setSelectedItem(OrigTypeface);  // put this item back in the edit box
                           cb.locked=false;

                           break;
                        } 
                     } 
                  }
               } 
           }
       });
    } 

 } 

0 个答案:

没有答案