更改JRadioButtonMenuItem的选定点颜色

我正在使用我的个人Java聊天客户端,其中一个function是设置用户状态(可用,不可见,忙)。 为了使用户友好,我将这些状态放入带有JRadioButtonMenuItemJMenu

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

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

我想用三个不同的自定义RadioButtonMenuItem扩展JRadioButtonMenuItem ,但无法理解如何绘制JRadioButtonMenuItem

谁能帮我解决这个问题?

编辑1
感谢您的建议,将IconsetIcon()setSelectedIcon()方法结合使用。
但是,由于我的问题是关于改变无线电点,你还能帮我隐藏RadioButton的无线电点吗?

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

每个外观和感觉的UI代表呈现单选按钮的点。 您可以提供自己的BasicRadioButtonUI ,但努力并非无足轻重。 作为替代方案,实现Icon界面,如ColorIcon所示。

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

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

我的想法是,JRadioButtonMenuItem的行为很好,它只是它的绘画有点傻。 但我不想延长它或覆盖油漆或任何这些恶作剧。 所以我总结说,只是窃取它的行为并将其绘画留在后面。

您会注意到ButtonGroup接受了AbstractButton ,所以我喜欢Dungeon Hunter的解决方案:使用常规的JMenuItem 。 我追加到那个,窃取了JToggleButtonButtonModel并发送了一个将进行图像交换的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; } } 

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

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

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

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

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

添加列表器以获取最新事件以使用setIcon()方法更新Icon。