Свойства пользовательского интерфейса не содержат некоторых ключей

У меня следующая проблема. Мне нужно получить свойства пользовательского интерфейса:

UIManager.getString("OptionPane.okButtonText")

который возвращает строку "OK", и это работает. Однако, если я перебираю набор ключей UIDefaults, я никогда не получаю ключ "OptionPane.okButtonText". Кто-нибудь знает, почему это происходит? Я получаю UIDefaults тремя разными способами (UIManager.getDefaults(), UIManager.getLookAndFeel().getDefaults() и UIManager.getLookAndFeelDefaults()), но ни один из них не работает.

Изменить: я также нашел этот список свойств класса JFileChooser, который содержит некоторые свойства, которых нет в наборе ключей UIDefaults. Проблема в том, как программно получить все эти свойства?

Изменить: пример кода:

UIDefaults defaults = UIManager.getDefaults();
String thekey = "OptionPane.okButtonText";
System.out.println(thekey + ": " + UIManager.getString(thekey));
for (Enumeration e = defaults.keys(); e.hasMoreElements();) {
    Object key = e.nextElement();
    System.out.println(key + ": " + defaults.get(key));
}

этот код возвращает печать этих свойств. Ключ "OptionPane.okButtonText" не появляется в выводе.


person Alberto    schedule 20.04.2011    source источник
comment
что-то не так в вашем коде? - работает на меня   -  person kleopatra    schedule 20.04.2011
comment
См. Настройки UIManager по умолчанию   -  person trashgod    schedule 20.04.2011
comment
Добавляю код. @trashgod Я получаю код с этого сайта :)   -  person Alberto    schedule 20.04.2011
comment
Вы делаете что-то необычное (что бы это ни значило ;-) по сравнению с локалью по умолчанию в вашей системе? Например, иметь итальянский по умолчанию и пытаться получить доступ к английской версии?   -  person kleopatra    schedule 20.04.2011
comment
ааа - только что заметил повторение набора ключей: не имеет смысла, они хранятся не там, см. разъяснение в моем ответе (и игнорируйте мой последний комментарий здесь ;-)   -  person kleopatra    schedule 20.04.2011


Ответы (2)


Это может быть проблемой с resourceBundles: текстовые свойства optionPane (а также f.i. fileChooser и другие) загружаются из локализованных пакетов. Они (раньше были, не совсем уверен, что это все еще так) внутренние классы в com.sun.swing.internal.plaf. Может там что-то не так...

вот фрагмент, который работает:

    String ok = "OptionPane.okButtonText";
    String text = ""; 
    text += " LAF: " + UIManager.getLookAndFeelDefaults().get(ok);
    text += " lookup: " + UIManager.get(ok);
    text += " default: " + UIManager.getDefaults().get(ok);
    System.out.println(text);

    // output, whereever I add that:
     LAF: OK lookup: OK default: OK

независимо от того, какой LAF установлен в данный момент. Моя система Win/Vista, моя локаль по умолчанию de

Изменить: просто для уточнения - локализованные ресурсы не обязательно являются прямыми записями в keys()/entrySet(), это методы в Hashtable, которые не переопределяются в UIDefaults. Таким образом, хотя поиск, как в моем фрагменте, всегда должен работать, запрос перечислений неверен - записи не там, а в некоторых кэшированных картах, которые подаются из resourceBundles.

Edit2: добавлено определение ok (думал, что это будет ... очевидно после нескольких часов разговора об этом ключе :-)

Edit3: для дальнейших экспериментов нам, вероятно, следует искать значение, которое отличается больше, чем «ОК» в разных локалях, т.е. отменаButtonText

