Pergunta

I would like to create my own Look and Feel and have derived the MetalLookAndFeel. I have setup a very basic configuration where all files are in the same directory and have not a package declaration:

MyLookAndFeel.java

import javax.swing.UIDefaults;
import javax.swing.plaf.basic.BasicLookAndFeel;
import javax.swing.plaf.metal.MetalLookAndFeel;


public class MyLookAndFeel extends MetalLookAndFeel {

    public MyLookAndFeel() {
        setCurrentTheme(new DefaultMetalTheme());
    }

    @Override
    protected void initClassDefaults(UIDefaults table) {
        super.initClassDefaults(table);

        table.put( "ButtonUI", "MyButtonUI");
    }

    @Override
    public String getName() {
        return "MyLookAndFeel";
    }

    @Override
    public String getID() {
        return "MyLookAndFeel";
    }

    @Override
    public String getDescription() {
        return "MyLookAndFeel";
    }

    @Override
    public boolean isNativeLookAndFeel() {
        return false;
    }

    @Override
    public boolean isSupportedLookAndFeel() {
         return true;
    }
} 

And we also have the MyButtonUI.java:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.plaf.metal.MetalButtonUI;


public class MyButtonUI extends MetalButtonUI {

    @Override
    public void paint(Graphics g, JComponent c) {

    }

    @Override
    protected void paintButtonPressed(Graphics g, AbstractButton b) {
        g.fillRect(0, 0, 40, 40);
    }

    @Override
    protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
            String text) {
    }
}

With the above code I expect that a weird button is going to be painted (or no button at all since the paint method is empty) when I run the TestUI JFrame class with this constructor, but the button looks quiet normal:

public TestUI() throws UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(new MyLookAndFeel());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200,200);
        setLayout(new FlowLayout());
        add(new JButton("Press"));
        add(new JLabel("Text"));
        setVisible(true);
    }

Have I forgotten something important?

Foi útil?

Solução

  • "MyButtonUI" should be full path (same as for Icon packaged in jar) or valid class name e.g. UIManager.put("ButtonUI", MyButtonUI.class.getName());

  • override BasicButtonUI, with interfaces to another LaFs, can be empty, without override all methods for all System LaFs, instead of MetalButtonUI, your custom MetalButtonUI is so LaF sensitive, breakable, in the case that is registred in UIManager

  • maybe will help you partial workaround for MetalButtonUI, maybe there isn't reason to register custom UI to UIManager, sure final decision is up tu you

Outras dicas

In your class MyButtonUI you have to implement a public static method createUI(). Like this:

public static ComponentUI createUI(JComponent c)
{
    return new MyButtonUI ();
}

Or return one shared instance for all the buttons.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top