Using Napkin LookAndFeel

1

I'm using the Eclipse IDE and I have this code:

package br.com.caelum.argentum.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class ArgentumUI {

    private JFrame janela;
    private JPanel painelPrincipal;
    public static void main(String[] args) {
        try {  
            UIManager.setLookAndFeel("napkin.NapkinLookAndFeel");  
        } catch (Exception e) {  
               e.printStackTrace();  
        }
        new ArgentumUI().montaTela();
    }

    public void montaTela() {
        preparaJanela();
        preparaPainelPrincipal();
        preparaBotaoCarregar();
        preparaBotaoSair();
        mostraJanela();
    }


    private void mostraJanela() {
        // TODO Auto-generated method stub
        janela.pack();
        janela.setSize(540, 540);
        janela.setVisible(true);
    }

    private void preparaBotaoSair() {
        // TODO Auto-generated method stub
        JButton botaoSair = new JButton("Sair");
        botaoSair.setMnemonic(KeyEvent.VK_S);
        botaoSair.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        painelPrincipal.add(botaoSair);
    }

    private void preparaBotaoCarregar() {
        // TODO Auto-generated method stub
        JButton botaoCarregar = new JButton("Carregar XML");
        botaoCarregar.setMnemonic(KeyEvent.VK_C);
        botaoCarregar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new EscolhedorDeXML().escolhe();
            }
        });
        painelPrincipal.add(botaoCarregar);

    }

    private void preparaPainelPrincipal() {
        // TODO Auto-generated method stub
        painelPrincipal = new JPanel();
        janela.add(painelPrincipal);
    }

    private void preparaJanela() {
        // TODO Auto-generated method stub
        janela = new JFrame("Argentum");
        janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

Napkin is already in Referenced Libraries, however I'm getting these errors:

keys we didn't overwrite: []
Exception in thread "main" java.awt.IllegalComponentStateException: The frame is decorated
    at java.awt.Frame.setBackground(Frame.java:986)
    at javax.swing.JFrame.frameInit(JFrame.java:253)
    at javax.swing.JFrame.<init>(JFrame.java:219)
    at br.com.caelum.argentum.ui.ArgentumUI.preparaJanela(ArgentumUI.java:77)
    at br.com.caelum.argentum.ui.ArgentumUI.montaTela(ArgentumUI.java:26)
    at br.com.caelum.argentum.ui.ArgentumUI.main(ArgentumUI.java:22)

How to fix?

    
asked by anonymous 08.10.2014 / 01:22

1 answer

1

Victor, here it is (it's a hard code to run).

There appeared to be a breach of compatibility between JDK 6 and JDK 7 for translucent windows (see this post in SOen ). NapKin is dependent on this feature (see Error in NapKin Look and Feel in CodeRanch ).

workaround suggested by Rob Spoor is:

  • Do not configure look & feel logo face.
  • Create your user interface.
  • Call setUndecorated(true) in frame .
  • Set the look & feel .
  • Call SwingUtilities.updateComponentTreeUI to frame .
  • If necessary, call setUndecorated(false) in frame .

In your case it was not necessary to call setUndecorated .

I've made the following changes:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            try {
                ArgentumUI ui = new ArgentumUI();
                ui.montaTela();
                UIManager.setLookAndFeel("napkin.NapkinLookAndFeel");
                SwingUtilities.updateComponentTreeUI(ui.janela);
                ui.mostraJanela();
            } catch (Exception ex) {
                Logger.getLogger(ArgentumUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    });
}

And I updated the montaJanela method to not show the window immediately after building:

public void montaTela() {
    preparaJanela();
    preparaPainelPrincipal();
    preparaBotaoCarregar();
    preparaBotaoSair();
    //mostraJanela();
}

And everything worked as it should.

The SwingUtilities.invokeLater issue is not strictly required to make the code run (see Swing Application.) Why the main method should you dispatch the creation of the GUI for EDT? ), but prevention is better than cure. The Oracle tutorial makes it clear that almost every code that creates or interacts with Swing components should run on EDT .

    
08.10.2014 / 02:55