【问题标题】:Java bubble image adapt to text sizeJava气泡图适应文字大小
【发布时间】:2013-12-10 21:23:26
【问题描述】:

我正在尝试构建某种信使服务,但在呈现文本气泡时遇到问题。我首先将一个气泡分成 9 个图像,四个角是静态的。我遇到的问题是 NORTH、SOUTH、EAST 和 WEST 图像。

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

我环顾四周,但很多都是 Android 或 IOS 解决方案。 Java 中是否有重复功能,并且可以在不重新调整导致图像失真的paintComponent 内的图像大小的情况下执行此操作。

这是我尝试生成气泡时得到的结果:

欢迎提出任何想法!

【问题讨论】:

  • 提供一些我们可以适应的代码?否则我们会在黑暗中猜测你是如何编写程序的。
  • @kevinsa5 你说得对,提供代码总是一件好事,但大多数情况下,如果提供了代码,你会得到问题的答案,但不一定能理解。这就是为什么我要征求意见的原因:P

标签: java image swing jpanel


【解决方案1】:

可以使用Graphics.drawImage(x, y, w, h, null) 缩放图像。南北比例为 1 像素宽度的图像的宽度,东西方向类似。

【讨论】:

    【解决方案2】:

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

    虽然我毫不怀疑缩放会起作用,但它看起来有多好取决于源图像的好坏,并且在缩放图像时可能会产生不良的伪影。

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

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

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

    以下是平铺示例

    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();
                }
            }
    
        }
    
    }
    

    【讨论】:

    • 当您说“标题”时,您的意思是“平铺”吗?
    • 不,我想我的意思是,“我已经醒了很久,需要一些睡眠”:P - 谢谢,我想我已经全部纠正了......
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-03
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多