在JLabel中获取Icon位置

时间:2014-12-11 11:04:00

标签: java swing jlabel paintcomponent mouselistener

我试图在JLabel的Icon上显示网格(和其他项目),但我无法弄清楚如何根据其布局获取图标坐标。

P.S。由于我还需要鼠标支持,我无法使用setIcon()

破解图标内的绘图操作
public class ExtendedJLabel extends JLabel implements MouseMotionListener
{
    private final int GRID_STEP = 16;

    public ExtendedJLabel()
    {
        super();
        setOpaque(true);
        setBackground(UIManager.getColor("controlShadow");
        addMouseMotionListener(this);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        if(icon == null)
            return;

        // Icon Origin
        int ox = ...;
        int oy = ...;

        // Draw grid
        g.setColor(UIManager.getColor("controlShadow"));

        for(int row = 0; row < getIcon().getIconHeight() / GRID_STEP; row++)
            g.drawLine(ox, oy + row * GRID_STEP, ox + getIcon().getIconWidth(), oy + row * GRID_STEP);

        for(int col = 0; col < getIcon().getIconWidth() / GRID_STEP; col++)
            g.drawLine(ox + col * GRID_STEP, oy, ox + col * GRID_STEP, oy + getIcon().getIconHeight());
    }

    @Override
    public void mouseMoved(MouseEvent me)
    {
        // ...
    }

    @Override
    public void mouseDragged(MouseEvent me)
    {
        // ...
    }
}

1 个答案:

答案 0 :(得分:3)

  

我无法弄清楚如何根据布局获取图标坐标。

我相信你可以使用SwingUtiltities.layoutCompoundLabel(...)方法。

你可以:

  1. 创建自定义JLabel并覆盖paintComponent()方法以绘制网格,或
  2. 使用JLayer
  3. 由于我没有使用过JLayer,所以使用这种方法就是一个例子:

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.plaf.*;
    
    public class LabelIconGridUI extends LayerUI<JComponent>
    {
        @Override
        public void paint(Graphics g, JComponent c)
        {
            super.paint(g, c);
    
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setColor( Color.ORANGE );
    
            JLayer jlayer = (JLayer)c;
            JLabel label = (JLabel)jlayer.getView();
    
            Rectangle viewR = new Rectangle();
            viewR.width = label.getSize().width;
            viewR.height = label.getSize().height;
            Rectangle iconR = new Rectangle();
            Rectangle textR = new Rectangle();
    
            String clippedText = SwingUtilities.layoutCompoundLabel
            (
                label,
                g2.getFontMetrics(),
                label.getText(),
                label.getIcon(),
                label.getVerticalAlignment(),
                label.getHorizontalAlignment(),
                label.getVerticalTextPosition(),
                label.getHorizontalTextPosition(),
                viewR,
                iconR,
                textR,
                label.getIconTextGap()
            );
    
            int gridSize = 10;
            int start = iconR.x + gridSize;
            int end = iconR.x + iconR.width;
    
            for (int i = start; i < end; i += gridSize)
            {
                g2.drawLine(i, iconR.y, i, iconR.y + iconR.height);
            }
    
            g2.dispose();
        }
    
        private static void createAndShowUI()
        {
            JLabel label = new JLabel("Some Text" );
            label.setIcon( new ImageIcon( "DukeWaveRed.gif" ) );
    
            label.setVerticalAlignment( JLabel.CENTER );
            label.setHorizontalAlignment( JLabel.CENTER );
            label.setVerticalTextPosition( JLabel.BOTTOM );
            label.setHorizontalTextPosition( JLabel.CENTER );
    
            LayerUI<JComponent> layerUI = new LabelIconGridUI();
            JLayer<JComponent> layer = new JLayer<JComponent>(label, layerUI);
    
            JFrame frame = new JFrame("Label Icon Grid");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( layer );
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }