gpt4 book ai didi

java - 将字符串的ArrayList对齐到(custom)Box中将无法正确定位

转载 作者:行者123 更新时间:2023-11-30 08:03:21 25 4
gpt4 key购买 nike

在Java中将一组字符串对齐到框的底部时,我遇到了一个小问题。


  注意:我使用的Box类不是默认的> javax.Swing框!这是一个简单的服装盒,具有x,y位置以及宽度和高度!


我目前有什么?


一个Message类,可以由我的Allign类单独对齐。
一个MessageList对象,它包含一个Message对象的ArrayList,可以与Allign类对齐。
包含框的位置和尺寸的Box对象。 Allign类使用此框将对象对齐。
Allign类可以对齐不同类型的对象,并使用Box对象进行对齐。


我的代码应如何工作:

(页面下方的代码段)

Message对象可以使用不同的Font设置。 Allign类可以对齐这些Message的对象。 Message类包含一个名为obtainFontDimension()的方法,该方法在首选的Font设置中获取对象的String的范围。当我们想将对齐方式应用于Message对象时,我创建一个Box对象,其中包含x,y位置以及宽度和高度。通过调用Allign.applyAllignment(params),将应用计算以对齐Message中的Box对象,并设置Message的dx,dy(绘制x,y位置)。

到这里为止一切正常。

