5

我正在开发我的个人 Java 聊天客户端,它的一个功能是设置用户状态(可用、不可见、忙碌)。为了使其用户友好,我将这些状态放入JMenuwith 中JRadioButtonMenuItem

问题是我希望每个状态RadioButton都有自己的单选点颜色(或点图标)。例如:

  • [绿点] 可用
  • [红点] 忙
  • [灰点] 不可见。

我想JRadioButtonMenuItem用三种不同的自定义扩展RadioButtonMenuItem,但不明白JRadioButtonMenuItem是怎么画的。

谁能帮我解决这个问题?

编辑 1
感谢您提出与和方法Icon一起使用的建议。 但是,由于我的问题是关于更改无线电点,您能否帮我隐藏无线电点?setIcon()setSelectedIcon()
RadioButton

编辑 2
这是我的应用程序的当前屏幕截图。
MyIM 菜单栏截图
正如你所看到的,在那之前的那个点在RadioButtonMenuItem某种程度上是荒谬的废话。这就是为什么我想摆脱点,或将其更改为我的自定义图标:)

4

4 回答 4

5

单选按钮的点由 UI 委托为每个外观呈现。你可以提供你自己的BasicRadioButtonUI,但努力不是微不足道的。作为替代方案,实现接口,如此Icon所示。ColorIcon

于 2012-08-19T07:09:15.577 回答
3

我建议你使用 Swing Components 的 Icon 属性。这是为 JRadioButtonMenuItem 设置图标的示例。每当状态发生变化时,使用 seticon 方法来更改图标。使用图标代替颜色

这是一个示例http://www.java2s.com/Code/Java/Swing-JFC/Anexampleofradiobuttonmenuitemsinaction.htm

于 2012-08-19T07:27:20.570 回答
1

我的想法是,JRadioButtonMenuItem 的行为很好,只是它的绘画有点傻。但我不想扩展它或覆盖油漆或任何那些恶作剧。所以我得出结论,只是偷它的行为,把它的画留在后面。

你会注意到ButtonGroup接受AbstractButtons,所以我喜欢地牢猎人的解决方案:使用常规JMenuItems。我会附加它,窃取JToggleButton'sButtonModel并发送一个ItemListener将进行图像交换的文件(如 Ramesh John 建议的那样)。

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JToggleButton;

public class TestRadioCustomIcon {

    public static void main(String[] args){
        new TestRadioCustomIcon().go();
    }

    private void go(){
        JFrame frame = new JFrame("Foo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JMenuBar jmb = new JMenuBar();
        JMenu menu = new JMenu("Menu");

        JMenuItem i1 = makeFauxRadioMenuItem("Item 1");
        JMenuItem i2= makeFauxRadioMenuItem("Item 2");
        JMenuItem i3= makeFauxRadioMenuItem("Item 3");
        i1.setSelected(true);

        ButtonGroup bg = new ButtonGroup();
        bg.add(i1);
        bg.add(i2);
        bg.add(i3);

        menu.add(i1);
        menu.add(i2);
        menu.add(i3);
        jmb.add(menu);
        frame.add(jmb);
        frame.pack();
        frame.setVisible(true);
    }

    private ImageIcon selected = loadImage("C:\\path\\to\\image1.bmp");
    private ImageIcon deselected = loadImage("C:\\path\\to\\image2.bmp");
    private ItemListener il = new ItemListener(){
        @Override
        public void itemStateChanged(ItemEvent e){
            AbstractButton ab = (AbstractButton) e.getSource();
            switch(e.getStateChange()){
                case ItemEvent.SELECTED:
                    ab.setIcon(selected);
                    break;
                case ItemEvent.DESELECTED:
                    ab.setIcon(deselected);
                    break;
            }
        }
    }

    private ImageIcon loadImage(String filePath){
        try{
            BufferedImage bi = ImageIO.read(new File(filePath));
            return new ImageIcon(bi);
        } catch (IOException e){
            //sad day
            return null;
        }
    }

    private JMenuItem makeFauxRadioMenuItem(String label){
        JMenuItem item = new JMenuItem(label);
        //Make it think it's a RadioButton
        item.setModel(new JToggleButton.ToggleButtonModel());
        //When selection changes occur, swap icons
        item.addItemListener(il);
        //Assume deselected
        item.setIcon(deselected);
        return item;
    }
}

这适用于任何旧图标,而不仅仅是更改按钮的颜色。

于 2014-02-26T18:31:49.243 回答
0

添加一个新类以RadioButtonMenuItem通过扩展来自定义JRadioButtonMenuItem.

通过实现 Icon 接口添加内部类以更新状态 Icon。覆盖所有paintIcon()方法用当前状态图标更新方法。

通过传递状态图标调用超类。

super(theMenuText, new StatusIcon(theStudyIcon, getUserStatus(UserId)));

添加侦听器以获取最新事件以使用setIcon()方法更新图标。

于 2013-10-29T13:55:29.800 回答