Look & Feel

illaX

Erfahrenes Mitglied
Hi,

ich habe eine JComboBox, diese enthaelt alle Namen von den unterstuetzten Look & Feels.

Wenn ich jetzt das Look & Feel auf Windows umstelle verschwindet der Text in der ComboBox. Weiss jemand woran das liegt?

Bei allen anderen L&F funktioniert es ohne Probleme, nur bei Windows verschwindet der Text von der ComboBox.

Danke fuer Hilfe
 
Ich habe den Fehler ein wenig eingraenzen koennen. Er entsteht bei meinem Renderer.

Code:
public class LookAndFeelRenderer extends JLabel implements ListCellRenderer {

    public LookAndFeelRenderer() {
        super();
    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        
        LookAndFeelInfo info = (LookAndFeelInfo) value;
        
        setText(info.getName());
        
        return this;
    }
}

Wenn ich nun das Windows L&F aktiviert habe wird der Text nicht mehr dargestellt. Wenn ich jetzt aber eine andere Componente erweiter, zB TextField oder Button funktioniert es.
 
Habe das Problem umgangen. Habe von der Klasse LookAndFeelInfo die toString() Methode ueberschrieben und den Renderer geloescht. Bin zwar nicht so zufrieden damit, aber mit solchem mysterioesem Verhalten muss ich wohl leben :D
 
Hallo illaX,

der Thread ist zwar bissel alt, ich schreib trotzdem ein Paar Worte dazu :) .

Wollte auch immer schon während der Laufzeit meiner Programme das Look and Feel ändern können. Dank deiner Inspiration hab ich wie du ein Beispiel mit einer JComboBox mit den verschiedenen Look and Feels implementiert. Wenns dich noch interessiert, bei meinem Beispiel verschwinden keine Comboeinträge:

Java:
import java.awt.BorderLayout;

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class LNFExample extends JFrame {

	private String[] lnfs = { "javax.swing.plaf.metal.MetalLookAndFeel",
			"com.sun.java.swing.plaf.windows.WindowsLookAndFeel",
			"com.sun.java.swing.plaf.motif.MotifLookAndFeel" };

	private JComboBox combo = new JComboBox(lnfs);

	public LNFExample() {
		super("Example");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setAlwaysOnTop(true);
		this.setLocationByPlatform(true);
		this.setSize(320, 480);

		combo.addPopupMenuListener(new PopupMenuListener() {
			public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
			}

			public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
				changeLF(combo.getSelectedItem().toString());
			}

			public void popupMenuCanceled(PopupMenuEvent e) {
			}
		});

		this.add(combo, BorderLayout.NORTH);
		this.add(new JScrollPane(new JTextArea(
				"Try the various look and feels of Swing!")),
				BorderLayout.CENTER);
		this.add(new JButton("JButton"), BorderLayout.SOUTH);
		this.add(new JLabel("JLabel"), BorderLayout.WEST);
		this.add(new JSlider(JSlider.VERTICAL), BorderLayout.EAST);

		this.setVisible(true);
	}

	public void changeLF(String lnfName) {
		try {
			UIManager.setLookAndFeel(lnfName);
		} catch (Exception e) {
		}
		SwingUtilities.updateComponentTreeUI(this);
	}

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


Vg Erdal
 
Bei dir steht aber in der ComboBox javax.swing......L&F?

Genau dies wollte ich nicht und habe deswegene meinen eigenen Renderer geschrieben um den String zu formatieren und dabei ist dann dieser Bug entstanden.
 
Asoo!

ein zweiter Versuch:

