1

所以,我一直在修改 Minecraft 一段时间,我看到了它是如何生成按钮的。它需要一个非常宽的按钮图像,占据左侧的一部分,占据右侧的一部分,然后将两者重新组合在一起形成一个较小的图像。

很抱歉,我无法用语言很好地解释这一点,所以让我向您展示一下糟糕的 Paint.Net 技能:

解释

但是,我无法让它工作,结果是这样的: 结果是

这是我的代码的一部分:

public class ComponentToolbarButton extends JComponent implements MouseListener {

    private static final int HEIGHT = 40;

    // ... other methods here

    private BufferedImage getImageBasedOnWidth(Graphics g) {
        BufferedImage finalImage = null;
        BufferedImage rawImage = null;


         // Try/catch block to initialize rawImage

         // Setting font and things here        

        int compWidth = determineComponentWidth(g); // Returns the (should-be) width of the component

        if (compWidth != getWidth()) { 
            setPreferredSize(new Dimension(compWidth, HEIGHT)); // Just making sure :)
        }

        finalImage = new BufferedImage(compWidth, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics finalImageGraphics = finalImage.getGraphics();


        // Draw left side:
        finalImageGraphics.drawImage(rawImage, 0, 0, 0, compWidth / 2, 0, 0, compWidth, HEIGHT, null);

        // Draw right side:
        finalImageGraphics.drawImage(rawImage, compWidth / 2, 0, compWidth, HEIGHT, rawImage.getWidth() / 2 - compWidth,
            0, rawImage.getWidth(), rawImage.getHeight(), null);


        return finalImage;
    }
}

提前致谢!(顺便说一句,我试图尽可能地缩短代码)

4

2 回答 2

2

好的,经过一番思考,我想出了这个小技巧来展示我认为它应该如何工作:P

public class TestMenu extends JComponent {

    protected static final int MAX_HEIGHT = 40;
    protected static final int LEFT_MARGIN = 5;
    protected static final int RIGHT_MARGIN = 5;

    protected static final ImageIcon BACKGROUND = new ImageIcon(TestMenu.class.getResource("/Menu.png"));

    private String text;

    public TestMenu() {

        setOpaque(false);
        text  = "This is some text";
        setFont(UIManager.getFont("Label.font"));

    }

    @Override
    public Dimension getPreferredSize() {

        FontMetrics fm = getFontMetrics(getFont());
        int width = fm.stringWidth(text) + LEFT_MARGIN + RIGHT_MARGIN;

        Dimension size = new Dimension(width, MAX_HEIGHT);

        return size;

    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        int width = getWidth() - 1;
        int height = getHeight() - 1;

        BufferedImage imgLeft = new BufferedImage(LEFT_MARGIN, MAX_HEIGHT, BufferedImage.TYPE_INT_ARGB);
        BufferedImage imgRight = new BufferedImage(RIGHT_MARGIN, MAX_HEIGHT, BufferedImage.TYPE_INT_ARGB);
        BufferedImage imgBody = new BufferedImage(width - LEFT_MARGIN - RIGHT_MARGIN, MAX_HEIGHT, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2d = imgLeft.createGraphics();
        g2d.drawImage(BACKGROUND.getImage(), 0, 0, this);
        g2d.dispose();

        g2d = imgRight.createGraphics();
        g2d.drawImage(BACKGROUND.getImage(), RIGHT_MARGIN - BACKGROUND.getIconWidth(), 0, this);
        g2d.dispose();

        g2d = imgBody.createGraphics();
        g2d.drawImage(BACKGROUND.getImage(), -LEFT_MARGIN, 0, this);
        g2d.dispose();

        g2d = (Graphics2D) g;

        g2d.drawImage(imgLeft, 0, 0, this);
        g2d.drawImage(imgBody, LEFT_MARGIN, 0, this);
        g2d.drawImage(imgRight, width - RIGHT_MARGIN, 0, this);

        FontMetrics fm = g2d.getFontMetrics();

        int x = (width - fm.stringWidth(text)) / 2;
        int y = ((height - fm.getHeight()) / 2) + fm.getAscent();

        g2d.setColor(Color.WHITE);
        g2d.drawString(text, x, y);


    }

}

首先,永远不要尝试在该paint方法中构建所有图像片段,它会减慢绘制程序并消耗大量内存,但对于这个示例,我只是想演示一下这个想法。改用后备缓冲区(我认为这就是你想要做的)。

这将产生:

在此处输入图像描述

于 2012-08-04T21:54:42.383 回答
1

也许坐标在调用中混淆了drawImage

boolean Graphics.drawImage(Image img,
       int dstx1, int dsty1, int dstx2, int dsty2,
       int srcx1, int srcy1, int srcx2, int srcy2,
       ImageObserver observer);

宽度和高度尺寸是根据以下公式计算的:(dstx2-dstx1), (dsty2-dsty1)

在左侧试试这个:

finalImageGraphics.drawImage(rawImage, 
        0, 0, compWidth / 2, HEIGHT, 
        0, 0, rawImage.getWidth() / 2, rawImage.getHeight(),
        null);

绘制图像是该主题的一个很好的教程。

于 2012-08-04T21:29:17.343 回答