You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JFrame图形绘制、组件边框添加及精确定位技术求助

类似Wordle的解单词游戏开发问题解决方案

问题描述

我正在开发一款类似Wordle的解单词游戏,布局为上方显示5个打乱字母的JLabel(lb1-lb5),下方对应5个JTextField(tf1-tf5)供用户输入字母正确顺序。目前遇到以下问题:

  1. 无法在现有JPanel之上为这些JLabel和JTextField绘制矩形边框;
  2. 不清楚如何正确显示自定义图形;
  3. 希望能精确定位这些标签与文本框,实现每个标签对应在文本框正上方。

解决方案

1. 为组件添加边框

无需手动绘制边框,直接使用Swing内置的BorderFactory给组件或面板设置边框即可:

  • 给单个JLabel/JTextField加边框:
// 给标签加黑色实线边框
lb1.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
// 给文本框加黑色实线边框
tf1.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
  • 给整组输入组件加外框(给inputs面板设置):
inputs.setBorder(BorderFactory.createCompoundBorder(
    BorderFactory.createLineBorder(Color.DARK_GRAY, 3),
    BorderFactory.createEmptyBorder(10,10,10,10)
));

2. 正确显示自定义图形

你的自定义图形面板未被实例化添加到界面,且Swing组件推荐重写paintComponent而非paint,修改如下:

  • 重写paintComponent方法并调用父类方法:
public class GraphicsPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // 必须调用,避免界面渲染异常
        Graphics2D g2d = (Graphics2D) g;
        // 相对面板坐标绘制,适配窗口大小
        g2d.setColor(Color.RED);
        g2d.drawRect(10, 10, getWidth()-20, getHeight()-20);
    }
}
  • 在构造方法中实例化并添加到界面(设置透明以不遮挡下层组件):
GraphicsPanel gp = new GraphicsPanel();
gp.setOpaque(false); // 透明,允许下层组件显示
gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.BOTH;
mainPanel.add(gp, gbc, 0); // 0表示添加到最上层

3. 精确定位标签与文本框对齐

通过调整GridBagConstraints参数,保证每列宽度一致,组件对齐:

  • 在添加标签和文本框前,统一设置约束:
gbc.weightx = 1.0; // 每列权重相同,平分可用宽度
gbc.fill = GridBagConstraints.HORIZONTAL; // 组件水平填充列宽
gbc.insets = new Insets(5, 5, 5, 5); // 组件间间距
  • 给JTextField设置固定列数,保证大小统一:
tf1 = new JTextField(1); // 限制输入1个字符,大小一致

修改后的完整代码

import java.awt.*;
import javax.swing.*;

public class Scramble extends JFrame {

    Font mainFont = new Font("Impact", Font.BOLD, 60);
    Font smallFont = new Font("Impact", Font.BOLD, 30);

    JLabel lbWelcome;
    JLabel lb1, lb2, lb3, lb4, lb5;
    JTextField tf1, tf2, tf3, tf4, tf5;
    GridBagConstraints gbc = new GridBagConstraints();

    Scramble() {
        // 初始化全局GridBag约束
        gbc.anchor = GridBagConstraints.PAGE_START;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;

        // 主面板
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());
        mainPanel.setBackground(new Color(12, 177, 237));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 40, 30, 40));

        // 标题
        lbWelcome = new JLabel("Scramble", SwingConstants.CENTER);
        lbWelcome.setFont(mainFont);
        lbWelcome.setToolTipText("Scramble is a game created by Glen Filson");
        gbc.gridx = 0;
        gbc.gridy = 0;
        mainPanel.add(lbWelcome, gbc);

        // 输入面板
        JPanel inputs = new JPanel();
        inputs.setBackground(new Color(12, 177, 200));
        inputs.setLayout(new GridBagLayout());
        // 给输入面板加外框
        inputs.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(Color.DARK_GRAY, 3),
            BorderFactory.createEmptyBorder(10,10,10,10)
        ));
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.NONE;
        mainPanel.add(inputs, gbc);

        // 输入组件的约束设置
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);

        // 打乱字母标签
        lb1 = new JLabel("F", SwingConstants.CENTER);
        lb1.setFont(smallFont);
        lb1.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 0;
        gbc.gridy = 0;
        inputs.add(lb1, gbc);

        lb2 = new JLabel("I", SwingConstants.CENTER);
        lb2.setFont(smallFont);
        lb2.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 1;
        gbc.gridy = 0;
        inputs.add(lb2, gbc);

        lb3 = new JLabel("G", SwingConstants.CENTER);
        lb3.setFont(smallFont);
        lb3.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 2;
        gbc.gridy = 0;
        inputs.add(lb3, gbc);

        lb4 = new JLabel("H", SwingConstants.CENTER);
        lb4.setFont(smallFont);
        lb4.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 3;
        gbc.gridy = 0;
        inputs.add(lb4, gbc);

        lb5 = new JLabel("T", SwingConstants.CENTER);
        lb5.setFont(smallFont);
        lb5.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 4;
        gbc.gridy = 0;
        inputs.add(lb5, gbc);

        // 输入文本框
        tf1 = new JTextField(1);
        tf1.setFont(smallFont);
        tf1.setHorizontalAlignment(JTextField.CENTER);
        tf1.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 0;
        gbc.gridy = 1;
        inputs.add(tf1, gbc);

        tf2 = new JTextField(1);
        tf2.setFont(smallFont);
        tf2.setHorizontalAlignment(JTextField.CENTER);
        tf2.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 1;
        gbc.gridy = 1;
        inputs.add(tf2, gbc);

        tf3 = new JTextField(1);
        tf3.setFont(smallFont);
        tf3.setHorizontalAlignment(JTextField.CENTER);
        tf3.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 2;
        gbc.gridy = 1;
        inputs.add(tf3, gbc);

        tf4 = new JTextField(1);
        tf4.setFont(smallFont);
        tf4.setHorizontalAlignment(JTextField.CENTER);
        tf4.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 3;
        gbc.gridy = 1;
        inputs.add(tf4, gbc);

        tf5 = new JTextField(1);
        tf5.setFont(smallFont);
        tf5.setHorizontalAlignment(JTextField.CENTER);
        tf5.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        gbc.gridx = 4;
        gbc.gridy = 1;
        inputs.add(tf5, gbc);

        // 添加自定义图形面板
        GraphicsPanel gp = new GraphicsPanel();
        gp.setOpaque(false);
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.BOTH;
        mainPanel.add(gp, gbc, 0);

        // 窗口设置
        setTitle("Scramble");
        setSize(500, 650);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setBackground(new Color(100, 60, 100));
        add(mainPanel);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Scramble();
    }

    public class GraphicsPanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.RED);
            g2d.drawRect(10, 10, getWidth()-20, getHeight()-20);
        }
    }
}

内容的提问来源于stack exchange,提问作者Glen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:06:28