Java Swing-如何模仿为什么我的外观和感觉绘制禁用图标?

Java Swing-如何模仿为什么我的外观和感觉绘制禁用图标?,java,swing,look-and-feel,disabled-control,Java,Swing,Look And Feel,Disabled Control,设置Swing控件的图标(例如JButton)时,会自动生成一个灰色较深的禁用图标。我希望能够模仿图标颜色在禁用状态下的变化方式,这样我就可以创建我自己的禁用图标,并将其设置为禁用按钮 有没有一种方法可以实现这一点(除了首先实例化控件并检索它的图标,我正在寻找更直接、更少黑客的方法) 有没有办法实现这一点(除了先实例化控件并检索其图标之外) LAF负责创建禁用图标。AbstractButtonbutton类中的getDisabledIcon()方法如下所示: Icon disabledIcon

设置Swing控件的图标(例如
JButton
)时,会自动生成一个灰色较深的禁用图标。我希望能够模仿图标颜色在禁用状态下的变化方式,这样我就可以创建我自己的禁用图标,并将其设置为禁用按钮

有没有一种方法可以实现这一点(除了首先实例化控件并检索它的图标,我正在寻找更直接、更少黑客的方法)

有没有办法实现这一点(除了先实例化控件并检索其图标之外)

LAF负责创建禁用图标。
AbstractButton
button类中的
getDisabledIcon()
方法如下所示:

Icon disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, getIcon());
因此,从理论上讲,LAF getDisabledIcon()方法希望组件作为参数传入,因此您的问题的答案是:“是的,需要首先创建按钮”

但是,在实际操作中(至少对于金属和窗户而言),该组件在创建图标时并未实际使用,因此您可以执行以下操作:

ImageIcon original = new ImageIcon( ... );
Icon disabled = UIManager.getLookAndFeel().getDisabledIcon(null, original);
使用这种方法是有风险的,因为其他LAF可能确实需要该组件来创建禁用图标

但是,我想您可以创建一个组件,然后使用多个不同的图标调用此方法,而不是传递null,因此这仍然比为每个图标创建一个唯一的组件要好一些

以下是我用来测试该方法的SSCCE:

import javax.swing.*;
import javax.swing.plaf.metal.*;
import java.awt.*;
import java.awt.image.*;

public class ButtonDisabledIcon extends JPanel
{
    public ButtonDisabledIcon()
    {
        ImageIcon original = new ImageIcon( "dukewavered.gif" );

        JButton button1 = new JButton( "Original" );
        button1.setIcon( original );
        add(button1);

        JButton button2 = new JButton( "Disabled" );
        button2.setIcon(original);
        button2.setEnabled(false);
        add(button2);

        JButton button3 = new JButton( "LAF Disabled" );
        button3.setIcon( UIManager.getLookAndFeel().getDisabledIcon(null, original) );
        add(button3);
  }
    private static void createAndShowUI()
    {
/*
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) { }
*/
        JFrame frame = new JFrame("Button Disabled Icon");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ButtonDisabledIcon() );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
有没有办法实现这一点(除了先实例化控件并检索其图标之外)

LAF负责创建禁用图标。
AbstractButton
button类中的
getDisabledIcon()
方法如下所示:

Icon disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, getIcon());
因此,从理论上讲,LAF getDisabledIcon()方法希望组件作为参数传入,因此您的问题的答案是:“是的,需要首先创建按钮”

但是,在实际操作中(至少对于金属和窗户而言),该组件在创建图标时并未实际使用,因此您可以执行以下操作:

ImageIcon original = new ImageIcon( ... );
Icon disabled = UIManager.getLookAndFeel().getDisabledIcon(null, original);
使用这种方法是有风险的,因为其他LAF可能确实需要该组件来创建禁用图标

但是,我想您可以创建一个组件,然后使用多个不同的图标调用此方法,而不是传递null,因此这仍然比为每个图标创建一个唯一的组件要好一些

以下是我用来测试该方法的SSCCE:

import javax.swing.*;
import javax.swing.plaf.metal.*;
import java.awt.*;
import java.awt.image.*;

public class ButtonDisabledIcon extends JPanel
{
    public ButtonDisabledIcon()
    {
        ImageIcon original = new ImageIcon( "dukewavered.gif" );

        JButton button1 = new JButton( "Original" );
        button1.setIcon( original );
        add(button1);

        JButton button2 = new JButton( "Disabled" );
        button2.setIcon(original);
        button2.setEnabled(false);
        add(button2);

        JButton button3 = new JButton( "LAF Disabled" );
        button3.setIcon( UIManager.getLookAndFeel().getDisabledIcon(null, original) );
        add(button3);
  }
    private static void createAndShowUI()
    {
/*
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) { }
*/
        JFrame frame = new JFrame("Button Disabled Icon");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ButtonDisabledIcon() );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
在@camickr's上放大,你可以用和这个做实验

在@camickr's上放大,你可以用和这个做实验


谢谢你指出了底层方法。我会研究它!谢谢你指出了底层方法。我会研究它!我不确定我是否得到了它;是getGrey()吗L&F这样做的方式,或者只是一种获得灰色图标的方式?不,每个L&F都可以自由地做不同的事情;
com.apple.laf.AquaLookAndFeel
,例如,试图避免使禁用的外观难以辨认;我的小
getGray()
方法只是一种可能的方法。我不确定我是否得到了它;是getGrey()L&F这样做的方式,或者仅仅是一种获得灰色图标的方式?不,每个L&F都可以自由地做不同的事情;
com.apple.laf.AquaLookAndFeel
,例如,试图避免使禁用的外观难以辨认;我的小
getGray()
方法只是一种可能的方法。