0

我正在开发一个基于 NetBeans 平台的纸牌游戏,我正在努力了解动态图像。为什么是动态的?好吧,我希望卡片在运行时根据页面的更改(即名称、文本、成本等)进行调整。

我的第一个技巧是创建一个组件(JPanel),其中预先放置了标签,我根据卡片值加载了文本/图像。这似乎工作正常,但是当我想到某些页面在以后的版本中具有不同的外观时(这意味着并非所有内容都在同一个地方),这变得很麻烦。

所以我试图根据某种模板来了解如何做到这一点。

任何想法?

有一个后续问题:JList of cards?

4

1 回答 1

0

最后我有时间回到这个问题上,并且能够找到一种使用 Java 2D 教程的方法。

这些图片与我将在我的应用程序中使用的图片不同,但可以作为概念证明。

包javaapplication3;

导入 java.awt.*;导入 java.awt.font.FontRenderContext;导入 java.awt.font.LineBreakMeasurer;导入 java.awt.font.TextAttribute;导入 java.awt.font.TextLayout;导入 java.awt.image.BufferedImage;导入java.io.File;导入 java.io.IOException;导入 java.net.MalformedURLException;导入 java.net.URL;导入 java.text.AttributedCharacterIterator;导入 java.text.AttributedString;导入 java.util.ArrayList;导入 java.util.HashMap;导入 java.util.logging.Level;导入 java.util.logging.Logger;导入 javax.imageio.ImageIO;

/** * * @author Javier A. Ortiz Bultrón */ public class DefaultImageManager {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    try {
        // TODO code application logic here
        DefaultImageManager manager = new DefaultImageManager();
        URL url = DefaultImageManager.class.getResource("weather-rain.png");
        manager.getLayers().add(ImageIO.read(url));
        url = DefaultImageManager.class.getResource("weather-sun.png");
        manager.getLayers().add(ImageIO.read(url));
        manager.addText(new Font("Arial", Font.PLAIN, 10), "Many people believe that Vincent van Gogh painted his best works "
                + "during the two-year period he spent in Provence. Here is where he "
                + "painted The Starry Night--which some consider to be his greatest "
                + "work of all. However, as his artistic brilliance reached new "
                + "heights in Provence, his physical and mental health plummeted. ",
                200, 150, new Point(0, 0));
        manager.generate();
    } catch (MalformedURLException ex) {
        Logger.getLogger(DefaultImageManager.class.getName()).log(Level.SEVERE,

空,前);} catch (IOException ex) { Logger.getLogger(DefaultImageManager.class.getName()).log(Level.SEVERE, null, ex); } } /** * 用于创建最终图像的层 */ private ArrayList layers = new ArrayList(); 私有 ArrayList textLayers = new ArrayList();

/**
 * @return the layers
 */
public ArrayList<BufferedImage> getLayers() {
    return layers;
}

private Dimension getMaxSize() {
    int width = 0, height = 0;
    for (BufferedImage img : getLayers()) {
        if (img.getWidth() > width) {
            width = img.getWidth();
        }
        if (img.getHeight() > height) {
            height = img.getHeight();
        }
    }
    return new Dimension(width, height);
}

public void addText(Font font, String text, int height, int width, Point location) {
    BufferedImage textImage = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_ARGB);
    HashMap<TextAttribute, Object> map =
            new HashMap<TextAttribute, Object>();
    map.put(TextAttribute.FAMILY, font.getFamily());
    map.put(TextAttribute.SIZE, font.getSize());
    map.put(TextAttribute.FOREGROUND, Color.BLACK);
    AttributedString aString = new AttributedString(text, map);
    AttributedCharacterIterator paragraph = aString.getIterator();
    // index of the first character in the paragraph.
    int paragraphStart = paragraph.getBeginIndex();
    // index of the first character after the end of the paragraph.
    int paragraphEnd = paragraph.getEndIndex();
    Graphics2D graphics = textImage.createGraphics();
    FontRenderContext frc = graphics.getFontRenderContext();
    // The LineBreakMeasurer used to line-break the paragraph.
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
    // Set break width to width of Component.
    float breakWidth = width;
    float drawPosY = 0;
    // Set position to the index of the first character in the paragraph.
    lineMeasurer.setPosition(paragraphStart);

    // Get lines until the entire paragraph has been displayed.
    while (lineMeasurer.getPosition() < paragraphEnd) {
        // Retrieve next layout. A cleverer program would also cache
        // these layouts until the component is re-sized.
        TextLayout layout = lineMeasurer.nextLayout(breakWidth);

        // Compute pen x position. If the paragraph is right-to-left we
        // will align the TextLayouts to the right edge of the panel.
        // Note: this won't occur for the English text in this sample.
        // Note: drawPosX is always where the LEFT of the text is placed.
        float drawPosX = layout.isLeftToRight()
                ? 0 : breakWidth - layout.getAdvance();

        // Move y-coordinate by the ascent of the layout.
        drawPosY += layout.getAscent();

        // Draw the TextLayout at (drawPosX, drawPosY).
        layout.draw(graphics, drawPosX, drawPosY);

        // Move y-coordinate in preparation for next layout.
        drawPosY += layout.getDescent() + layout.getLeading();
    }
    getTextLayers().add(textImage);
}

public void generate() throws IOException {
    Dimension size = getMaxSize();
    BufferedImage finalImage = new BufferedImage(size.width, size.height,
            BufferedImage.TYPE_INT_ARGB);
    for (BufferedImage img : getLayers()) {
        finalImage.createGraphics().drawImage(img,
                0, 0, size.width, size.height,
                0, 0, img.getWidth(null),
                img.getHeight(null),
                null);
    }
    for(BufferedImage text: getTextLayers()){
        finalImage.createGraphics().drawImage(text,
                0, 0, text.getWidth(), text.getHeight(),
                0, 0, text.getWidth(null),
                text.getHeight(null),
                null);
    }
    File outputfile = new File("saved.png");
    ImageIO.write(finalImage, "png", outputfile);
}

/**
 * @return the textLayers
 */
public ArrayList<BufferedImage> getTextLayers() {
    return textLayers;
}

/**
 * @param textLayers the textLayers to set
 */
public void setTextLayers(ArrayList<BufferedImage> textLayers) {
    this.textLayers = textLayers;
} }

它仍然需要对文本的位置进行一些特别的改进,但它确实有效。我想我可以实现一个 xml 格式来存储所有这些信息,因此很容易配置。在下面的示例中,太阳被绘制在雨之上,而文本则位于所有之上。对于我的应用程序,每一层都将构建我想要的页面。

以下是我使用的图片: 在此处输入图像描述 在此处输入图像描述

最后的结果:

在此处输入图像描述

于 2011-11-22T23:08:25.937 回答