Редактировать 4 (самый последний перед большим перерывом, обещанный :-) - поскольку «как найти все локализованные значения» невозможно, не прибегая к грязным средствам (также известным как детали реализации). Единственный способ, который я могу придумать, - это заглянуть в ResourceBundles, которые - предположительно - загружены, например

    import com.sun.swing.internal.plaf.basic.resources.basic;

    String cancel = "OptionPane.cancelButtonText";
    ListResourceBundle bundle = new basic();
    for (String key : bundle.keySet()) {
        if(cancel.equals(key)) {
            System.out.println(key
                    + ": " + bundle.getString(key));

        }
    }
person kleopatra    schedule 20.04.2011
comment
Спасибо за разъяснения. Я думаю, что ваш анализ верен, но у меня нет голосов. Локализованные ресурсы не отображаются в entrySet() из UIDefaults . - person trashgod; 20.04.2011
comment
Это именно то, что я искал! Большое спасибо за все ответы! - person Alberto; 22.04.2011

Похоже, что OptionPane.okButtonText — это функция, уникальная для Aqua, доступная во всех L&F, как показано с использованием этого подхода, который включает локализованные значения, не видимые при переборе entrySet().

import javax.swing.UIDefaults;
import javax.swing.UIManager;

/** @see https://stackoverflow.com/questions/5729306 */
public class OptionPaneDefaults {

    public static void main(String[] args) throws Exception {
        UIManager.LookAndFeelInfo[] lfa =
            UIManager.getInstalledLookAndFeels();
        for (UIManager.LookAndFeelInfo lf : lfa) {
            UIManager.setLookAndFeel(lf.getClassName());
            UIDefaults uid = UIManager.getLookAndFeelDefaults();
            System.out.println("***"
                + " " + lf.getName()
                + " " + lf.getClassName()
                + " " + uid.size() + " entries");
            String ok = "OptionPane.okButtonText";
            String text = "";
            text += " LAF: " + UIManager.getLookAndFeelDefaults().get(ok);
            text += " lookup: " + UIManager.get(ok);
            text += " default: " + UIManager.getDefaults().get(ok);
            System.out.println(text);
        }
    }
}

Консоль, Mac OS X:

*** Metal javax.swing.plaf.metal.MetalLookAndFeel 636 entries
 LAF: OK lookup: OK default: OK
*** Nimbus com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel 1054 entries
 LAF: OK lookup: OK default: OK
*** CDE/Motif com.sun.java.swing.plaf.motif.MotifLookAndFeel 550 entries
 LAF: OK lookup: OK default: OK
*** Mac OS X com.apple.laf.AquaLookAndFeel 711 entries
 LAF: OK lookup: OK default: OK

Консоль, Windows 7:

*** Metal javax.swing.plaf.metal.MetalLookAndFeel 636 entries
 LAF: OK lookup: OK default: OK
*** Nimbus com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel 1049 entries
 LAF: OK lookup: OK default: OK
*** CDE/Motif com.sun.java.swing.plaf.motif.MotifLookAndFeel 550 entries
 LAF: OK lookup: OK default: OK
*** Windows com.sun.java.swing.plaf.windows.WindowsLookAndFeel 637 entries
 LAF: OK lookup: OK default: OK
*** Windows Classic com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel 637 entries
 LAF: OK lookup: OK default: OK
person trashgod    schedule 20.04.2011
comment
Но я попробовал это в Windows 7 с системным L&F, и если я получаю свойство с помощью метода getString, он работает нормально. Проблема в том, чтобы получить все ключи. Я думаю, что мы должны получить весь разнообразный пользовательский интерфейс ComponentClass и ключи таким образом, но как? - person Alberto; 20.04.2011
comment
@alberto: я не вижу записи для OptionPane.okButtonText в Windows 7; результаты добавлены выше. - person trashgod; 20.04.2011
comment
нет особого смысла перебирать записи, см. разъяснение (надеюсь :-) моего ответа - person kleopatra; 20.04.2011
comment
@kleopatra: Ага, кажется, теперь я понимаю; Я обновил этот ответ, чтобы отразить мои результаты для Windows 7 и Mac OS X с использованием вашего подхода. - person trashgod; 20.04.2011