2012-06-16 18 views
6

Attualmente ho un JComboBox che sto usando come playlist audio - quello che mi piacerebbe ottenere è un piccolo pulsante "Rimuovi" sul lato destro di ogni oggetto che posso usare per rimuoverlo dal modello sottostante, dove si trova il cerchio:Pulsanti di visualizzazione negli elementi JComboBox

Quale sarebbe il modo migliore per raggiungere questo obiettivo?

Mi piacerebbe che il pulsante fosse lo stesso per tutti gli elementi in JComboBox.

demo screenshot

+0

sono volete '1)' messo JLabel e con JButton a quella voce, '2)' per tutte le voci del JComboBox o no – mKorbel

+0

@mKorbel Non sei sicuro di cosa intendi per il tuo primo punto? Ma per il secondo punto, sì. – berry120

+0

vedo un problema importante, JComboBox drop_down si spegne dopo ogni Mouse_click all'elemento (Java1.4 e versioni successive), sei d'accordo e accettando che – mKorbel

risposta

8

Vorrei iniziare dicendo che questa è una domanda interessante (+1 qualche tempo fa).

Ho dovuto provare rapidamente e vedere di persona quanto sia difficile ottenere il risultato desiderato con JComboBox. La conclusione che ho ottenuto (come dice @trashgod nel commento sopra) era che questo oggetto non è mai stato progettato per avere altri componenti o almeno mi sembra così.

Di seguito è un esempio che fa qualcosa che vuoi. Potresti usarlo come principio, ma per essere onesti dovresti dimenticarti di usare lo JComboBox per questo problema.

Per nessun motivo il seguente esempio presenta il modo corretto di affrontare il problema. Mostra semplicemente il risultato dei miei tentativi di affrontare il problema. Il codice seguente non conserva le regole di buona pratica, ad es. mescola la presentazione con la funzionalità (il renderer rimuove gli elementi). Questo è in realtà solo un hack non una soluzione reale.

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

mia raccomandazione finale e il modo in cui lo farei è: costruire il vostro COMPONENTE PROPRIO. Rendilo estensibile e modificabile separandolo dal trigger e dalla presentazione, in cui entrambi utilizzano JComponent mentre si oppongono all'uso di un renderer. In questo modo sarai in grado di acquisire e servire eventi sui componenti anziché come in questo caso tutti gli eventi vengono catturati dallo JList utilizzato per il rendering.

Di seguito è un esempio che dovrebbe aiutare l'avvio. Non è la soluzione finale ma presenta molte importanti questioni relative alla realizzazione di tale componente. Si consiglia di utilizzare la funzionalità presentato e avvolgere il tutto di conseguenza in un unico componente:

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, ottima risposta, grazie! – berry120

Problemi correlati