我正在尝试构建某种信使服务,但我遇到了渲染文本泡泡的问题。我开始将气泡分成9个图像,四个角落是静态的。我有问题的地方是NORTH,SOUTH,EAST和WEST图像。
我希望他们重复自己类似于CSS选项重复。基本上,使气泡适应内容。
我环顾四周,但很多是Android或IOS解决方案。 Java中是否存在重复功能,并且无需重新调整paintComponent中的图像大小,从而导致图像失真。
以下是我尝试生成气泡时的情况:
欢迎任何想法!
答案 0 :(得分:3)
可以使用Graphics.drawImage(x, y, w, h, null)缩放图像。对于南北尺度,图像宽度为1像素宽,东西方也相似。
答案 1 :(得分:2)
要添加到@Joop Eggen的答案,您基本上需要将您的北部和南部图像缩放为必要的宽度,并将您的东部和西部图像调整为必要的高度。
它看起来像下面的东西。您将拥有8或9张图像,具体取决于您是否有中心图像。您可以将北部和南部缩放到innerWidth = outerWidth - 2 * borderWidth
的宽度;您的东西方向将垂直缩放到innerHeight = outerHeight - 2 * borderHeight
的高度。
答案 2 :(得分: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();
}
}
}
}