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

Codename One:自定义SpanToggleCheckBox无文本显示及多行切换按钮实现

Hey there! Let's figure out why your SpanToggleCheckBox isn't showing any text and fix it with practical solutions.

What's Wrong with Your Current Code?

Looking at your snippet, there are a few key issues causing the missing text:

  • You didn't add the TextArea to the component tree: You created a textArea instance, but never added it to the SpanToggleCheckBox itself with add(textArea). Without this, the TextArea doesn't get rendered at all.
  • CheckBox's default layout doesn't support extra components: CheckBox uses a built-in layout designed for an icon + single-line text label. Shoving a TextArea into it without adjusting the layout will either break the layout or make the TextArea invisible.
  • You bypassed CheckBox's native text handling: CheckBox has its own setText() and text rendering logic, but you ignored that entirely. Your code doesn't sync the TextArea with the CheckBox's state or disable the default text drawing.

If you just need to display multi-line text (not edit it), the simplest approach is to override the CheckBox's painting logic to draw multiple lines. This keeps all native CheckBox behavior intact while fixing the text display.

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

public class MultiLineToggleCheckBox extends JCheckBox {
    private String multiLineText;

    public MultiLineToggleCheckBox(String text) {
        super();
        this.multiLineText = text;
        setPreferredSize(calculatePreferredSize());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // Calculate starting position for text (account for icon and insets)
        Icon icon = getIcon();
        int iconOffset = icon != null ? icon.getIconWidth() + getIconTextGap() : 0;
        int x = getInsets().left + iconOffset;
        int y = getInsets().top + g.getFontMetrics().getAscent();

        // Draw each line of text
        Graphics2D g2d = (Graphics2D) g.create();
        for (String line : multiLineText.split("\n")) {
            g2d.drawString(line, x, y);
            y += g2d.getFontMetrics().getHeight();
        }
        g2d.dispose();
    }

    // Calculate the right size to fit all text lines
    private Dimension calculatePreferredSize() {
        FontMetrics fm = getFontMetrics(getFont());
        String[] lines = multiLineText.split("\n");
        int maxLineWidth = lines.stream().mapToInt(fm::stringWidth).max().orElse(0);
        Icon icon = getIcon();
        int totalWidth = maxLineWidth + (icon != null ? icon.getIconWidth() + getIconTextGap() : 0) + getInsets().left + getInsets().right;
        int totalHeight = lines.length * fm.getHeight() + getInsets().top + getInsets().bottom;
        return new Dimension(totalWidth, totalHeight);
    }

    // Helper methods to update text
    public void setMultiLineText(String text) {
        this.multiLineText = text;
        setPreferredSize(calculatePreferredSize());
        repaint();
    }

    public String getMultiLineText() {
        return multiLineText;
    }
}

Solution 2: Replace CheckBox's Label with a TextArea (Supports Editing)

If you need the text to be editable or want more control over text formatting, replace the CheckBox's default label with a JTextArea (or JTextPane for rich text). This requires adjusting the layout to fit the TextArea properly.

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

public class SpanToggleCheckBox extends JCheckBox {
    private JTextArea textArea;

    public SpanToggleCheckBox(String text) {
        super();
        // Remove the default single-line label
        setText(null);

        // Configure the TextArea
        textArea = new JTextArea(text);
        textArea.setEditable(false); // Set to true if you want editable text
        textArea.setOpaque(false); // Match CheckBox's background
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);

        // Set up a layout to align icon and TextArea
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        Icon icon = getIcon();
        if (icon != null) {
            add(new JLabel(icon));
            add(Box.createHorizontalStrut(getIconTextGap()));
        }
        add(textArea);
        add(Box.createHorizontalGlue()); // Push content to the left

        // Sync selection state with text color (optional)
        addChangeListener(e -> {
            textArea.setForeground(isSelected() ? getSelectedTextColor() : getForeground());
        });
    }

    // Override setText/getText to work with the TextArea
    @Override
    public void setText(String text) {
        textArea.setText(text);
    }

    @Override
    public String getText() {
        return textArea.getText();
    }
}

Which Solution Should You Use?

  • Go with Solution 1 if you just need to display static multi-line text. It's lightweight, maintains all native CheckBox functionality (like keyboard shortcuts, focus states), and is easy to maintain.
  • Choose Solution 2 if you need editable text, rich formatting, or more control over the text component's behavior.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:07:18