2015-11-21 2 views
0

Как и в названии, я создаю пользовательский JComboBox, и пользовательский BasicComboPopup не скрывает, когда я пишу popup.hide(); Кроме того, если вы, ребята, знаете более простой способ создания JComboBox, который показывает сокращенные значения в основном компоненте, но не сокращенный контент во всплывающем окне, я все уши. Вот мой код:Пользовательский JComboBox не закрывается при двойном щелчке

 import javax.swing.JComboBox; 
    import java.awt.event.MouseEvent; 
    import java.awt.event.MouseAdapter; 
    import javax.swing.JFrame; 
    import java.awt.GridBagLayout; 
    import java.awt.Component; 
    import java.awt.Container; 
    import javax.swing.JButton; 
    import java.awt.event.ActionListener; 
    import java.awt.event.ActionEvent; 
    import javax.swing.JPopupMenu; 
    import javax.swing.plaf.basic.BasicComboPopup; 

    class ChangingCombos extends JFrame 
    { 
     String[] abbrStr = new String[]{"--","TF","FF","SP"}; 
     String[] longStr = new String[]{"-Select One-","Thermo Film","Fashion Film","Specialty"}; 
     AbbreviatedComboBox<String> box = new AbbreviatedComboBox<String>(longStr,abbrStr); 

     public ChangingCombos() 
     { 
      setLayout(new GridBagLayout()); 
      add(box); 
      setDefaultCloseOperation(EXIT_ON_CLOSE); 
      setLocation(300,300); 
      pack(); 
      setVisible(true); 
     } 

     public static void main(String[]args) 
     { 
      new ChangingCombos(); 
     } 

     class AbbreviatedComboBox<E> extends JComboBox<E> 
     { 
      E[] items = null; 
      E[] abbreviations = null; 
      BasicComboPopup popup = null; 
      JComboBox self = this; 
      JComboBox<E> abstractBox; 

      public AbbreviatedComboBox(E[] items, E[] abbreviations) 
      { 
       super(abbreviations); 
       this.items = items; 
       this.abbreviations = abbreviations; 
       abstractBox = new JComboBox<E>(items); 
       popup = new BasicComboPopup(abstractBox); 
       addCustomMouseListener(this); 
       for(Component c: GUIUtilities.getAllSubcomponentsOf(this))addCustomMouseListener(c); 

      } 

      private void addCustomMouseListener(Component c) 
      { 
       c.addMouseListener(new MouseAdapter() 
       { 
       public void mousePressed(MouseEvent e) 
       { 
        System.out.println("ohp"); 
        if(!popup.isVisible()) 
        { 
         popup.show(self,0,self.getHeight()); 
        } 
        else popup.hide(); 
       } 
       }); 
      } 
     } 
    } 

... также, чтобы объяснить GUIUtilities, это еще один пользовательский класс и метод getAllSubcomponentsOf(Container c) рекурсивно возвращает все компоненты, содержащиеся в указанном контейнере. Это быстрый способ получить доступ к маленькой кнопке стрелки на JComboBox. Может показаться, что это создаст проблему с добавлением нескольких прослушивателей к одному и тому же объекту, но он будет выполнять только одно действие через одно действие, как было проверено с печатью System.out.println("ohp") только один раз за клик.

Редактировать: setVisible(false) не работает. Метод hide, на который я ссылаюсь, равен ComboPopup.hide(); он не устарел. Когда я делаю abstractBox.hidePopup(), он ничего не делает, потому что abstractBox не отображается на экране и никогда не предназначался. Просто его всплывающее окно. Продолжайте пытаться.

ответ

0

Это то, что я в конечном счете, в конечном итоге, используя.