现在,我创建一个MessageList对象并向其中添加一些(Message对象。对此进行对齐时,它将遍历它包含的Message对象,并在它们上调用obtainFontDimensions()。高度这些字符串中的所有字符将被求和,并得出这些字符串的总高度(int listHeight)。要获取每个Message对象的绘制位置,我们将Box的y位置取为对齐。首先我们删除listHeight'sy位置的Box



现在我们得到了第一个字符串的偏移量。当应用底部对齐方式时,它只是将Box的高度添加到偏移量中。最后,通过将当前Message对象的高度添加到te offset中,为下一个Message对象设置偏移量。下一次迭代的时间,直到ArrayList被完全计算为止。这将导致以下结果:



怎么了?

将对齐方式应用于MessageList对象时,一些字符串彼此完美地接触(请参见图像上的圆圈B),而某些字符串与其他像素之间的距离要比其他像素更长(请参见图像上的圆圈A1,A2)。紧接着,在底部保留了意外的填充(请参见图像上的圆圈C)。



到目前为止,我尝试了什么?


首先,我一直在检查字符串的高度,这似乎都是正确的。因此,`obtainFontDimensions()`方法似乎运行良好。
在纸上画出这个概念,并尝试重新计算该过程,这应该使我获得Strings的正确位置。例如:
-`Box':x = 80,y = 80,宽度= 100,高度= 100
-具有3个“消息”的“消息列表”,其高度为0 = 10、1 = 10、2 = 20。这些字符串的总高度为40像素。
-在实际分配之前,第一个String的位置变为box.y-listHeight,为40。
-当实际对齐底部时,偏移量变为40 + 100 = 140。
-将计算第二个字符串的偏移量:140 + 20(当前消息的高度)= 160。
-重复第三个字符串,即160 + 10 = 170。
-这就是说,最后一个字符串的底线是170 + 10 = 180,等于“ Box”底端的底端。

您的建议...?


代码段

(仅重要部分)

public class Window()
{
public void draw(Graphics2D g2d)
{
Box contentBox = new Box(100, 100, 300, 300);
Message loadTitle = new Message("This is a testing TITLE", Colors.ORANGE, Fonts.LOADING_TITLE, false);
Message loadDescription = new Message(loadString, Colors.RED, Fonts.LOADING_DESCRIPTION, false);
Message loadTip = new Message("This is a random TIP!", Colors.RED, Fonts.LOADING_DESCRIPTION, false);
Message loadRelease = new Message("Planned game release 2939!", Colors.RED, Fonts.LOADING_DESCRIPTION, false);
Message loadSingle = new Message("THIS IS A SINGLE MESSAGE! 2o15", Colors.RED, Fonts.LOADING_DESCRIPTION, false);

MessageList list = new MessageList();
list.add(loadTitle);
list.add(loadDescription);
list.add(loadTip);
list.add(loadRelease);
list.add(loadSingle);
Allign.applyAllignment(g2d, Allignment.BOTTOM_RIGHT, list, loadBox);

loadBox.testDraw(g2d);
loadTitle.draw(g2d);
loadDescription.draw(g2d);
loadTip.draw(g2d);
loadRelease.draw(g2d);
loadSingle.draw(g2d);
}
}

public class Message
{
private String text;
private Color color;
private Font font;
private int dx, dy;
private int width, height;
private Rectancle2D vb; // temp

public Message(String text, int x, int y, Color color, Font font)
{
// set text, color, font, x, y..
}
public Rectangle2D obtainFontDimension(Graphics2D g2d)
{
if(font == null){ font = Fonts.DEFAULT; }
g2d.setFont(font);

FontRenderContext frc = g2d.getFontRenderContext();
GlyphVector gv = g2d.getFont().createGlyphVector(frc, text);
Rectangle2D vb = gv.getPixelBounds(null, 0, 0);

this.width = (int)vb.getWidth();
this.height = (int)vb.getHeight();
this.gv = gv; // TEMP for bound drawing

return vb;
}
public void draw(Graphics2D g2d)
{
g2d.setFont(font);
g2d.setColor(color);
g2d.drawString(text, dx, dy);

// TEMP draw bounds
g2d.setColor(new Color(0, 0, 0, 100));
g2d.draw(gv.getPixelBounds(null, dx, dy));
}
}

public class Allign
{
public static enum Allignment
{
BOTTOM_RIGHT
//, etc
}
public static void applyAllignment(Graphics2D g2d, Allignment allignment, Object object, Box box)
{
Point position = null;
Point dimension = null;

if(obj instanceof Message){ // Single Message object }
else if(obj instanceof Message)
{
MessageList messageList = (MessageList) obj;

int listHeight = 0;
for(Message message : messageList.getList())
{
listHeight += message.obtainFontDimension(g2d).getHeight();
}
position = new Point(box.x, box.y-listHeight); // offset Y

for(Message message : messageList.getList())
{
message.setDrawPosition(allign(allignment, position, new Dimension(message.getWidth(), 0), box, true));
position.y += message.getHeight();
}
}
}
private static Point allign(Allignment allignment, Point position, Dimension dimension, Box box, boolean verticalAllign)
{
switch(allignment)
{
case BOTTOM_RIGHT:
position = allignRight(position, dimension, box);
if(!verticalAllign) break;
position = allignBottom(position, dimension, box);
break;
// Rest
}
}
private static Point allignBottom(Point position, Dimension dimension, Box box)
{
return new Point(position.x, position.y+box.height-dimension.height);
}
}

最佳答案

我可以建议这样的实用程序类吗?

public class TextPrinter {

public enum VerticalAlign {

TOP,
MIDDLE,
BOTTOM
}

public enum HorizontalAlign {

LEFT,
CENTER,
RIGHT
}

private Font font;
private Color color;
private int width;
private int height;
private VerticalAlign vAlign = VerticalAlign.TOP;
private HorizontalAlign hAlign = HorizontalAlign.LEFT;

public Font getFont() {
return font;
}

public void setFont(Font font) {
this.font = font;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

public VerticalAlign getVerticalAlign() {
return vAlign;
}

public void setVerticalAlign(VerticalAlign vAlign) {
this.vAlign = vAlign;
}

public HorizontalAlign getHorizontalAlign() {
return hAlign;
}

public void setHorizontalAlign(HorizontalAlign hAlign) {
this.hAlign = hAlign;
}

public Color getColor() {
return color;
}

public void setColor(Color color) {
this.color = color;
}

private int getOffSetX(int widthText){
int result = 0;
if (hAlign == HorizontalAlign.CENTER){
result = (width - widthText)/2;
} else if (hAlign == HorizontalAlign.RIGHT){
result = width - widthText;
}
return result;
}

private int getOffSetY(int ascent, int descent){
int result = ascent;
if (vAlign == VerticalAlign.MIDDLE){
result = (height + ascent - descent)/2;
} else if (vAlign == VerticalAlign.BOTTOM){
result = height - descent;
}
return result;
}

public void print(Graphics g, String text, int x, int y) {
g.setColor(color);
g.setFont(font);
FontMetrics fm = g.getFontMetrics(font);

int widthText = fm.stringWidth(text);
g.drawString(text, x + getOffSetX(widthText), y + getOffSetY(fm.getAscent(), fm.getDescent()));
}
}


我在扑克游戏中使用它:
https://github.com/dperezcabrera/jpoker

关于java - 将字符串的ArrayList对齐到(custom)Box中将无法正确定位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31548488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com