Изменение цвета фона выбранного JToggleButton - PullRequest
7 голосов
/ 27 апреля 2011

Я пытаюсь изменить цвет JToggleButton, когда он был выбран надежным, независимым и надежным способом.

Если вы используете Metal L & F, то использование UIManager является подходом:

UIManager.put("ToggleButton.selected", Color.RED);

Примечание : Iyy указал, что у меня была опечатка в названии свойства выше, но я оставлю это выше для людей, которые попадают сюда, но реальное имя свойства должноbe:

UIManager.put("ToggleButton.select", Color.RED);

Однако, это не работает в моем текущем стиле (в настоящее время Windows XP).После некоторого дальнейшего анализа выясняется, что внешний вид системы в Windows (все еще XP) вообще не использует никаких UIManager -основных *1013* свойств для ToggleButton или, по крайней мере, сам не предоставляет их(в Интернете есть быстрый пример поиска всех ключей свойств из UIManager, который в этом примере удобно явно ограничен Color свойствами).

Я попытался установитьцвет фона:

Action action = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) { /* stuff */ }
};
JToggleButton button = new JToggleButton(action);
// tried with and without opaque true
button.setOpaque(true);
button.setBackground(Color.RED);

Он не только не изменяет выбранное состояние, но и не влияет на невыбранное состояние.

Я пытался изменить цвет фона только после получения действия.:

@Override
public void actionPerformed(ActionEvent e)
{
    JToggleButton button = (JToggleButton)e.getSource();
    if (button.isSelected()) // alternatively, (Boolean)getValue(Action.SELECTED_KEY)
    {
        button.setBackground(Color.RED);
    }
}

Ничего из этого не работает.Единственное, что я нашел для работы, - это чтобы я сам нарисовал кнопку в выбранном состоянии (что приводит к рабочему примеру, хотя и нестандартному виду):

private class ColoredToggleButton extends JToggleButton
{
    ColoredToggleButton(Action action, Color color)
    {
        super(action);

        setBackground(color);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (this.isSelected())
        {
            int w = getWidth();
            int h = getHeight();
            String s = getText();

            // selected color
            g.setColor(getBackground());
            g.fillRect(0, 0, w, h);
            // selected foreground color
            g.setColor(SystemColor.controlText);
            g.drawString(s,
                         (w - g.getFontMetrics().stringWidth(s)) / 2 + 1,
                         (h + g.getFontMetrics().getAscent()) / 2 - 1);
        }
    }
}

Это немного изменено по сравнению скомментарий в этом сообщении об ошибке Java .Интересно (забавно?), В утверждениях, которые были исправлены в 1998 году.

Кто-нибудь знает лучший, независимый от L & F способ установки цвета фона выбранного JToggleButton?

Ответы [ 5 ]

5 голосов
/ 05 марта 2013

«ToggleButton.selected» неправильный, для него требуется «ToggleButton.select». И должно быть обновление до компонента.

UIManager.put("ToggleButton.select", Color.WHITE);
SwingUtilities.updateComponentTreeUI(togglebuttonname);
5 голосов
/ 30 марта 2014
JToggleButton btn = new JToggleButton(...);
btn.setUI(new MetalToggleButtonUI() {
    @Override
    protected Color getSelectColor() {
        return Color.RED;
    }
});
3 голосов
/ 27 апреля 2011

Вы можете увидеть, достаточно ли setIcon() для вашей цели, но вы также можете переопределить paint() в делегате ButtonUI.

Добавление: @ kleopatra комментарий хорош-taken: изменение делегата пользовательского интерфейса не тривиально.Недавний пример @ mKorbel показывает как сложность, так и универсальность подхода.Его существенным преимуществом является независимость внешнего вида.

Упоминаются некоторые менее амбициозные подходы здесь .

1 голос
/ 25 ноября 2016

Вы можете просто принудительно включить цвет фона перед каждым перекрашиванием - для этого вам нужно изменить paintComponent, проверить, переключается ли кнопка, установить фон в зависимости от состояния переключения и, наконец, позволить суперклассу выполнить фактическое задание рисования:

public class ColoredToggleButton extends JToggleButton
{
    @Override
    public void paintComponent(Graphics g)
    {
        Color bg;
        if (isSelected()){
            bg = Color.GREEN;
        } else {
            bg = Color.RED;
        }
        setBackground(bg);
        super.paintComponent(g);
    }
}
0 голосов
/ 01 декабря 2016

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

Вот пример, который я недавно использовал

private class FavouriteToggle extends JToggleButton {
    public FavouriteToggle() {
        setUI(new BasicToggleButtonUI()); //Removes selectColor

        ////Your Custom L&F Settings////
        setBackground(new Color(255, 252, 92));
        setForeground(Color.GRAY);
        setText("Favourite");
        setBorder(null);
        setFocusPainted(false);

        ////Add your own select color by setting background////
        addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(((JToggleButton) e.getSource()).isSelected()) {
                    setForeground(Color.BLACK);
                    setBackground(new Color(255, 251, 0));
                } else {
                    setBackground(new Color(255, 252, 92));
                    setForeground(Color.GRAY);
                }
            }
        });
    }
}
...