我如何正确对齐这段文字? [英] How do i align this text correctly?
问题描述
我今天写这个时钟极性和我差不多完成了exept我要对齐我类似的线内文本这。有谁知道如何做到这一点?香港专业教育学院试图使用的FontRenderContext和字体规格,但我似乎无法得到它的工作。这里是整个源$ C $ C,所以你可以编译它,并亲眼看一下。
进口java.applet.Applet中;
进口java.awt.AWTEvent中;
进口java.awt.Color中;
进口java.awt.Font中;
进口java.awt.FontMetrics中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.RenderingHints中;
进口java.awt.Shape中;
进口java.awt.Toolkit中;
进口java.awt.font.FontRenderContext;
进口java.awt.font.GlyphVector中;
进口java.awt.geom.AffineTransform中;
进口java.awt.geom.Arc2D中;
进口java.awt.geom.Point2D中;
进口java.awt.image.BufferedImage中;
进口java.awt.image.WritableRaster中;
进口的java.util.Calendar;
进口java.util.TimeZone中;公共类时钟小程序扩展实现Runnable {INT [] [] colorsInt = {{20,20,20},{100,100,50},{50100100},{10,170,50},{79,29,245},{24,69,234},{253,24,103}} ;
颜色[]颜色;
INT大小;
INT半径;
布尔anitalias = FALSE;
静态最终浮动HPI =(浮点)(Math.PI / 180F);公共无效的start(){
enableEvents方法(AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
新的Thread(本)。开始();
}公共无效的run(){
的setSize(500,500); //对于appletviewer中,以后删除。 //设置显卡的东东,双缓冲。
屏幕的BufferedImage =新的BufferedImage(800,600,BufferedImage.TYPE_INT_RGB);
Graphics2D的G =(Graphics2D的)screen.getGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
WR的WritableRaster = screen.getRaster();
图形appletGraphics =的getGraphics(); //某些变量以用于帧。
长fpstn =600分之1000000000;
INT剔= 0,FPS = 0,ACC = 0;
长lastTime = System.nanoTime(); //瓦尔
日历℃;
大小= 500;
半径=大小/ 2;
Arc2D.Float此类拱;
浮规模,弧度;
长毫秒;
诠释秒,分钟,小时,月,年,星期,请将dayOfMonth,DAYOFYEAR,daysInMonth,DAYSINYEAR;
浮动[] = tvars新的浮动[6];
浮动[] =瓦尔新的浮动[6];
的String [] =名新的String [6];
FontMetrics对象FM = g.getFontMetrics();
字体字型= g.getFont();
FRC的FontRenderContext = g.getFontRenderContext();
GlyphVector的GV = font.createGlyphVector(FRC,世界,你好);
INT长度= gv.getNumGlyphs(); // 在里面
initColors();
的for(int i = 0; I< vars.length;我++)
瓦尔[I] = 0; //游戏循环。
而(真){
长今= System.nanoTime();
ACC + =现在 - lastTime;
勾选++;
如果(ACC> = 1000000000L){
ACC - = 1000000000L;
FPS =打勾;
勾选= 0;
} //更新
C = Calendar.getInstance();
毫秒= c.get(Calendar.MILLISECOND);
第二= c.get(Calendar.SECOND);
分钟= c.get(Calendar.MINUTE);
小时= c.get(Calendar.HOUR_OF_DAY);
请将dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
DAYOFYEAR = c.get(Calendar.DAY_OF_YEAR);
一周中的某天= c.get(Calendar.DAY_OF_WEEK);
月= c.get(的Calendar.MONTH);
daysInMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
DAYSINYEAR = c.getActualMaximum(Calendar.DAY_OF_YEAR); tvars [0] =(第二* 1000 +毫秒)/ 60000f * 360F;
tvars [1] =(分* 60F +秒)/ 3600f * 360F;
tvars [2] =(小时* 60F +分钟)/ 1440f * 360F;
tvars [3] =((一周中的某天 - 2)* 24F +小时)/ 168F * 360F;
tvars [4] =((请将dayOfMonth - 1)* 24F +小时)/(daysInMonth * 24F)* 360F;
tvars [5] = DAYOFYEAR /(浮点)DAYSINYEAR * 360F; 的for(int i = 0; I< vars.length;我++){
如果(tvars [I] - 瓦尔[I]→1){
瓦尔[I] + =(tvars [I] - 瓦尔[I])/ 15;
}否则如果(tvars [I] - 瓦尔[1] - ; - 1){
瓦尔[Ⅰ] - =(瓦尔[I] - tvars [I])/ 15;
}其他{
瓦尔[I] = tvars [I]
}
} 名字[0] =第二+秒+(第二个→1S:); lastTime =现在; //渲染
g.setColor(颜色[0]);
g.fillRect(0,0,尺寸,大小);
的for(int i = 0; I< vars.length;我++){ 规模= I /(浮点)vars.length *半径* 1.7f;
g.setColor(颜色[0]);
g.fillOval((int)的(比例/ 2),(INT)(比例/ 2),(INT)(大小 - 规模),(INT)(大小 - 尺度));
g.setColor(颜色[I + 1]);
规模+ = 15;
ARCH =新Arc2D.Float此类(规模/ 2,规模/ 2,大小 - 规模大小 - 规模,450 - 瓦尔[I],瓦尔[I],Arc2D.PIE);
g.fill(拱); g.setColor(Color.WHITE);
弧度=(瓦尔[I])* HPI; //瓦尔[Ⅰ] - 90
规模=((浮点)(vars.length - I)/(浮点)vars.length *(浮点)半径/ 2F * 1.7f)+ 15F; g.translate(半径,半径);
的System.out.println第(i +:+((1 - 比例/半径)* 2));
对于(INT J = 0; J<姓名[0]。长度(); J ++){ 焦炭CH =名称[0] .charAt(J);
弧度=((瓦尔[Ⅰ] - (名称[0]。长度() - J)* 2)*(1 +(1 - 比例/半径)* 2))* HPI;
g.rotate(弧度);
g.drawString(CH +,0,-scale);
g.rotate(-radians);
}
g.translate(-radius,-radius); / *浮动X =(浮点)Math.cos(弧度)*规模;
浮Y =(浮点)Math.sin(弧度)*(vars.length - I)/ vars.length *半径/ 2 * 1.7f;
g.drawRect((INT)X +尺寸/ 2,(INT)Y +尺寸/ 2,10,10); * / }
规模= vars.length /(浮点)vars.length *半径* 1.7f;
g.setColor(颜色[0]);
g.fillOval((int)的(比例/ 2),(INT)(比例/ 2),(INT)(大小 - 规模),(INT)(大小 - 尺度)); g.setColor(Color.WHITE);
g.drawString(FPS+将String.valueOf(fps)的,20,30); //绘制画面上的全部结果。
appletGraphics.drawImage(屏幕,0,0,NULL); 做{
Thread.yield();
}而(System.nanoTime() - lastTime℃下);
如果(!isActive()){
返回;
}
}
}公共无效initColors(){
颜色=新的色彩[colorsInt.length]
的for(int i = 0; I< colors.length;我++){
颜色由[i] =新的色彩(colorsInt [I] [0],colorsInt [I] [1],colorsInt [I] [2]);
}
}}
下面是旋转文本的一个简单的例子。
附录:你想通过调整 stringWidth的文本的径向起点(名称[N])
。程序出现在努力跟随弧被旋转单个字符,而实施例看来是绘制在一条直线相切的弧的文本。后一种方法可能证明简单。例如,这种变化在整个中心的标签弧的 getStartPoint()
:
的for(int i = 0; I< vars.length;我++){
...
字符串s =名称[0];
INT W = fm.stringWidth(S);
INT H = fm.getHeight()+ fm.getMaxDescent();
的Point2D p值= arch.getStartPoint();
INT X =(int)的p.getX();
INT Y =(int)的p.getY();
弧度=(瓦尔[I])* HPI;
g.rotate(弧度,X,Y);
g.drawString(S,X - 瓦特/ 2,Y + H);
g.rotate(-radians,X,Y);
}
为方便起见,code以上确实旋转()
来来回回;为了便于比较,这里的展示的重复串联旋转()
最初的例子:
进口java.awt中的*。
进口java.awt.geom.AffineTransform中;
进口的javax.swing *。/ ** @see http://stackoverflow.com/questions/6238037 * /
公共类RotateText继承JPanel { 私有静态最后的字体F =新的字体(衬线,Font.BOLD,32);
私有静态最后一个String =的Hello World!;
私有静态最后的颜色[] =颜色{
Color.red,Color.green,Color.blue,Color.cyan
};
私人的Graphics2D G2D;
在私人的AffineTransform; 公共RotateText(){
集preferredSize(新尺寸(400,400));
} @覆盖
公共无效的paintComponent(图形G){
G2D =(Graphics2D的)克;
g2d.setFont(F);
g2d.setColor(Color.black);
g2d.fillRect(0,0,的getWidth(),的getHeight());
在= g2d.getTransform();
INT W = this.getWidth();
INT H = this.getHeight();
INT W2 = g2d.getFontMetrics()stringWidth(S)/ 2。
INT H2 = 2 * g2d.getFontMetrics()的getHeight()/ 3。
渲染(0,W / 2 - W2,H - H2);
渲染(1,H 2,H / 2 - W2);
渲染(2,W / 2 + W2,H2);
渲染(3,W - H2,H / 2 + W2);
g2d.setTransform(AT);
g2d.setColor(Color.yellow);
g2d.fillRect(W / 3,H / 3,W / 3,H / 3);
} 私人无效渲染(INT N,INT的x,int y)对{
g2d.setColor(颜色[N]);
g2d.setTransform(AT);
g2d.rotate(N * Math.PI / 2,X,Y);
g2d.drawString(S,X,Y);
} 公共静态无效的主要(字串[] args){
EventQueue.invokeLater(新的Runnable(){
// @覆盖
公共无效的run(){
JFrame的F =新的JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(新RotateText(),BorderLayout.CENTER);
f.pack();
f.setVisible(真);
}
});
}
}
I wrote this polar clock today and i am almost finished exept i want to align my text inside the line similar to this. Does anyone know how to do this? Ive tried to use FontRenderContext and font metrics but i cant seem to get it to work. Here is the whole source code so you can compile it and see for yourselves.
import java.applet.Applet;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.util.Calendar;
import java.util.TimeZone;
public class Clock extends Applet implements Runnable {
int[][] colorsInt = {{20,20,20},{100,100,50},{50,100,100},{10,170,50},{79,29,245},{24,69,234},{253,24,103}};
Color[] colors;
int size;
int radius;
boolean anitalias = false;
static final float HPI = (float)(Math.PI / 180f);
public void start() {
enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
new Thread(this).start();
}
public void run() {
setSize(500, 500); // For AppletViewer, remove later.
// Set up the graphics stuff, double-buffering.
BufferedImage screen = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D)screen.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
WritableRaster wr = screen.getRaster();
Graphics appletGraphics = getGraphics();
// Some variables to use for the fps.
long fpstn = 1000000000 / 600;
int tick = 0, fps = 0, acc = 0;
long lastTime = System.nanoTime();
// Vars
Calendar c;
size = 500;
radius = size / 2;
Arc2D.Float arch;
float scale, radians;
long miliSecond;
int second, minute, hour, month, year, dayOfWeek, dayOfMonth, dayOfYear, daysInMonth, daysInYear;
float[] tvars = new float[6];
float[] vars = new float[6];
String[] names = new String[6];
FontMetrics fm = g.getFontMetrics();
Font font = g.getFont();
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, "Hello world");
int length = gv.getNumGlyphs();
// Init
initColors();
for (int i = 0; i < vars.length; i++)
vars[i] = 0;
// Game loop.
while (true) {
long now = System.nanoTime();
acc += now - lastTime;
tick++;
if (acc >= 1000000000L) {
acc -= 1000000000L;
fps = tick;
tick = 0;
}
// Update
c = Calendar.getInstance();
miliSecond = c.get(Calendar.MILLISECOND);
second = c.get(Calendar.SECOND);
minute = c.get(Calendar.MINUTE);
hour = c.get(Calendar.HOUR_OF_DAY);
dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
dayOfYear = c.get(Calendar.DAY_OF_YEAR);
dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
month = c.get(Calendar.MONTH);
daysInMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
daysInYear = c.getActualMaximum(Calendar.DAY_OF_YEAR);
tvars[0] = (second * 1000 + miliSecond) / 60000f * 360f;
tvars[1] = (minute * 60f + second) / 3600f * 360f;
tvars[2] = (hour * 60f + minute) / 1440f * 360f;
tvars[3] = ((dayOfWeek - 2) * 24f + hour) / 168f * 360f;
tvars[4] = ((dayOfMonth - 1) * 24f + hour) / (daysInMonth * 24f) * 360f;
tvars[5] = dayOfYear / (float)daysInYear * 360f;
for (int i = 0; i < vars.length; i++) {
if (tvars[i] - vars[i] > 1) {
vars[i] += (tvars[i] - vars[i]) / 15;
} else if(tvars[i] - vars[i] < -1) {
vars[i] -= (vars[i] - tvars[i]) / 15;
} else {
vars[i] = tvars[i];
}
}
names[0] = second + " Second" + (second > 1 ? "s" : "");
lastTime = now;
// Render
g.setColor(colors[0]);
g.fillRect(0, 0, size, size);
for (int i = 0; i < vars.length; i++) {
scale = i / (float)vars.length * radius * 1.7f;
g.setColor(colors[0]);
g.fillOval((int)(scale / 2), (int)(scale / 2), (int)(size - scale), (int)(size - scale));
g.setColor(colors[i + 1]);
scale += 15;
arch = new Arc2D.Float(scale / 2, scale / 2, size - scale, size - scale, 450 - vars[i], vars[i], Arc2D.PIE);
g.fill(arch);
g.setColor(Color.WHITE);
radians = (vars[i]) * HPI;// vars[i] - 90
scale = ((float)(vars.length - i) / (float)vars.length * (float)radius / 2f * 1.7f) + 15f;
g.translate(radius, radius);
System.out.println(i + ": " + ((1 - scale / radius) * 2));
for (int j = 0; j < names[0].length(); j++) {
char ch = names[0].charAt(j);
radians = ((vars[i] - (names[0].length() - j) * 2) * (1 + (1 - scale / radius) * 2)) * HPI;
g.rotate(radians);
g.drawString(ch + "", 0, -scale);
g.rotate(-radians);
}
g.translate(-radius, -radius);
/*float x = (float)Math.cos(radians) * scale;
float y = (float)Math.sin(radians) * (vars.length - i) / vars.length * radius / 2 * 1.7f;
g.drawRect((int)x + size / 2, (int)y + size / 2, 10, 10);*/
}
scale = vars.length / (float)vars.length * radius * 1.7f;
g.setColor(colors[0]);
g.fillOval((int)(scale / 2), (int)(scale / 2), (int)(size - scale), (int)(size - scale));
g.setColor(Color.WHITE);
g.drawString("FPS " + String.valueOf(fps), 20, 30);
// Draw the entire results on the screen.
appletGraphics.drawImage(screen, 0, 0, null);
do {
Thread.yield();
} while (System.nanoTime() - lastTime < 0);
if (!isActive()) {
return;
}
}
}
public void initColors() {
colors = new Color[colorsInt.length];
for (int i = 0; i < colors.length; i++) {
colors[i] = new Color(colorsInt[i][0], colorsInt[i][1], colorsInt[i][2]);
}
}
}
Here's a simple example of rotating text.
Addendum: You'll want to adjust the the text's radial starting point by stringWidth(name[n])
. Your program appears to be rotating individual characters in a effort to follow the arc, while the example appears to be drawing the text in a straight line tangent to the arc. The latter approach may prove simpler. For example, this variation centers the labels across the arc's getStartPoint()
:
for (int i = 0; i < vars.length; i++) {
...
String s = names[0];
int w = fm.stringWidth(s);
int h = fm.getHeight() + fm.getMaxDescent();
Point2D p = arch.getStartPoint();
int x = (int) p.getX();
int y = (int) p.getY();
radians = (vars[i]) * HPI;
g.rotate(radians, x, y);
g.drawString(s, x - w / 2, y + h);
g.rotate(-radians, x, y);
}
For convenience the code above does rotate()
to and fro; for comparison, here's the original example showing repeated concatenations of rotate()
:
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
/** @see http://stackoverflow.com/questions/6238037 */
public class RotateText extends JPanel {
private static final Font f = new Font("Serif", Font.BOLD, 32);
private static final String s = "Hello World!";
private static final Color[] colors = {
Color.red, Color.green, Color.blue, Color.cyan
};
private Graphics2D g2d;
private AffineTransform at;
public RotateText() {
setPreferredSize(new Dimension(400, 400));
}
@Override
public void paintComponent(Graphics g) {
g2d = (Graphics2D) g;
g2d.setFont(f);
g2d.setColor(Color.black);
g2d.fillRect(0, 0, getWidth(), getHeight());
at = g2d.getTransform();
int w = this.getWidth();
int h = this.getHeight();
int w2 = g2d.getFontMetrics().stringWidth(s) / 2;
int h2 = 2 * g2d.getFontMetrics().getHeight() / 3;
render(0, w / 2 - w2, h - h2);
render(1, h2, h / 2 - w2);
render(2, w / 2 + w2, h2);
render(3, w - h2, h / 2 + w2);
g2d.setTransform(at);
g2d.setColor(Color.yellow);
g2d.fillRect(w / 3, h / 3, w / 3, h / 3);
}
private void render(int n, int x, int y) {
g2d.setColor(colors[n]);
g2d.setTransform(at);
g2d.rotate(n * Math.PI / 2, x, y);
g2d.drawString(s, x, y);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
//@Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new RotateText(), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}
}
这篇关于我如何正确对齐这段文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!