Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałZygmunt Domian Został zmieniony 11 lat temu
1
Plan wykładu i18n o kontekście w aplikacji z GUI narzędzia ułatwiające życie: JOptionPane Swing i wielowątkowość użycie klasy SwingUtilities użycie klasy SwingWorker inne sposoby ( FoxTrot )
2
Internationalization (i18n) Co to jest i18n? dopasowanie aplikacji do konkretnego regionu i języka sposób wyświetlania dat, numerów kierunek i czcionka użyta do wyświetlania tekstu język napisów w aplikacji sposób ułożenia komponentów w GUI operacje na tekście (porównania, detekcja słów) Po co i18n? łatwość wprowadzania zmian, nawet gdy aplikacja jest przeznaczona na jeden rynek łatwość zarządzania zasobami
3
i18n – jak wykryć język? java.util.Locale.getDefault() Locale.getAvailableLocales() new Locale(lang, ctry, varnt) obiekt Locale = język + kraj + wariant http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
4
Przykład – skrypt w BeanShellu Locale [] locales = Locale.getAvailableLocales(); for (int i=0;i<locales.length;i++) { System.out.println( "Name: " + locales[i].getDisplayName() + ", language: " + locales[i].getDisplayLanguage() + ", country: " + locales[i].getDisplayCountry() + ", variant: " + locales[i].getDisplayVariant() ); } Name: niemiecki, language: niemiecki, country:, variant:, iso: deu_ Name: niemiecki (Austria), language: niemiecki, country: Austria, variant:, iso: deu_AUT Name: niemiecki (Austria,Euro), language: niemiecki, country: Austria, variant: Euro, iso: deu_AUT Name: niemiecki (Szwajcaria), language: niemiecki, country: Szwajcaria, variant:, iso: deu_CHE Name: niemiecki (Niemcy), language: niemiecki, country: Niemcy, variant:, iso: deu_DEU Name: niemiecki (Niemcy,Euro), language: niemiecki, country: Niemcy, variant: Euro, iso: deu_DEU Name: niemiecki (Luksemburg), language: niemiecki, country: Luksemburg, variant:, iso: deu_LUX Name: niemiecki (Luksemburg,Euro), language: niemiecki, country: Luksemburg, variant: Euro, iso: deu_LUX
5
i18n – formatowanie napisów java.text. MessageFormat(format, locale) Czym jest pole format? tekst i pola specjalne: liczby, daty, czas, waluta… Sposób wykorzystania: wywołanie metody format(Object [] args) Time: {0,time}, Date: {0,date}, Number: {1,number}, Number (formatted): {1, number, #.0}, Currency: {2, number, currency}.
6
i18n – formatowanie napisów import java.text.MessageFormat; Locale [] locales = Locale.getAvailableLocales(); Object [] arguments = new Object [] { new Date( System.currentTimeMillis() ), new Double(12003.1415), new Integer(10023), }; out = new PrintWriter(new OutputStreamWriter(System.out, "UTF-8")); for (int i=0;i<locales.length;i++) { MessageFormat mformat = new MessageFormat("Time: {0,time}, Date: {0,date}, Number: {1,number}, " + "Number (formatted): {1, number, #.0}, + "Currency: {2, number, currency}.", locales[i]); String result = mformat.format(arguments); out.println("locale: " + locales[i].getISO3Language() + "_" + locales[i].getISO3Country() + " result: " + result ); }
7
i18n – formatowanie liczb locale: ara_BHR result: Time: 09:37:20 ص, Date: 29/10/2003, Number: 12,003.142, Number (formatted): 12003.1, Currency: د. ب. 10,023. locale: ara_DZA result: Time: 09:37:20 ص, Date: 29/10/2003, Number: 12,003.142, Number (formatted): 12003.1, Currency: د. ج. 10,023. locale: eng_CAN result: Time: 9:37:20 AM, Date: 29-Oct-2003, Number: 12,003.142, Number (formatted): 12003.1, Currency: $10,023.00. locale: eng_GBR result: Time: 09:37:20, Date: 29-Oct-2003, Number: 12,003.142, Number (formatted): 12003.1, Currency: £10,023.00. locale: jpn_JPN result: Time: 9:37:20, Date: 2003/10/29, Number: 12,003.142, Number (formatted): 12003.1, Currency: 10,023. locale: pol_ result: Time: 09:37:20, Date: 2003-10-29, Number: 12 003,142, Number (formatted): 12003,1, Currency: ¤ 10 023,00. locale: pol_POL result: Time: 09:37:20, Date: 2003-10-29, Number: 12 003,142, Number (formatted): 12003,1, Currency: 10 023 zł.
8
Zasoby tekstowe i i18n Klasa ResourceBundle Metoda getString(String key) np. getString("ok.string") Metoda getBundle(String baseName, Locale locale, ClassLoader loader) Jak tworzona jest instancja ResourceBundle? candidate bundle names baseName_language_country_variant baseName_language_country baseName_language baseName_defaultLanguage_defaultCountry_defaultVariant … Poszukiwana klasa o nazwie takiej, jak kandydat Jeśli nie znaleziono, używany jest PropertyResourceBundle
9
Przykład – resource bundles Default: Słój pełen pysznych ciastek. UK: A jar full of yummy biscuits Chinese: A jar full of yummy cookies // default resource bundle... ResourceBundle bundle1 = ResourceBundle.getBundle("napisy", Locale.getDefault()); // get specific resource bundle (British English) ResourceBundle bundle2 = ResourceBundle.getBundle("napisy", Locale.UK); // get specific resource bundle (chinese) - example // of fallback action if resource does not exist. ResourceBundle bundle3 = ResourceBundle.getBundle("napisy", Locale.ENGLISH); key = "sloj.pelen.pysznych.ciach"; System.out.println("Default: " + bundle1.getString(key)); System.out.println("UK: " + bundle2.getString(key)); System.out.println("Chinese: " + bundle3.getString(key));
10
Przykład – resource bundles (2) napisy.properties: # default American English locale sloj.pelen.pysznych.ciach=A jar full of yummy cookies napisy_en_GB.properties: # British English locale sloj.pelen.pysznych.ciach=A jar full of yummy biscuits napisy_pl.properties: # Polish locale sloj.pelen.pysznych.ciach=S\u0142\u00f3j pe\u0142en pysznych ciastek. W plikach property mogą występować jedynie litery alfabetu US-ASCII (podstawowy). Inne znaki koduje się za pomocą narzędzia native2ascii
11
Plan wykładu i18n o kontekście w aplikacji z GUI narzędzia ułatwiające życie: JOptionPane Swing i wielowątkowość użycie klasy SwingUtilities użycie klasy SwingWorker inne sposoby ( FoxTrot )
12
O kontekście w aplikacji z GUI aplikacje GUI mają z natury obiektową strukturę – komponenty dają się łatwo izolować zadanie utrudniają niektóre aspekty, np. dostęp do zasobów, napisów (i18n) dostęp do obiektów zarządzających (controller) aspekty nie są zazwyczaj związane ze strukturą obiektową GUI, a jedynie wskazują na obiekty potrzebne w danym miejscu programu
13
O kontekście w aplikacji z GUI Przekazanie obiektów potrzebnych do implementacji pewnego aspektu często przez metody/ pola statyczne/ obiekty typu singleton przez wiele parametrów (konstruktory) obiekt kontekstu AspectJ – rozszerzenie Javy o aspekty
14
Co zawiera kontekst? Wszystkie obiekty, które są potrzebne z punktu widzenia aspektów i18n uchwyty do kontrolerów źródeł zewnętrznych (np. połączenie z bazą danych) kontekst może (powinien) być również generatorem zdarzeń zmiana języka interfejsu zerwane połączenie z bazą danych
15
Jak przekazywać kontekst? Najwygodniej chyba jako właściwość property obiektów: setContext(ApplicationContext context)
16
Plan wykładu i18n o kontekście w aplikacji z GUI narzędzia ułatwiające życie: JOptionPane Swing i wielowątkowość użycie klasy SwingUtilities użycie klasy SwingWorker inne sposoby ( FoxTrot )
17
Czym jest javax.swing.OptionPane ? JOptionPane makes it easy to pop up a standard dialog box that prompts users for a value or informs them of something. Wsparcie dla: prostych okienek informacyjnych wybór opcji wprowadzanie tekstu bardziej skomplikowane dialogi Wszystkie dialogi są modalne!
18
Przykłady… JOptionPane.showMessageDialog(null, "Eggs aren't supposed to be green."); JOptionPane.showMessageDialog(null, "Eggs aren't supposed to be green.", "Insane warning", JOptionPane.WARNING_MESSAGE); JOptionPane.showMessageDialog(null, "Eggs aren't supposed to be green.", "Insane warning", JOptionPane.ERROR_MESSAGE);
19
Przykłady Object[] options = {"Yes, please", "No, thanks", "No eggs, no ham!"}; int n = JOptionPane.showOptionDialog(null, "Would you like some green eggs to go with that ham?", "A Silly Question", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
20
Przykłady Object[] possibilities = {"ham", "spam", "yam"}; String s = (String) JOptionPane.showInputDialog( null, "Complete the sentence:\n" + "\"Green eggs and...\"", "Customized Dialog", JOptionPane.PLAIN_MESSAGE, null /* custom icon */, possibilities, "ham");
21
Zaawansowane użycie JOptionPane Parametr message może być dowolnym komponentem lub tablicą komponentów JPanel message = new JPanel( new BorderLayout()); JScrollPane scrollPane = new JScrollPane(); scrollPane.getViewport().add(new JTree()); scrollPane.setPreferredSize(new Dimension(200,300)); message.add( scrollPane, BorderLayout.CENTER ); message.add( new JCheckBox("Zawsza ta opcja"), BorderLayout.SOUTH ); int n = JOptionPane.showConfirmDialog(null, message, "Customized dialog", JOptionPane.OK_CANCEL_OPTION);
22
Plan wykładu i18n o kontekście w aplikacji z GUI narzędzia ułatwiające życie: JOptionPane Swing i wielowątkowość użycie klasy SwingUtilities użycie klasy SwingWorker inne sposoby ( FoxTrot )
23
Model wielowątkowości w SWING Swing jest jednowątkowy wątek obsługujący komunikaty jest ukryty Swing nie jest aplikacją thread-safe nie można (nie powinno się) wykonywać operacji na komponentach z równolegle działających wątków częściowo z: Simone Bordet, A New Solution for Using Threads with the Java […]
24
O niepoprawnych programach… Jedyny wątek, który ma prawo wpływać na GUI to EventDispatchingThread SwingUtilities.isEventDispatchThread() frame.setSize(200,200); frame.pack(); frame.show(); // CONCURRENT ACCESS TO SWING! frame.setTitle("Bubu");
25
O niepoprawnych programach (2) obiekty listener są wywoływane przez Swing, a więc są bezpieczne wykonanie akcji powinno być jak najszybsze, bowiem blokuje odświeżanie GUI JFrame frame = new JFrame("Swing Freeze Test"); final JButton button = new JButton("Freeze me !"); frame.getContentPane().add(button); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { button.setText("Sleeping..."); Thread.currentThread().sleep(10000); button.setText("Freeze me !"); } }); frame.setSize(200,200); frame.pack(); frame.show(); Sleeping?
26
Jak poradzić sobie z problemem? Metoda najprostsza: SwingUtilities.invokeLater(Runnable) kolejkuje zadanie dla wątku Swinga natychmiast powraca (nie blokuje) można stosować z każdego punktu w programie Problemy: brak synchronizacji z wątkiem roboczym mocno zakręcony kod aplikacji trudności z kodem zwracającym wartość lub przechwyceniem wyjątków
27
Rozwiązanie przy pomocy invokeLater JFrame frame = new JFrame("Swing Freeze Test"); final JButton button = new JButton("Freeze me !"); frame.getContentPane().add(button); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { button.setText("Sleeping..."); button.setEnabled(false); new Thread() { public void run() { Thread.currentThread().sleep(3000); SwingUtilities.invokeLater( new Runnable() { public void run() { button.setEnabled(true); button.setText("Freeze me !"); } }); } }.start(); } }); frame.setSize(200,200); frame.pack(); frame.show(); swing-safe
28
Użycie SwingWorker SwingWorker powstał jako łata na problemy z długimi operacjami w listenerach nie jest częścią Swinga – trzeba pobrać samodzielnie http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
29
JFrame frame = new JFrame("Swing Freeze Test"); final JButton button = new JButton("Freeze me !"); frame.getContentPane().add(button); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { button.setText("Sleeping..."); button.setEnabled(false); SwingWorker worker = new SwingWorker() { public Object construct() { try { Thread.currentThread().sleep(3000); } catch (InterruptedException e) {} return "some-value"; } public void finished() { // called on the event dispatching thread! button.setEnabled(true); button.setText("Freeze me!, returned: + get()); } }; worker.start(); // start the lengthy task } ); frame.setSize(400,50); frame.show();
30
Inne sposoby… Foxtrot ( http://foxtrot.sourceforge.net/ ) http://foxtrot.sourceforge.net/ synchroniczna obsługa długich zadań wyjątki w miejscu wywołania
31
final JButton button = new JButton("Take a nap !"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { button.setText("Sleeping..."); String text = null; try { text = (String)Worker.post(new Task() { public Object run() throws Exception { Thread.sleep(10000); return "Slept !"; } }); } catch (Exception x)... button.setText(text); somethingElse(); } });
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.