Look and Feel w Javie

LOSMARCELOS

W Javie (Swing) istnieje mechanizm Look and Feel, który umożliwia nam modyfikację wyglądu programów. Wygląd interfejsu naszego programu może być "systemowy, natywny", tj. zmieniać się w zależności od systemu na którym uruchomimy program, oraz identyczny na różnych systemach/platformach (program będzie wyglądać bardzo podobnie na Linux/Windows/MacOS). Wbudowane w Jave schematy GUI, przenośne między systemami to : Motif (wygląda ala lata 80), Metal (taki niebieskawy) oraz Nimbus (ładniusi, trochę kojarzy się z MacOS). Nimbus został wprowadzony w wersji Java 1.6 Update 10.

Aby zademonstrować działanie Systemu Look and Feel w środowisku Netbeans należy stworzyć nowy projekt umieścić kilka komponentów na formularzu i dodać komponent JComboBox. Nazwijmy ten komponent WygladProgramu_jComboBox
Następnie we właściwościach JComboBox (prawy przycisk myszy na komponencie i klikamy na Properties) wybieramy z listy "Model", klikamy w przycisk z trzema kropkami i wklejamy następującą treść :

Domyślny (Systemowy)
Metal
Motif
Nimbus

Dzięki temu w liście rozwijalnej mamy 4 elementy :)
Następnie klikamy na naszym JComboBox prawy przycisk myszy Events->Action->Action Performed...

Wpisujemy kod :


    private void WygladProgramu_jComboBoxActionPerformed(java.awt.event.ActionEvent evt) {                                                        
        // TODO add your handling code here:
        /* Konfiguracja wyglądu program */
        try {
            this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            if (WygladProgramujComboBox.getSelectedIndex() == 0) {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch(Exception e) {
                    JOptionPane.showMessageDialog(this, e.toString(), "Błąd", JOptionPane.ERROR_MESSAGE);
                }
                SwingUtilities.updateComponentTreeUI(this);
            }

            if (WygladProgramujComboBox.getSelectedIndex() == 1) {
                try {
                    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                } catch(Exception e) {
                    JOptionPane.showMessageDialog(this, e.toString(), "Błąd", JOptionPane.ERROR_MESSAGE);
                }
                SwingUtilities.updateComponentTreeUI(this);
            }

            if (WygladProgramujComboBox.getSelectedIndex() == 2) {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
                } catch(Exception e) {
                    JOptionPane.showMessageDialog(this, e.toString(), "Błąd", JOptionPane.ERROR_MESSAGE);
                }
                SwingUtilities.updateComponentTreeUI(this);
            }
            if (WygladProgramujComboBox.getSelectedIndex() == 3) {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch(Exception e) {
                    JOptionPane.showMessageDialog(this, e.toString(), "Błąd", JOptionPane.ERROR_MESSAGE);
                }
                SwingUtilities.updateComponentTreeUI(this);

            }
        }
        finally
        {
            this.setCursor(Cursor.getDefaultCursor());
        }
        System.gc();

    }                  
 

