JComboBox: Dropdownmenü aussehen ändern

Larrywayn

Mitglied
Hallo zum erstenmal.

Bei dem Zusammenbasteln meines GUI's gab es bisher keine Probleme, bzw. konnte ich alle Fragen durch Google oder durch passives mitlesen lösen.
Doch diese JComboBox scheint etwas ganz spezielles zu sein, so dass guter Rat teuer ist.
2 Probleme beschäftigen mich nun konkret:

1. In Bezug auf dieses Postings: http://www.tutorials.de/forum/1469335-post1.html (Ich wusste nicht ob ich es "pushen" hätte sollen?). Genau diese Frage quält mich schon seit Stunden. Dieser Rahmen, wo kommt er her? Weder in der abgeleiteten ComboBox, dem eigenen ComboBoxModel noch im eigenen ListCellRenderer, konnte ich eine Möglichkeit finden ihn zu deaktivieren. Selbst das testweise Überschreiben, der paint-Methoden, hat kein Erfolg gebracht. Hinweise würden mir schon reichen.

2. Wie schon erwähnte, habe ich eine eigene JComboBox Klasse. In dieser überschreibe ich die paint-Methode, damit ich eine halbtransparente ComboBox bekomme. Außerdem setze ich setOpaque() auf false. Jetzt möchte ich das Dropdownmenü auch anpassen. Deshalb hab ich auch brav einen ListCellRenderer implementiert, welcher JLabel extended. Mit diesem bekomme ich natürlich die einzelnen Listeneinträge und kann ihren Text, ihren Hintergrund und ihre Schriftfarbe setzen, auch transparenter Hintergrund, per Color(xxx, xxx, xxx, 128), funktioniert. Sofern man auf die JComboBox setBackground() aufruft, mit dem Parameter Color(0, 0, 0, 0). Sieht auch alles genauso aus wie gewollt, jedoch kann man es nicht wirklich benutzen. Wenn die Maus über die einzelnen Elemente fährt, ändern sich die Farben. Sie addieren (multiplizieren? Irgendwie so) sich, so dass es immer undurchsichtiger wird, bzw. sich der Hintergrund nicht zurück ändert.
jcombobox.jpg

Es sieht aus, als ob ein repaint() irgendwo fehlen würde, bzw. ein fireEvent, welches anzeigt, dass sich etwas geändert hat.
Spontan würde ich die Komponente, welche getListCellRendererComponent() aufruft, dafür verantwortlich machen. Nur ich habe absiolut keine Ahnung mehr. Diese JComboBox mit ihren ganzen Ableitungen und setOpaque() ist mir gerade zu undurchsichtig.

Wäre echt Klasse, wenn ihr mir Tips oder Ideen geben könntet, wie ihr an die Sache rangehen würdet. Wenn einer natürlich weiß, wie es geht, wäre es noch praktischer.
Danke schonmal.

Sascha ^^
 
Es hat sich einiges ergeben von daher wollte ich meine Ergebnisse mitteilen.

Problem 1 ist nun gelößt. Um den Rahmen zu entfernen muss man ein eigenes UI für die ComboBox schreiben, indem man von ComboBoxUI ableitet.
Dann muss man nur noch die protected Methode createPopup()
überschreiben und am besten folgendes machen:
Java:
protected ComboPopup createPopup()
	{
		BasicComboPopup popup = new BasicComboPopup(this.comboBox);
		popup.setBorder(BorderFactory.createEmptyBorder());
		popup.getAccessibleContext().setAccessibleParent(this.comboBox);
		return popup;
	}
Wenn man die Größe auch anpassen möchte, kann man noch die show() Methode vom BasicComboPopup überschreiben.

Das 2 Problem besteht weiterhin.
Ich hab zwar nun das Popup gefunden und auch die paint() Methode überschrieben, aber das bringt nur teilweise etwas. Ich kann das Popupmenü nun gänzlich selber gestalten, aber erstmal nur das beim Ausklappen. Sobald man mit der Maus darüber geht, wird die paint() Methode des ListCellRenderes aufgerufen. Gut hab ich diese eben auch überschrieben und angepasst.
Jedoch kann ich machen, was ich möchte, der Effekt vom Bild oben besteht einfach weiterhin. Die Farben und der Alphakanal addieren sich.
Wenn ich es zu und wieder aufklappe, sieht es wieder normal aus.
Wenn jemand vielleicht mal etwas Ähnliches hatte, egal in welcher Situation, wäre mir auch schon geholfen.

Mfg Sascha o.o
 
Zuletzt bearbeitet:
So Problem Nummer 2 hab ich nun auch hinbekommen.
Falls es jemanden interessiert:
Java:
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

public class ComboBoxCustomListCellRenderer extends JLabel implements ListCellRenderer 
{
	private static final long serialVersionUID = 1L; 
	protected boolean isSelected;
	protected JFrame jf;
	public ComboBoxCustomListCellRenderer(JFrame jf) 
	{
		this.jf = jf;
		isSelected = false;
	}

	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
	{	
		if (isSelected) 
		{
			this.isSelected = true;
			setForeground(list.getSelectionForeground());
		} 
		else 
		{
			this.isSelected = false;
			setForeground(list.getForeground());
		}
		setText(value.toString());
		return this;
	}

	public void paint(Graphics g)
	{
		if(isSelected)
		{
			isSelected = false;
			g.setColor(new Color(0,255,0,128));
		}
		else
		{
			g.setColor(new Color(255,0,0,128));
		}
		FontMetrics f = g.getFontMetrics();
		String s = this.getText();
		g.fillRect(0, 0, getWidth(), f.getHeight()+f.getAscent());
		g.setColor(new Color(0,0,255));
		if(( f.stringWidth(s)- getWidth()) >= 0)
		{
			g.drawString( s.substring(0, (int)(f.getMaxAdvance()-3))+"...", 0, f.getHeight());
		}
		else
		{
			g.drawString( s, 0, f.getHeight());
		}
		jf.repaint();
	}
}
Ist zwar unschön mit der Übergabe des JFrames, aber nur so konnt ich das repaint erwzingen, so dass sich die Farben nicht überlagern.
Wenn es eine hübschere Lösung gibt, bin ich aber gerne noch offen diese zu hören ^^
Mfg larrywayn
 
Zuletzt bearbeitet von einem Moderator:
Zurück