【问题标题】:Change selected dot color of JRadioButtonMenuItem更改 JRadioButtonMenuItem 的选定点颜色
【发布时间】:2012-08-15 00:38:12
【问题描述】:

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

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

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

我想用三个不同的自定义RadioButtonMenuItem 扩展JRadioButtonMenuItem,但不明白JRadioButtonMenuItem 是如何绘制的。

谁能帮我解决这个问题?

编辑 1
感谢您建议将 IconsetIcon()setSelectedIcon() 方法一起使用。
但是,由于我的问题是关于更改单选点,您能否帮我隐藏 RadioButton 中的单选点?

编辑 2
这是我的应用程序的当前屏幕截图。

正如你所看到的,RadioButtonMenuItem 之前的那个点在某种程度上是荒谬的废话。这就是为什么我想摆脱点,或者将其更改为我的自定义图标:)

【问题讨论】:

标签: java swing radio-button menuitem


【解决方案1】:

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

【讨论】:

  • 我认为您的意思是将RadioButtonMenuItem 的图标设置为某个自定义图标?我认为这会将图标设置在该 RadioButton 的文本旁边,而不是点本身。
  • 没错,如图here;我还想强调实现接口是多么容易。
  • 请参考我更新的截图。对我来说,有黑点真的很烦人:P
  • 我会把它变成一个单一的JMenuItem;当相应的状态改变时,同时改变图标和文本。
【解决方案2】:

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

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

【讨论】:

  • 谢谢 :) 你能参考我更新的截图吗? RadioButton 之前的黑点真的让我很困扰:)
  • 尝试使用 JMenuItem 代替 JRadioButtonMenuItem docs.oracle.com/javase/1.4.2/docs/api/javax/swing/…, javax.swing.Icon)
  • +1 我不知道比切换到JMenuItem 更简单的方法,但是您会失去视觉反馈。
  • @LuanNguyen 使用常规的 JCheckBoxes 和 JRadioButtons,设置图标/选定图标是实际更改复选框/按钮的方法。不知道为什么它不适用于菜单项,我猜他们没有添加该功能。正如 Sunny/trashgod 所建议的那样,我认为您将不得不切换到常规的 JMenuItem。我认为您应该能够对其进行子类化并自己跟踪所选状态,并适当地设置图标。另外作为旁注,除了 setIcon/setSelectedIcon 之外,还有 setDisabledIcon/setDisabledSelectedIcon 如果您曾经禁用它们。
【解决方案3】:

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

你会注意到ButtonGroup 接受AbstractButtons,所以我喜欢地牢猎人的解决方案:使用常规的JMenuItems。我会附加上,窃取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;
    }
}

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

【讨论】:

    【解决方案4】:

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

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

    通过状态图标调用超类。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-12
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2011-08-14
      相关资源
      最近更新 更多