Java:
import java.awt.BorderLayout;

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class LNFExample extends JFrame {

	private String[] lnfs = { "javax.swing.plaf.metal.MetalLookAndFeel",
			"com.sun.java.swing.plaf.windows.WindowsLookAndFeel",
			"com.sun.java.swing.plaf.motif.MotifLookAndFeel" };

	private String[] lnfs2 = { "MetalLookAndFeel", "WindowsLookAndFeel",
			"MotifLookAndFeel" };

	private JComboBox combo = new JComboBox(lnfs2);

	public LNFExample() {
		super("Example");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setAlwaysOnTop(true);
		this.setLocationByPlatform(true);
		this.setSize(320, 480);

		combo.addPopupMenuListener(new PopupMenuListener() {
			public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
			}

			public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
				changeLF(lnfs[combo.getSelectedIndex()]);
			}

			public void popupMenuCanceled(PopupMenuEvent e) {
			}
		});

		this.add(combo, BorderLayout.NORTH);
		this.add(new JScrollPane(new JTextArea(
				"Try the various look and feels for Swing!")),
				BorderLayout.CENTER);
		this.add(new JButton("JButton"), BorderLayout.SOUTH);
		this.add(new JLabel("JLabel"), BorderLayout.WEST);
		this.add(new JSlider(JSlider.VERTICAL), BorderLayout.EAST);

		this.setVisible(true);
	}

	public void changeLF(String lnfName) {
		try {
			UIManager.setLookAndFeel(lnfName);
		} catch (Exception e) {
		}
		SwingUtilities.updateComponentTreeUI(this);
	}

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


Vg Erdal
 
Das ist ein schoener Trick, allerdings beziehe ich vorher die installierten L&Fs (soll ja flexibel und ueberall lauffaehig sein).

Alos muesste man den lnfs array fuellen, die Inhalte pattern und alles nach dem letzten Punkt in den anderen array fuellen.

Ich habe es so gemacht:
Code:
private LookAndFeelInfo[] info = null;
private MyLookAndFeelInfo[] lookAndFeelModel = null;
.
.
.

info = UIManager.getInstalledLookAndFeels();
        lookAndFeelModel = new MyLookAndFeelInfo[info.length];
        
        // convert LookAndFeelInfo in MyLookAndFeelInfo
        for(int i = 0; i < info.length; i++) {
            LookAndFeelInfo feel = info[i];
            lookAndFeelModel[i] = new MyLookAndFeelInfo(feel.getName(), 
                    feel.getClassName());
        }

        cbLookAndFeel = new JComboBox(lookAndFeelModel);
        cbLookAndFeel.addItemListener(new DataChangeController(this));

und mein Listener:
Code:
public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            LookAndFeelInfo look = (LookAndFeelInfo) e.getItem();
            try {
                UIManager.setLookAndFeel(look.getClassName());
                SwingUtilities.updateComponentTreeUI(MainPanel.getInstance()
                        .getApplet());
                SwingUtilities.updateComponentTreeUI(dialog);
            } catch (ClassNotFoundException e1) {
                e1.printStackTrace();
            } catch (InstantiationException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            } catch (UnsupportedLookAndFeelException e1) {
                e1.printStackTrace();
            }
        }
    }

Finde ich ein wenig sicherer als mit 2 Arrays rumzuhantieren
 
Zuletzt bearbeitet:
Hallo illaX,

stimmt es seien nicht alle LookandFeels überall verfügbar. Da ich bisher nur auf Windows gearbeitet habe, hab ich daran nicht gedacht. D.h. du holst dir die verfügbaren LNFs über den UIManager und füllst die ComboBox entsprechend.

Danke für die Idee. Werd demnächst meine Proggis mit einem LNFChooser ausstatten.

Vg Erdal
 
Jops ich werde das ab sofort auch machen :D

Es gibt auch mit Sicherheit eine bessere Moeglichkeit als meine, aber mir ist keine eingefallen :D
 
Hallo illaX,

da wir jetzt schon beim Thema LNFs sind. Gibt es eigentlich verschiedene DefaultThemes von Sun. Die Klasse MetalLookandFeel hat folgende Methode: setCurrentTheme() .


Vg Erdal
 
Zurück