2012-06-16 32 views
6

Tôi hiện đang có một JComboBox mà tôi đang sử dụng làm danh sách phát âm thanh - những gì tôi muốn đạt được là nút "xóa" nhỏ ở phía bên phải của mỗi mục mà tôi có thể sử dụng xóa nó khỏi mô hình cơ bản, nơi vòng tròn là:Các nút hiển thị trong các mục JComboBox

Cách tốt nhất để đạt được điều này là gì?

Tôi muốn nút này giống nhau cho tất cả các mục trong JComboBox.

demo screenshot

+0

bạn muốn '1)' đặt JLabel và JButton vào một mục, '2)' cho tất cả các mục trong JComboBox hoặc không phải là – mKorbel

+0

@mKorbel Bạn không chắc chắn ý nghĩa của điểm đầu tiên của mình là gì? Nhưng đối với điểm thứ hai, vâng. – berry120

+0

Ở đó tôi thấy một vấn đề quan trọng, JComboBox drop_down biến mất sau khi bất kỳ Mouse_click nào đến Mục (Java1.4 trở lên), bạn có đồng ý và chấp nhận rằng – mKorbel

Trả lời

8

Hãy để tôi bắt đầu bằng cách nói rằng đây là một câu hỏi thú vị (+1 một thời gian trước).

Tôi phải nhanh chóng thử và xem bản thân mình khó khăn như thế nào để đạt được kết quả mong muốn với JComboBox. Kết luận tôi nhận được (như @trashgod nói trong bình luận ở trên) là đối tượng này không bao giờ được thiết kế để có các thành phần khác hoặc ít nhất nó cảm thấy như thế này với tôi.

Dưới đây là mẫu làm điều gì đó bạn muốn. Bạn có thể sử dụng nó như là một sự khởi đầu, nhưng phải trung thực bạn nên quên sử dụng JComboBox cho vấn đề này.

Không có nghĩa là mẫu dưới đây trình bày đúng cách tiếp cận vấn đề. Nó chỉ đơn giản là cho thấy kết quả của những nỗ lực của tôi tiếp cận vấn đề. Mã bên dưới không bảo toàn các quy tắc thực hành tốt, ví dụ: nó trộn bản trình bày với chức năng (trình kết xuất loại bỏ các phần tử). Đây là thực tế chỉ là một hack không phải là một giải pháp thực sự.

import java.awt.*; 
import java.awt.event.*; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 

public class ButtonCombo { 

    private JPanel getContent() throws MalformedURLException { 
     String[] ids = {"north", "west", "south", "east"}; 
     JComboBox combo = new JComboBox(ids); 
     Icon removeIcon = new ImageIcon(new URL("http://filesharefreak.org/images/red_x.png")); 
     combo.setRenderer(new ButtonComboRenderer(removeIcon, combo)); 
     JPanel panel = new JPanel(); 
     panel.add(combo); 
     return panel; 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        JFrame f = new JFrame(); 
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        JPanel panel = new JPanel(); 
        panel.add(new ButtonCombo().getContent()); 
        JButton button = new JButton("OKOKO"); 
        panel.add(button); 
        f.setContentPane(panel); 
        f.setSize(300, 160); 
        f.setLocation(200, 200); 
        f.setVisible(true); 
       } catch (MalformedURLException ex) { 
        Logger.getLogger(ButtonCombo.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     }); 
    } 
} 

class ButtonComboRenderer implements ListCellRenderer { 
    Icon icon; 
    JPanel panel; 
    JLabel label; 
    JButton button; 