import javax.swing.border.LineBorder; 
    import java.awt.Dimension; 
    import java.awt.event.ItemEvent; 
    import java.awt.event.ItemListener; 
    import javax.swing.JComboBox; 
    import java.awt.event.MouseEvent; 
    import java.awt.event.MouseListener; 
    import java.awt.Component; 
    import javax.swing.JButton; 
    import javax.swing.plaf.basic.BasicComboPopup; 

    class AbbreviatedComboBox<E> extends JComboBox<E> implements MouseListener, ItemListener 
    { 
    AbbreviatedComboBox<E> self = this; 
    E[] items = null; 
    E[] abbreviations = null; 
    JComboBox<E> abstractBox = null; 
    BasicComboPopup popup = null; 
    JButton comboBoxButton = null; 
    int maximumRowCount = 0; 

    public AbbreviatedComboBox(E[] items, E[] abbreviations) 
    { 
     super(abbreviations); 
     this.items = items; 
     this.abbreviations = abbreviations; 
     abstractBox = new JComboBox<E>(items); 
     new JComboBoxRowCountRetreival(); 
     popup = new BasicComboPopup(abstractBox); 
     for(Component c: getComponents())if(c instanceof JButton)comboBoxButton = (JButton)c; 
     for(MouseListener l: getMouseListeners())removeMouseListener(l); 
     for(MouseListener l: comboBoxButton.getMouseListeners())comboBoxButton.removeMouseListener(l); 
     addMouseListener(this); 
     comboBoxButton.addMouseListener(this); 
     abstractBox.addItemListener(this); 
     popup.setPreferredSize(new Dimension(popup.getPreferredSize().width,popup.getPreferredSize().height/maximumRowCount*items.length+popup.getMargin().top+popup.getMargin().bottom+(((LineBorder)popup.getBorder()).getThickness()*2))); 
     popup.addMouseListener(this); 
    } 

    public void itemStateChanged(ItemEvent e) 
    { 
     for(int i = 0; i < items.length; i++)if(items[i].equals(e.getItem()))setSelectedIndex(i); 
     popup.hide(); 
    } 

    public void mousePressed(MouseEvent e) 
    { 
     requestFocusInWindow(); 
     if(!popup.isVisible()) 
     { 
      popup.show(this,0,getHeight()); 
     } 
     else 
     { 
      popup.hide(); 
     } 
    } 

    public void mouseReleased(MouseEvent e){} 
    public void mouseClicked(MouseEvent e){} 
    public void mouseEntered(MouseEvent e){} 
    public void mouseExited(MouseEvent e){} 

    class JComboBoxRowCountRetreival extends JComboBox 
    { 
     public JComboBoxRowCountRetreival() 
     { 
      super(); 
      self.maximumRowCount = super.maximumRowCount; 
     } 
    } 
    } 
+0

Нет, вы не должны использовать два массива для отслеживания ваших данных. Если у вас есть две части информации, вам необходимо создать пользовательский объект и сохранить объект в модели, как я объяснил в своем первоначальном ответе. Я обновляю свой ответ, чтобы показать, как вы можете отображать поле со списком и выпадающее меню по-разному. Поле со списком будет иметь индекс -1. В моем простом примере я просто отобразил номер выбора вместе со значением. В вашем случае у вас есть два свойства, чтобы вы отображали соответствующее свойство. Все мои другие комментарии из моего первоначального ответа по-прежнему применяются. – camickr

0

Попробуйте использовать popup.hidePopup(); Я считаю, что .hide(); устарел.

Отметьте this для получения более подробной информации о текущем методе.

И this вне, почему старый устарел.

Существует альтернативный метод. Вы могли бы назвать popup.setVisible(false);

+0

'javax.swing.plaf.basic.ComboPopup.hide() 'не устарел, кстати. 'javax.swing.plaf.basic.BasicComboPopup.hidePopup()' не существует. Я также попробовал 'setVisible (false)'. – user3376587

+0

hidePopup() - это метод для JComboBox. Объект, который я пытаюсь скрыть, - BasicComboPopup. JComboBox 'abstractBox' не отображается на экране. – user3376587

1

более простым способом сделать JComboBox, что показывает сокращенное значение в основном компоненте, но содержание не-сокращенный во всплывающем окне

Вы сохраняете пользовательский объект в ComboBoxModel, что содержит два свойства:

  1. значение - используется для обработки в программе
  2. описание - используется для отображения в поле со списком

Затем вы можете использовать собственный рендерер для поля со списком для отображения значения описания.

Для получения дополнительной информации и кодовых примеров этого подхода обращайтесь к ComboBox With Custom Renderer.

Вы также можете проверить Combo Box Prompt, который позволяет запрашивать значение без сохранения элемента в ComboBoxModel. Вам нужно будет включить это решение в средство визуализации из приведенного выше примера.

Edit:

Может быть, я неправильно понял ваше требование. Вот простой пример, который рендерер выпадающий список иначе, чем дисплей в поле со списком:

import java.awt.*; 
import javax.swing.*; 
import javax.swing.plaf.basic.*; 

public class ComboBoxRenderer extends JPanel 
{ 
    public ComboBoxRenderer() 
    { 
     String[] items = { "Red", "Green", "Blue" }; 
     JComboBox<String> comboBox = new JComboBox<String>(items); 
     comboBox.setSelectedIndex(-1); 
     comboBox.setPrototypeDisplayValue("Select Color"); 
     comboBox.setRenderer(new MyRenderer()); 

     add(comboBox, BorderLayout.NORTH); 
    } 

    class MyRenderer extends BasicComboBoxRenderer 
    { 
     public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
     { 
      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 

      if (value == null) 
       value = "Select Color"; 

      if (index == -1 && value != null) 
      { 
       setText(value.toString()); 
      } 
      else 
       setText(index + " : " + value); 

      return this; 
     } 
    } 

    private static void createAndShowGUI() 
    { 

     JFrame frame = new JFrame("SSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new ComboBoxRenderer()); 
     frame.setLocationByPlatform(true); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
+0

Ничего себе! Спасибо за эту очень полезную информацию. Я думаю, что это именно то, что я ищу. Если это сработает, я выберу ваш ответ как лучший. – user3376587

+0

Думал, что я вернусь к этому, чтобы вы знали ... к сожалению, это не сработало. Но я опубликую, что работало как ответ. – user3376587