Jest jeszcze jedna kwestia, którą należy zrobić... Polacy nie gęsi i swój język mają :)
Jeśli wybierzemy inny niż natywny/systemowy wygląd to okienka dialogowe typu otwórz/zapisz plik (komponent JFileChooser) będą mieć opis i etykietki po angielsku.... Aby to zmienić należy napisać funkcję :


    /* Funkcja lokalizująca napisy w okienkach dialogowych typu otwórz/zapisz) */
    /** @version 1.0 */
    /** @param komponent nazwa komponentu z oknem dialogowym */
    public void LokalizujNapisyPL(javax.swing.JComponent komponent)
    {
        UIManager.put("FileChooser.lookInLabelText","Szukaj w");
        UIManager.put("FileChooser.lookInLabelMnemonic",""+ KeyEvent.VK_W);
 
        UIManager.put("FileChooser.saveInLabelText","Zapisz w");
        UIManager.put("FileChooser.saveInLabelMnemonic",""+KeyEvent.VK_W);
 
        UIManager.put("FileChooser.fileNameLabelText","Nazwa pliku:");
        UIManager.put("FileChooser.fileNameLabelMnemonic",""+KeyEvent.VK_N);
 
        UIManager.put("FileChooser.filesOfTypeLabelText","Pliki typu:");
        UIManager.put("FileChooser.filesOfTypeLabelMnemonic",""+KeyEvent.VK_P);
 
        UIManager.put("FileChooser.upFolderToolTipText","Poziom wyżej");
        UIManager.put("FileChooser.homeFolderToolTipText","Pulpit");
        UIManager.put("FileChooser.newFolderToolTipText","Nowy katalog");
        UIManager.put("FileChooser.listViewButtonToolTipText","Lista");
        UIManager.put("FileChooser.detailsViewButtonToolTipText","Szczegóły");
 
        UIManager.put("FileChooser.fileNameHeaderText","Nazwa");
        UIManager.put("FileChooser.fileSizeHeaderText","Rozmiar");
        UIManager.put("FileChooser.fileTypeHeaderText","Typ");
        UIManager.put("FileChooser.fileDateHeaderText","Modyfikacja");
        UIManager.put("FileChooser.fileAttrHeaderText","Atrybuty");
 
        UIManager.put("FileChooser.newFolderErrorText","Błąd podczas tworzenia katalogu");
 
        UIManager.put("FileChooser.saveButtonText","Zapisz");
        UIManager.put("FileChooser.saveButtonMnemonic",""+KeyEvent.VK_Z);
 
        UIManager.put("FileChooser.openButtonText","Otwórz");
        UIManager.put("FileChooser.openButtonMnemonic",""+KeyEvent.VK_O);
 
        UIManager.put("FileChooser.cancelButtonText","Anuluj");
        UIManager.put("FileChooser.openButtonMnemonic",""+KeyEvent.VK_R);

        UIManager.put("FileChooser.openDialogTitleText","Otwieranie");
        UIManager.put("FileChooser.saveDialogTitleText","Zapisywanie");
 
        UIManager.put("FileChooser.saveButtonToolTipText","Zapisanie pliku");
        UIManager.put("FileChooser.openButtonToolTipText","Otwarcie pliku");
        UIManager.put("FileChooser.cancelButtonToolTipText","Anuluj");
        UIManager.put("FileChooser.acceptAllFileFilterText","Wszystkie pliki");
        
        UIManager.put("FileChooser.directoryOpenButtonText", "Otwórz katalog");
        UIManager.put("FileChooser.directoryOpenButtonToolTipText", "Otwiera katalog");

        UIManager.put("FileChooser.foldersLabelText", "Nazwa folderu: ");
        UIManager.put("FileChooser.pathLabelText", "Ścieżka: ");
        UIManager.put("FileChooser.directoryDescriptionText", "Scieżka katalogu, opis");
        UIManager.put("FileChooser.foldersLabelText", "Foldery");
        UIManager.put("FileChooser.newFolderAccessibleName", "Nowy folder");
        UIManager.put("FileChooser.newFolderToolTipText", "Nowy folder");
        UIManager.put("FileChooser.other.newFolder", "Nowy folder");
        UIManager.put("FileChooser.other.newFolder.subsequent", "Nowy folder");
        UIManager.put("FileChooser.win32.newFolder", "Nowy folder");
        UIManager.put("FileChooser.win32.newFolder.subsequent", "Nowy folder");

        
		SwingUtilities.updateComponentTreeUI(komponent);  
    }
 

Tą metodę można umieścić w konstruktorze klasy z JFrame

LokalizujNapisyPL(OtworzPlikjFileChooser); //jesli JFileChooser nazywa sie tak

Ta funkcje należy uruchamiać za każdym razem gdy zmienimy schemat w Look and Feel.

Więcej informacji na ten temat :
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/index.html

Mam nadzieję, że ten krótki artykuł się przyda, jak będę mieć więcej czasu to go poprawie i dodam więcej opisów.

3 komentarzy

Ok, dzięki za informację, dogłębnie zbadam temat. Chodziło mi o to, że domyślny tzn. nie domyślny w sensie javowym tylko jako natywny wygląd dla danego systemu operacyjnego :)

Wbrew temu co autor sugeruje na liście do comboboxa wygląd default wcale nie musi być wyglądem systemowym. To się może zmieniać zależnie od wersji Javy i konkretnego systemu. Defaultowym jest najczęściej Motif lub Nimbus. Systemowy (Mac, Windows) trzeba samemu wymusić przez
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());