    public ButtonComboRenderer(Icon removeIcon, final JComboBox combo) { 
     icon = removeIcon; 
     label = new JLabel(); 
     button = new JButton(icon); 
     button.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight())); 
     panel = new JPanel(new BorderLayout()); 
     panel.add(label); 
     panel.add(button, BorderLayout.EAST); 
     panel.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mousePressed(MouseEvent e) { 
       if (button.getX() < e.getX()) { 
        System.out.println("button contains the click remove the item"); 
        combo.removeItem(label.getText()); 
       } 
      } 
     }); 
    } 
    //so we will install the mouse listener once 
    boolean isFirst = true; 

    @Override 
    public Component getListCellRendererComponent(JList list, 
      Object value, 
      int index, 
      boolean isSelected, 
      boolean cellHasFocus) { 
     if (isFirst) { 
      isFirst = false; 
      list.addMouseListener(new MouseAdapter() { 

       @Override 
       public void mousePressed(MouseEvent e) { 
        panel.dispatchEvent(e); 
        e.consume(); 
       } 
      }); 
     } 
     String text = (String) value; 
     label.setText(text); 
     if(text == null) 
      button.setIcon(null); 
     else if(button.getIcon() == null) 
      button.setIcon(icon); 
     panel.setBackground(isSelected ? Color.red : Color.white); 
     panel.setForeground(isSelected ? Color.white : Color.black); 
     return panel; 
    } 
} 

khuyến nghị cuối cùng của tôi và cách tôi sẽ làm điều đó là: BUILD COMPONENT RIÊNG BẠN. Làm cho nó có thể mở rộng và sửa đổi bằng cách tách nó khỏi trình kích hoạt và bản trình bày, trong đó cả hai sử dụng JComponent khi chúng phản đối việc sử dụng trình kết xuất đồ họa. Bằng cách này, bạn sẽ có thể nắm bắt và phân phát sự kiện trên các thành phần thay vì trong trường hợp này tất cả các sự kiện được chụp bởi JList được sử dụng để hiển thị.

Dưới đây là mẫu sẽ giúp bạn bắt đầu. Nó không phải là giải pháp cuối cùng nhưng nó trình bày rất nhiều vấn đề quan trọng liên quan đến việc tạo ra thành phần như vậy. Bạn nên sử dụng chức năng được trình bày và bao bọc tất cả tương ứng trong một thành phần:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import javax.swing.*; 

public class MockJComboBox { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       final JPanel popupContent = new JPanel(new GridLayout(0, 1)); 
       popupContent.setBackground(Color.GREEN); 
       popupContent.add(new JLabel("Content of popupContent panel")); 
       popupContent.add(new JLabel("Content of popupContent panel")); 
       popupContent.add(new JLabel("Content of popupContent panel")); 
       popupContent.add(new JLabel("Content of popupContent panel")); 
       popupContent.add(new JLabel("Content of popupContent panel")); 
       popupContent.add(new JComboBox(new Object[]{"Content of popupContent panel"})); 
       final JButton popupCloseButton = new JButton("X"); 
       popupContent.add(popupCloseButton); 

       final JScrollPane s = new JScrollPane(popupContent); 
       s.setPreferredSize(new Dimension(popupContent.getPreferredSize().width + s.getVerticalScrollBar().getPreferredSize().width 
         + s.getBorder().getBorderInsets(s).left 
         + s.getBorder().getBorderInsets(s).right, 100)); 

       JPanel panel = new JPanel(); 
       panel.setPreferredSize(new Dimension(200, 200)); 
       final JButton popupOpenButton = new JButton(); 
       panel.add(popupOpenButton); 
       final JFrame f = new JFrame(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.setContentPane(panel); 
       final PopupFactory popupFactory = PopupFactory.getSharedInstance(); 
       popupOpenButton.setAction(new AbstractAction("Open") { 
        private Popup popup; 
        private boolean isShown = false; 

        @Override 
        public void actionPerformed(ActionEvent e) { 
         if (isShown) { 
          popup.hide(); 
         } else { 
          popup = popupFactory.getPopup(popupOpenButton, s, 
            popupOpenButton.getLocationOnScreen().x, popupOpenButton.getLocationOnScreen().y + popupOpenButton.getHeight()); 
          popupCloseButton.setAction(new AbstractAction(popupCloseButton.getText()) { 

           @Override 
           public void actionPerformed(ActionEvent e) { 
            isShown = false; 
            popup.hide(); 
           } 
          }); 
          popup.show(); 
         } 
         isShown = !isShown; 
        } 
       }); 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 
+1

+1, câu trả lời tuyệt vời, cảm ơn! – berry120

Các vấn đề liên quan