Frage

Ich habe eine JComboBox und möchte einen Separator in der Liste der Elemente haben. Wie mache ich das in Java?

Ein Beispielszenario, wo dies würde sich als nützlich ist, wenn sie ein Combobox für font-family-Auswahl; ähnlich wie die font-family-Auswahl-Kontrolle in Word und Excel. In diesem Fall würde Ich mag das meistverwendeten-Fonts an der Spitze zeigen, dann einem Separator und schließlich alle Schriftfamilien unter dem Separator in alphabetischer Reihenfolge.

Kann mir jemand helfen mit, wie dies zu tun, oder ist dies nicht möglich in Java?

War es hilfreich?

Lösung

Es ist ein ziemlich kurzes Tutorial mit einem Beispiel, das zeigt, wie eine benutzerdefinierte ListCellRenderer auf java2s verwenden   http://www.java2s.com/Code/Java/Swing-Components /BlockComboBoxExample.htm

Im Grunde geht es um eine bekannte Platzhalter in der Liste Modell einfügen und wenn Sie den Platzhalter in den ListCellRenderer erkennen zurückkehren Sie eine Instanz von "neuem JSeparator (JSeparator.HORIZONTAL)

Andere Tipps

Als ich schrieb und den Code unten getestet, haben Sie sich wahrscheinlich viel bessere Antworten ...
Ich habe nichts dagegen, als ich das Experiment genossen / Lernen (immer noch ein bisschen grün auf der Schaukel vorne).

[EDIT] Drei Jahre später, ich bin ein bisschen weniger grün, und ich nahm Konto in den gültigen Äußerungen bobndrew. Ich habe kein Problem mit der Schlüssel-Navigation, die nur funktioniert (vielleicht ist es ein JVM-Version Problem war?). Ich verbessert den Renderer Highlight zu zeigen, though. Und ich benutze einen besseren Demo-Code. Die akzeptierte Antwort ist wahrscheinlich besser (Standard), ich ist wahrscheinlich flexibler, wenn Sie eine benutzerdefinierte Trenn wollen ...

Die Grundidee ist ein Renderer für die Elemente des Kombinationsfelds zu verwenden. Für die meisten ist es ein einfaches JLabel mit dem Text des Artikels. Für die letzten letzten / am häufigsten verwendeten Artikeln, dekoriere ich die JLabel mit einem benutzerdefinierten Rahmen eine Linie auf seinem Boden zu ziehen.

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


@SuppressWarnings("serial")
public class TwoPartsComboBox extends JComboBox
{
  private int m_lastFirstPartIndex;

  public TwoPartsComboBox(String[] itemsFirstPart, String[] itemsSecondPart)
  {
    super(itemsFirstPart);
    m_lastFirstPartIndex = itemsFirstPart.length - 1;
    for (int i = 0; i < itemsSecondPart.length; i++)
    {
      insertItemAt(itemsSecondPart[i], i);
    }

    setRenderer(new JLRenderer());
  }

  protected class JLRenderer extends JLabel implements ListCellRenderer
  {
    private JLabel m_lastFirstPart;

    public JLRenderer()
    {
      m_lastFirstPart = new JLabel();
      m_lastFirstPart.setBorder(new BottomLineBorder());
//      m_lastFirstPart.setBorder(new BottomLineBorder(10, Color.BLUE));
    }

    @Override
    public Component getListCellRendererComponent(
        JList list,
        Object value,
        int index,
        boolean isSelected,
        boolean cellHasFocus)
    {
      if (value == null)
      {
        value = "Select an option";
      }
      JLabel label = this;
      if (index == m_lastFirstPartIndex)
      {
        label = m_lastFirstPart;
      }
      label.setText(value.toString());
      label.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
      label.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
      label.setOpaque(true);

      return label;
    }
  }
}

Separator Klasse kann dick sein, mit benutzerdefinierter Farbe, etc.

import java.awt.*;
import javax.swing.border.AbstractBorder;

/**
 * Draws a line at the bottom only.
 * Useful for making a separator in combo box, for example.
 */
@SuppressWarnings("serial")
class BottomLineBorder extends AbstractBorder
{
  private int m_thickness;
  private Color m_color;

  BottomLineBorder()
  {
    this(1, Color.BLACK);
  }

  BottomLineBorder(Color color)
  {
    this(1, color);
  }

  BottomLineBorder(int thickness, Color color)
  {
    m_thickness = thickness;
    m_color = color;
  }

  @Override
  public void paintBorder(Component c, Graphics g,
      int x, int y, int width, int height)
  {
    Graphics copy = g.create();
    if (copy != null)
    {
      try
      {
        copy.translate(x, y);
        copy.setColor(m_color);
        copy.fillRect(0, height - m_thickness, width - 1, height - 1);
      }
      finally
      {
        copy.dispose();
      }
    }
  }

  @Override
  public boolean isBorderOpaque()
  {
    return true;
  }
  @Override
  public Insets getBorderInsets(Component c)
  {
    return new Insets(0, 0, m_thickness, 0);
  }
  @Override
  public Insets getBorderInsets(Component c, Insets i)
  {
    i.left = i.top = i.right = 0;
    i.bottom = m_thickness;
    return i;
  }
}

Test-Klasse:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


@SuppressWarnings("serial")
public class TwoPartsComboBoxDemo extends JFrame
{
  private TwoPartsComboBox m_combo;

  public TwoPartsComboBoxDemo()
  {
    Container cont = getContentPane();
    cont.setLayout(new FlowLayout());

    cont.add(new JLabel("Data: ")) ;

    String[] itemsRecent = new String[] { "ichi", "ni", "san" };
    String[] itemsOther = new String[] { "one", "two", "three" };
    m_combo = new TwoPartsComboBox(itemsRecent, itemsOther);

    m_combo.setSelectedIndex(-1);
    cont.add(m_combo);
    m_combo.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent ae)
      {
        String si = (String) m_combo.getSelectedItem();
        System.out.println(si == null ? "No item selected" : si.toString());
      }
    });

    // Reference, to check we have similar behavior to standard combo
    JComboBox combo = new JComboBox(itemsRecent);
    cont.add(combo);
  }

  /**
   * Start the demo.
   *
   * @param args   the command line arguments
   */
  public static void main(String[] args)
  {
    // turn bold fonts off in metal
    UIManager.put("swing.boldMetal", Boolean.FALSE);

    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        JFrame demoFrame = new TwoPartsComboBoxDemo();
        demoFrame.setTitle("Test GUI");
        demoFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        demoFrame.setSize(400, 100);
        demoFrame.setVisible(true);
      }
    });
  }
}

Sie können eine benutzerdefinierte ListCellRenderer verwenden, die die Trennzeichenposten unterschiedlich ziehen würde. Siehe docs und eine kleine Tutorial .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top