java - Alligning an ArrayList of Strings into a (custom)Box won't get in proper position [solved] -
i've got little problem alligning group of strings bottom of box in java.
note: box class i'm using not default > javax.swing box! it's simple costum box x, y position, , width , height!
what have?
- - message class can individually alligned allign class.
- messagelist object containing arraylist of message objects can alligned allign class.
- box object contains position , dimension of box. allign class uses box allign objects in.
- allign class can allign different types of objects, , use box object allign in.
how code should work:
(code snippets further down page)the message object can use different font settings. allign class can allign these messages objects. message class contains method called obtainfontdimension(), gets bounds of object's string in preferred font settings. when want apply allignment message object, create box object contains x,y position , width , height. calling allign.applyallignment(params) calculations applied allign message object in box, , message's dx, dy (drawing x, y positions) set.
till here works fine...
now create messagelist object , add ( message objects it. when applying allignment this, run through message objects contains, , call obtainfontdimensions() on them. height of these strings summed, , results total height (int listheight) of strings together. drawing position of each message object, take y-position of box want allign in. first remove listheight of box's y position:
now got offset of first string. when bottom allignment being applied, adds height of box offset. finally, offset set next message object adding current message object height te offset. time next itteration, till arraylist has been calculated. should result in following:
what going wrong?
when applying allignment messagelist object, strings touch eachother (see circle b on image), , keep pixels more distance others (see circle a1, a2 on image). , next that, there remains unexpected padding on bottom (see circle c on image).
what have attempted far?
- first i've been checking height of strings, seem correct. obtainfontdimensions() method seems working fine.
- drawing concept on paper, , attempt recalculate procedure, should me correct position of strings. example:
- - box: x=80, y=80, width=100, height=100
- messagelist 3 messages, have height of 0=10, 1=10, 2=20. total height of these strings 40 pixels.
- before alligning, position of first string becomes box.y-listheight, 40.
- when alligning bottom, the offset becomes 40+100=140.
- offset second string calculated: 140+20(current message's height)=160.
- repeats third string, is 160+10 = 170. - means, bottom line of final string on 170+10 = 180, equals bottom of box's bottom. - your suggestion...?
code snippets
(only important parts)if think need more parts of code, let me know! think/hope should enough.
public class window() { public void draw(graphics2d g2d) { box contentbox = new box(100, 100, 300, 300); message loadtitle = new message("this testing title", colors.orange, fonts.loading_title, false); message loaddescription = new message(loadstring, colors.red, fonts.loading_description, false); message loadtip = new message("this 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 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 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); } }
final world i've done best explain problem possible. if need more information or code, please let me know! willing take me, , attempt me out.. big thanks!
can suggest utility class this?
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())); } }
i use in poker game: https://github.com/dperezcabrera/jpoker
Comments
Post a Comment