如何从 LAF 获得 JCheckBox 的选中和未选中外观

how to get both selected and not selected look of the JCheckBox from LAF

我有一个问题,因为我试图同时选择和未选择 JCheckbox 图像,到目前为止我已经能够从 UIManager 获取图标,但不幸的是它没有勾选版本?我看到有画这些图标的画家,但如果我 运行 下面的代码它给了我 NPE。

p = (Painter) UIManager.get("CheckBox[Enabled].iconPainter");
BufferedImage selected = new BufferedImage( 20, 20, BufferedImage.TYPE_INT_ARGB ) ;
p.paint((Graphics2D) selected.getGraphics(), null, 20, 20);

谁能帮我解决这个问题?

编辑:

基本上p在get方法后为null。

堆叠:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at addlayer.AddLayerUI.initOwn(AddLayerUI.java:47)
    at addlayer.AddLayerUI.<init>(AddLayerUI.java:28)
    at addlayer.AddLayerUI.run(AddLayerUI.java:136)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access0(EventQueue.java:97)
    at java.awt.EventQueue.run(EventQueue.java:709)
    at java.awt.EventQueue.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

代码:

package addlayer;

import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.Painter;
import javax.swing.UIManager;

public class AddLayerUI extends javax.swing.JFrame {

    public AddLayerUI() {        
        initComponents();
        initOwn();
    }
    
    private void initOwn(){
        Icon icn ;
        icn = UIManager.getIcon("CheckBox.icon") ; //Works but gives only unchecked version of the check box, i need checked as well

        Painter p;

        p = (Painter) UIManager.get("CheckBox[Selected].iconPainter"); // returns null

        BufferedImage selected = new BufferedImage( 20, 20, BufferedImage.TYPE_INT_ARGB ) ;
        p.paint((Graphics2D) selected.getGraphics(), null, 20, 20);
    };
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("AddLayer - TatukGIS DK11 sample");
        setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/icon.png")));
        setSize(new java.awt.Dimension(800, 600));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 800, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 601, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    public static void main(String args[]) {
        /* Set the Windows look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(AddLayerUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(AddLayerUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(AddLayerUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(AddLayerUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>


        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new AddLayerUI().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    // End of variables declaration                   
}

本例将使用UI绘制不同状态的按钮。

(图片有误,左上角应该没有勾选)

import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import java.awt.image.*;
import java.awt.*;
public class Icp{

    public static void main(String[] args){
        JCheckBox canon = new JCheckBox();
        Dimension d = canon.getPreferredSize();
        int w = (int)d.getWidth();
        int h = (int)d.getHeight();
        canon.setBounds(0, 0, w, h);
        BasicToggleButtonUI ui = (BasicToggleButtonUI)UIManager.getUI( canon );
        
        
        BufferedImage img = new BufferedImage(2*w, 2*h, BufferedImage.TYPE_INT_ARGB);
        
        Graphics g = img.getGraphics();
        ui.paint(g, canon);
        
        g.translate( w, 0);
        canon.setSelected(true);
        ui.paint(g, canon);
        
        g.translate(-w, h);
        canon.setEnabled(false);
        canon.setSelected(false);
        ui.paint(g, canon);
        
        g.translate(w, 0);
        canon.setSelected(true);
        ui.paint(g, canon);
        
        g.dispose();

        ImageIcon ico = new ImageIcon(img);
        
        JFrame frame = new JFrame();
        JLabel icn = new JLabel( ico );
        frame.add(icn);
        frame.pack();
        frame.setVisible(true);

        System.out.println( ui );
    }
}

我转换为 BasicToggleButtonUI 因为它有一个图标方法,但它是受保护的。