Нет состояния JButton

Я пытаюсь изменить внешний вид своего JButton, чтобы кнопка не находилась в рабочем состоянии.

В настоящее время у меня есть что-то вроде этого: то, что у меня есть сейчас

И мне бы хотелось что-то вроде этого: Пример NetBeans(из NetBeans)

Другими словами, я хочу, чтобы изображение кнопки было видно только тогда, когда кнопка не имеет какого-либо фокуса. Но когда пользователь щелкает или наведет на нее курсор, она должна действовать точно так же, как обычная кнопка.

другие примеры:

без фокуса

НЕ ХОЧУ без фокуса НЕ ХОЧУ не фокусироваться

перевернуть

roll overперевернуться

щелкните

clickщелкнуть

Я использую внутренний класс для своей кнопки. Это выглядит так:

private class CustumJButton extends JButton
{

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

Спасибо.


person AyoyeSnif    schedule 18.06.2013    source источник
comment
Думаю, этот замечательный пример, связанный с тем, как изменить внешний вид JButton от @mKorbel, - это то, что вы ищете :-)   -  person nIcE cOw    schedule 18.06.2013


Ответы (4)


Вы можете добиться этого с помощью setBorderPainted() и setContentAreaFilled() методы. Вот короткая демонстрация того, что вы ищете. Я надеюсь, что это даст вам приблизительное представление о том, как выполнить вашу задачу:

введите описание изображения здесь

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);
            }
        });
    }
}
person Vishal K    schedule 18.06.2013
comment
Это в значительной степени то, что я искал, спасибо! Просто чтобы вы знали, фокус не нужен, чтобы он работал. Если вы включите фокус, вокруг кнопки с фокусом появится ужасная точечная рамка. - person AyoyeSnif; 18.06.2013
comment
If you enable the focus, there is an horrible dot border around the focused button. Вы имеете в виду ужасную строчку вокруг icon на JButton? В этом случае вы можете использовать setFocusPainted(false) в конструкторе CustomJButton. - person Vishal K; 18.06.2013

Думаю, вам нужно использовать эти две вещи, чтобы заставить его работать: setBorderPainted (логическое) и setContentAreaFilled (boolean)

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

как указано в этом примере для изменения внешнего вида JButton @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);
    }
}
person nIcE cOw    schedule 18.06.2013
comment
это просто отключит всю краску. При щелчке мышью или при наведении курсора ничего не отображается. - person AyoyeSnif; 18.06.2013
comment
Я думал, что вы сможете сами с этим поработать, учитывая логическую часть, однако, счастлив узнать, что вы разобрались. Обновил и ответ с кодом. - person nIcE cOw; 18.06.2013

Вы должны установить состояние по умолчанию для кнопки как:

button.setBorderPainted(false);

Тогда вам нужно будет использовать MouseListener:

на mouseEntered вы бы использовали

button.setBorderPainted(true);

и при выходе из мыши вы должны использовать

button.setBorderPainted(false);
person camickr    schedule 18.06.2013
comment
+1 (ранее слишком спешил публиковать этот комментарий) не согласен, никогда не использовать MouseListener для компонентов кнопок, все эти события реализованы в JButton API, вторые параметры намного проще добавить ChangeListener и прослушивать события мыши / клавиш из ButtonModel - person mKorbel; 18.06.2013
comment
@nIcE, то же самое с голосом за, то же самое с неправильным ответом, мое мнение, особенно для JMenuXxx - person mKorbel; 18.06.2013

Вам следует проверить возможность создания скинов "Synth Look and Feel", но также имейте в виду, что Swing будет устаревшим и будет заменен на JavaFX. в долгосрочной перспективе. Если вы создаете новое приложение, вы можете рассмотреть возможность использования JavaFX, который может быть обработанный CSS для достижения желаемого эффекта.

person Tilo    schedule 18.06.2013