繁体   English   中英

我无法在 java swing 中居中文本

[英]I can't center text in java swing

我正在为我的游戏制作自定义组件,我尝试了在 Stack Overflow 中找到的所有内容,但无论如何我仍然无法将文本放置在矩形的中心。 我什至阅读了使用 java text API 的所有文档。

任何人都可以向我解释如何一劳永逸地将文本与java swing中的中心(矩形或框架的中心或任何东西)对齐? 这不是一个重复的问题,因为在 Stack Overflow 上的所有其他问题中,我都没有找到有效的解决方案。

到目前为止,我已经使用了 FontMetrics,我使用 stringWidth() 方法测量了宽度,使用 ascent 测量了高度(它们都不准确)。

package com.isi.uicomponents;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;

import com.isi.core.Game;
import com.isi.states.GameState;

public class Button extends UIComponent {

    private Font font;
    private String text;
    
    public Button(Game game, GameState state, int x, int y, int width, int height, String text) {
        super(game, state, x, y, width, height);
            
        font = new Font("Arial", Font.BOLD, 20);
        this.text = text;
    }

    public Button(Game game, GameState state, int x, int y, int width, int height) {
        super(game, state, x, y, width, height);
    
        text = null;
    }
    
    public String getText() {
        return text;
    }
    
    @Override
    public void tick() {
        
    }

    @Override
    public void draw(Graphics2D g) {        
        g.setColor(fillColor);
        g.fillRect(x, y, width, height);
        
        g.setColor(boundsColor);
        g.draw(bounds);
        
        if (text != null) {
            FontMetrics fm = g.getFontMetrics();
            
            int textX = x + (width / 2) - (fm.stringWidth(text) / 2);
            int textY = y + ((height - fm.getHeight()) / 2) + fm.getAscent();
            
            g.setFont(font);
            g.setColor(Color.white);
            g.drawString(text, textX, textY);
        }
    }
}

// =============================================

package com.isi.uicomponents;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import com.isi.core.Game;
import com.isi.states.GameState;

public abstract class UIComponent {

    public final static Color DEFAULT_BOUNDS_COLOR = Color.white;
    public final static Color DEFAULT_FILL_COLOR = Color.gray;
    
    protected Game game;
    protected GameState state;
    
    protected int x;
    protected int y;
    
    protected int width;
    protected int height;
    
    protected Rectangle bounds;
    
    protected Color boundsColor;
    protected Color fillColor;

    public UIComponent(Game game, GameState state, int x, int y, int width, int height) {
        this.game = game;
        this.state = state;
        
        this.x = x;
        this.y = y;
        
        this.width = width;
        this.height = height;
        
        bounds = new Rectangle(x, y, width, height);
        
        boundsColor = DEFAULT_BOUNDS_COLOR;
        fillColor = DEFAULT_FILL_COLOR;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    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 Rectangle getBounds() {
        return bounds;
    }

    public void setBounds(Rectangle bounds) {
        this.bounds = bounds;
    }
    
    public Color getBoundsColor() {
        return boundsColor;
    }

    public void setBoundsColor(Color boundsColor) {
        this.boundsColor = boundsColor;
    }

    public Color getFillColor() {
        return fillColor;
    }

    public void setFillColor(Color fillColor) {
        this.fillColor = fillColor;
    }

    public abstract void tick();

    public abstract void draw(Graphics2D g);    
}

// =============================================

package com.isi.states;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import com.isi.core.Game;
import com.isi.tools.ImageLoader;
import com.isi.uicomponents.Button;
import com.isi.uicomponents.UIComponent;

public class MainMenuState extends GameState {
    
    private static BufferedImage bg = ImageLoader.load("Main Menu Background.jpg");
    
    // Background coordinates for animation
    private int x;
    private int y;
    
    // MainMenu components array
    private ArrayList<UIComponent> components;
    
    public MainMenuState(Game game) {
        super(game);
    
        x = 0;
        y = 0;
        
        components = new ArrayList<UIComponent>();      
        components.add(new Button(game, this, game.getWidth() / 2 - 80 / 2, game.getHeight() / 2 - 50 / 2, 80, 50, "Play"));    
    }

    public ArrayList<UIComponent> getComponents() {
        return components;
    }

    public void tick() {        
        y = y >= game.getHeight() ? 0 : y + 2;
    }

    public void draw(Graphics2D g) {
        g.drawImage(bg, 0, -game.getHeight() + y, game.getWidth(), game.getHeight(), null);
        g.drawImage(bg, x, y, game.getWidth(), game.getHeight(), null);
    
        for (int i = 0; i < components.size(); i++) {
            components.get(i).draw(g);
        }
    }   
}

在此处输入图片说明

这很接近,您需要将 x 增加一半的宽度,然后减少一半的字符串宽度。 您还需要在获得字体规格之前设置字体,否则您将获得现有图形字体的规格。

g.setFont(font);

FontMetrics fm = g.getFontMetrics();
        
int textX = x + (width / 2) - (fm.stringWidth(text) / 2);

int textY = y + ((height - fm.getHeight()) / 2) + fm.getAscent();
        
g.setColor(Color.white);

g.drawString(text, textX, textY);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM