Java气泡图像适应文本大小

时间:2013-12-10 21:23:26

标签: java image swing jpanel

我正在尝试构建某种信使服务,但我遇到了渲染文本泡泡的问题。我开始将气泡分成9个图像,四个角落是静态的。我有问题的地方是NORTH,SOUTH,EAST和WEST图像。

我希望他们重复自己类似于CSS选项重复。基本上,使气泡适应内容。

我环顾四周,但很多是Android或IOS解决方案。 Java中是否存在重复功能,并且无需重新调整paintComponent中的图像大小,从而导致图像失真。

以下是我尝试生成气泡时的情况:

bubble 1 bubble 2

欢迎任何想法!

3 个答案:

答案 0 :(得分:3)

可以使用Graphics.drawImage(x, y, w, h, null)缩放图像。对于南北尺度,图像宽度为1像素宽,东西方也相似。

答案 1 :(得分:2)

要添加到@Joop Eggen的答案,您基本上需要将您的北部和南部图像缩放为必要的宽度,并将您的东部和西部图像调整为必要的高度。

它看起来像下面的东西。您将拥有8或9张图像,具体取决于您是否有中心图像。您可以将北部和南部缩放到innerWidth = outerWidth - 2 * borderWidth的宽度;您的东西方向将垂直缩放到innerHeight = outerHeight - 2 * borderHeight的高度。

enter image description here

答案 2 :(得分:2)

您有(至少)两种选择。您可以根据需要平铺图像元素,也可以缩放它们以适应。

虽然毫无疑问缩放会起作用,但它的外观有多好取决于源图像的好坏,并且在缩放图像时可能会产生不希望的伪像。

或者,您可以平铺图像以填充可用空间。根据图像的大小和复杂程度以及倾斜的区域,渲染器可能需要一些时间。

显然,平铺/缩放和图像的时间可以通过缓冲结果来缓解,并且仅在输出发生变化时重新生成输出。

最终解决方案将归结为您希望实现的目标。

以下是平铺的示例

BubbleText BubbleTtext

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class BubbleTextTest {

    public static void main(String[] args) {
        new BubbleTextTest();
    }

    public BubbleTextTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel label;

        public TestPane() {

            String text = "<html>I am the very model of a modern Major-General,<br>";
            text += "I've information vegetable, animal, and mineral,<br>";
            text += "I know the kings of England, and I quote the fights historical<br>";
            text += "From Marathon to Waterloo, in order categorical;a<br>";
            text += "I'm very well acquainted, too, with matters mathematical,<br>";
            text += "I understand equations, both the simple and quadratical,<br>";
            text += "About binomial theorem I'm teeming with a lot o' news, (bothered for a rhyme)<br>";
            text += "With many cheerful facts about the square of the hypotenuse.<br>";

            label = new JLabel(text);

            setBackground(new Color(209, 209, 209));

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            try {
                add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/TopLeft.png")))), gbc);
                gbc.gridx = 2;
                add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/TopRight.png")))), gbc);

                gbc.gridy = 2;
                gbc.gridx = 0;
                add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/BottomLeft.png")))), gbc);
                gbc.gridx = 2;
                add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/BottomRight.png")))), gbc);

                gbc.gridx = 1;
                gbc.gridy = 0;
                gbc.weightx = 1;
                gbc.fill = GridBagConstraints.HORIZONTAL;
                add(new FillerPane(ImageIO.read(getClass().getResource("/Top.png")), FillDirection.HORIZONTAL), gbc);
                gbc.gridy = 2;
                add(new FillerPane(ImageIO.read(getClass().getResource("/Bottom.png")), FillDirection.HORIZONTAL), gbc);

                gbc.gridx = 0;
                gbc.gridy = 1;
                gbc.weighty = 1;
                gbc.weightx = 0;
                gbc.fill = GridBagConstraints.VERTICAL;
                add(new FillerPane(ImageIO.read(getClass().getResource("/Left.png")), FillDirection.VERTICAL), gbc);
                gbc.gridx = 2;
                add(new FillerPane(ImageIO.read(getClass().getResource("/Right.png")), FillDirection.VERTICAL), gbc);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            gbc.gridx = 1;
            gbc.gridy = 1;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(label, gbc);
        }

    }

    public enum FillDirection {
        HORIZONTAL,
        VERTICAL
    }

    public class FillerPane extends JPanel {

        private BufferedImage img;
        private FillDirection fillDirection;

        public FillerPane(BufferedImage img, FillDirection fillDirection) {
            this.img = img;
            this.fillDirection = fillDirection;
        }

        @Override
        public Dimension getPreferredSize() {
            return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
        }

        @Override
        public Dimension getMinimumSize() {
            return getPreferredSize();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            if (img != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = 0;
                int y = 0;
                int xDelta = 0;
                int yDelta = 0;
                switch (fillDirection) {
                    case HORIZONTAL:
                        xDelta = img.getWidth();
                        break;
                    case VERTICAL:
                        yDelta = img.getHeight();
                        break;
                }
                while (x < getWidth() && y < getHeight()) {
                    g2d.drawImage(img, x, y, this);
                    x += xDelta;
                    y += yDelta;
                }
                g2d.dispose();
            }
        }

    }

}