3

I'm trying to change to appearance of my JButton so that the button have no up state.

Currently i have something like this: what i currently have

And i would like something like this:NetBeans example(comming from NetBeans)

In other words, I only want the image of the button to be visible when the button does not have any kind of focus. But when the user click or roll over it, it should act exactly the same as a regular button.

more examples:

no focus

DONT WANT no focusDO WANT no focus

roll over

roll overroll over

click

clickclick

I use a inner class for my button. It look like this:

private class CustumJButton extends JButton
{

    public CustumJButton(Icon icon)
    {
        super(icon);
        int size = 30;
        setPreferredSize(new Dimension(size, size));
        setFocusable(false);
    }
}

Thanks ayoye.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
AyoyeSnif
  • 130
  • 2
  • 6
  • I guess this wonderful example related to How to [change appearance of JButton](http://stackoverflow.com/a/7877817/1057230) by @mKorbel, is what you looking for :-) – nIcE cOw Jun 18 '13 at 16:36

4 Answers4

3

I guess you need to use these two things to make it work, setBorderPainted(boolean) and setContentAreaFilled(boolean)

buttonObject.setBorderPainted(false);
buttonObject.setContentAreaFilled(false);

as cited in this example for changing appearance of JButton by @mKorbel

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ButtonDemo
{
    private JButton demoButton;
    private ImageIcon buttonImage;

    private void displayGUI()
    {
        JFrame frame = new JFrame("Button Demo Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        try
        {
            //buttonImage = new ImageIcon(ImageIO.read(
            //  getClass().getResource("/image/bulb.gif")));
            buttonImage = new ImageIcon(ImageIO.read(
                new URL("http://gagandeepbali.uk.to/"
                                + "gaganisonline/swing/downloads/"
                                + "images/bulb.gif")));             
        }
        catch(Exception e)
        {
                e.printStackTrace();
        }
        demoButton = new JButton(buttonImage);
        setExceptionalState(demoButton);
        demoButton.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseEntered(MouseEvent me)
            {
                setNormalState(demoButton);
            }

            @Override
            public void mouseExited(MouseEvent me)
            {
                setExceptionalState(demoButton);
            }
        });

        contentPane.add(demoButton);
        frame.setContentPane(contentPane);
        frame.setSize(300, 100);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void setExceptionalState(JButton button)
    {
        button.setBorderPainted(false);
        button.setContentAreaFilled(false);
    }

    private void setNormalState(JButton button)
    {
        button.setBorderPainted(true);
        button.setContentAreaFilled(true);
    }

    public static void main(String[] args)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                new ButtonDemo().displayGUI();
            }
        };

        EventQueue.invokeLater(runnable);
    }
}
Community
  • 1
  • 1
nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • this simply disable all the paint. When you click or rollover nothing shows. – AyoyeSnif Jun 18 '13 at 16:58
  • I thought you be able to work yourself with that, given the logic part, though, happy to know that you got it sorted. Updated the answer with the code too. – nIcE cOw Jun 18 '13 at 17:31
3

You can achieve this using setBorderPainted() and setContentAreaFilled() methods. Here is the short Demo of what you are looking for. I hope it would give you rough figure to how to achieve your task.:

enter image description here

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class CustomJButton extends JButton 
{

    public CustomJButton(String icon)
    {
        super(icon);
        /*int size = 30;
        setPreferredSize(new Dimension(size, size));*/
        addFocusListener(new ButtonFocusAdapter());
        addMouseListener(new ButtonMouseAdapter());
        setContentAreaFilled(false);
        setBorderPainted(false);
        //setFocusable(false);//Don't use this method. This would avoid the focus event on JButton
    }
    private void decorateButton()
    {
        setContentAreaFilled(true);
        setBorderPainted(true);
    }
    private void unDecorateButton()
    {
        setContentAreaFilled(false);
        setBorderPainted(false);
    }
    private class ButtonFocusAdapter extends FocusAdapter
    {
        @Override
        public void focusGained(FocusEvent evt)
        {
            decorateButton();
        }
        @Override
        public void focusLost(FocusEvent evt)
        {
            unDecorateButton();
        }
    }
    private class ButtonMouseAdapter extends MouseAdapter
    {
        @Override
        public void mouseEntered(MouseEvent evt)
        {
            decorateButton();
        }
        @Override 
        public void mouseExited(MouseEvent evt)
        {
            unDecorateButton();
        }
    }
}
public class ButtonFrame extends JFrame
{
    public void createAndShowGUI()
    {
        Container c = getContentPane();
        c.setLayout(new FlowLayout());
        for (int i = 0; i < 4 ; i++ )
        {
            CustomJButton cb = new CustomJButton("Button "+i);
            c.add(cb);
        }
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String st[])
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                ButtonFrame bf = new ButtonFrame();
                bf.createAndShowGUI();
                bf.setLocationRelativeTo(null);
            }
        });
    }
}
Vishal K
  • 12,976
  • 2
  • 27
  • 38
  • This is pretty much what I was looking for thanks! Just to let you know, the focus is not needed for it to work. If you enable the focus, there is an horrible dot border around the focused button. – AyoyeSnif Jun 18 '13 at 17:20
  • `If you enable the focus, there is an horrible dot border around the focused button` . Do you mean the horrible line around the `icon` on `JButton`? If this is the case then you can use `setFocusPainted(false)` within the constructor of `CustomJButton`. – Vishal K Jun 18 '13 at 17:41
2

You would set the default state for the button as:

button.setBorderPainted(false);

Then you would need to use a MouseListener:

on mouseEntered you would use

button.setBorderPainted(true);

and on mouse exited you would use

button.setBorderPainted(false);
camickr
  • 321,443
  • 19
  • 166
  • 288
  • +1 (previously, too hurry to post this comment) disagree, never ever to use MouseListener for Buttons Components all those event are implemented in JButton API, secon options is quite easier add ChangeListener and listenning for Mouse/Key Events from ButtonModel – mKorbel Jun 18 '13 at 19:50
  • 1
    @nIcE cOw the same with upvote, the same with wrong answer, [my view](http://stackoverflow.com/a/14627663/714968), especially for JMenuXxx – mKorbel Jun 18 '13 at 19:53
1

You should check out the skinnable "Synth Look and Feel", but also be aware that Swing will be deprecated and replaced by JavaFX in the long run. If you are building a new application, you might want to consider using JavaFX which can be skinned with CSS to achieve the effect you are looking for.

Tilo
  • 3,255
  • 26
  • 31