Как сделать динамический образ во время выполнения?

Я работаю над карточной игрой на платформе NetBeans и изо всех сил пытаюсь понять динамические изображения. Почему динамический? Ну, я хочу, чтобы карты адаптировались во время выполнения к изменениям на странице (например, имя, текст, стоимость и т. д.).

Моим первым взломом было создание компонента (JPanel) с предварительно размещенными метками, куда я загружал текст/изображение на основе значений карты. Кажется, это работает нормально, но потом стало хлопотно, когда я подумал о том, что некоторые страницы в более поздних выпусках выглядят по-другому (это означает, что не все будет на одном месте).

Поэтому я пытаюсь получить представление о способах сделать это на основе какого-то шаблона.

Есть идеи?

Есть дополнительный вопрос по адресу: JList ofcards?


person javydreamercsw    schedule 11.10.2011    source источник
comment
Можете ли вы опубликовать какие-либо изображения для пояснения? это не так ясно :(   -  person Ayyappa    schedule 11.10.2011
comment
Я не могу получить доступ к ним с работы прямо сейчас, но вы можете обратиться к ссылке здесь, чтобы получить представление: en. wikipedia.org/wiki/WWE_with_Authority! Моя игра основана на этом.   -  person javydreamercsw    schedule 11.10.2011
comment
ссылка не работает...можете нарисовать грубый набросок что именно вы имеете в виду...или постарайтесь сформулировать вопрос подробно,пожалуйста...   -  person Ayyappa    schedule 11.10.2011
comment
Почему-то восклицательный знак не попал в ссылку.   -  person javydreamercsw    schedule 11.10.2011
comment
Я работаю над этим прямо сейчас...   -  person javydreamercsw    schedule 11.10.2011
comment
То есть вы имеете в виду, что на каждой карточке будет текст, фото, стоимость, размещенные в разных местах... и вы хотите найти способ отображать такие данные во время выполнения, верно?   -  person Ayyappa    schedule 11.10.2011
comment
давайте продолжим обсуждение в чате   -  person Ayyappa    schedule 11.10.2011
comment
Я получил сообщение поздно и никогда не мог добраться до чата вовремя. Чтобы ответить на ваш вопрос, да, я хотел бы иметь возможность изменять расположение компонентов (для разных наборов карт) и создавать их во время выполнения.   -  person javydreamercsw    schedule 17.11.2011


Ответы (1)


Наконец, у меня появилось время вернуться к этому и найти способ, используя Руководство по 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 Хавьер А. Ортис Бултрон */ 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 ArrayListlayers = new ArrayList(); частный ArrayList textLayers = новый 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 для хранения всей этой информации, поэтому его легко настроить. В приведенном ниже примере солнце нарисовано поверх дождя, а текст — поверх всего этого. Для моего приложения каждый слой будет собирать страницу, которую я хочу.

Вот изображения, которые я использовал: введите здесь описание изображениявведите здесь описание изображения

И окончательный результат:

введите здесь описание изображения

person javydreamercsw    schedule 22.11.2011