更改JRadioButtonMenuItem的选定点颜色
我正在使用我的个人Java聊天客户端,其中一个function是设置用户状态(可用,不可见,忙)。 为了使用户友好,我将这些状态放入带有JRadioButtonMenuItem
的JMenu
。
问题是我希望每个状态RadioButton
都有自己的无线电点颜色(或点图标)。 例如:
- [绿点]可用
- [红点]忙
- [灰点]看不见。
我想用三个不同的自定义RadioButtonMenuItem
扩展JRadioButtonMenuItem
,但无法理解如何绘制JRadioButtonMenuItem
。
谁能帮我解决这个问题?
编辑1
感谢您的建议,将Icon
与setIcon()
和setSelectedIcon()
方法结合使用。
但是,由于我的问题是关于改变无线电点,你还能帮我隐藏RadioButton
的无线电点吗?
编辑2
这是我的应用程序的当前屏幕截图。
正如你在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
。 我追加到那个,窃取了JToggleButton
的ButtonModel
并发送了一个将进行图像交换的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。