【问题标题】:Display text in Swing without JLabel [closed]在没有 JLabel 的 Swing 中显示文本[关闭]
【发布时间】:2012-10-23 17:31:59
【问题描述】:

我必须使用 Swing 制作一个 Java 程序,我想显示一些文本,但不使用 JLabel(包括文本组件)!我必须扩展JFrame。我还有什么其他选择?

【问题讨论】:

  • 这是一个相当奇怪的限制。在提出答案之前,您还有其他我们应该了解的限制吗?为什么不能使用 JLabel?
  • 我不认为这个问题过于本地化 - 可能有理由直接呈现文本 - 但更多上下文会有所帮助。
  • 其他限制可能是文本必须在显示之前换行。
  • 不要用废话重写/删除问题文本,要么删除它,暂时保留它,等你知道后再回来,或者标记为已解决。但是现在编辑一个问题说:我必须考虑更多......不是好主意,它将被删除。

标签: java swing jframe


【解决方案1】:

你不应该:

  • 不必要地扩展JFrame
  • 通过paint(..)直接绘制到JFrame

你应该:

  • 覆盖JComponents paintComponent(...)
  • paintComponent(...)做自定义绘画,
  • JComponent 实例添加到JFrame

这里有一个例子:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DrawSimpleText {

    public DrawSimpleText() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DrawSimpleText();
            }
        });
    }

    private void initComponents() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JPanel(true) {
            Font font = new Font("Serif", Font.PLAIN, 20);
            String s = "Java Source and Support";

            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;

                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setFont(font);

                FontMetrics fm = g.getFontMetrics(font);

                int width = fm.stringWidth(s);

                Dimension d = getSize();

                //center String/text
                int cx = (d.width - width) / 2;
                int cy = (d.height - fm.getHeight()) / 2 + fm.getAscent();

                g2.drawString(s, cx, cy);
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 100);
            }
        });
        f.pack();
        f.setVisible(true);
    }
}

更新:

根据您的评论 尽管它违反了所有 Swing 规则和我自己的道德

但是,如果您仍然需要这样做(我无法理解为什么这是不好的做法),方法如下:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class DrawSimpleText extends JFrame {

    public DrawSimpleText() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DrawSimpleText();
            }
        });
    }

    private void initComponents() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }
    Font font = new Font("Serif", Font.PLAIN, 20);
    String s = "Java Source and Support";

    @Override
    public void paint(Graphics g) {

        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setFont(font);

        FontMetrics fm = g.getFontMetrics(font);

        int width = fm.stringWidth(s);

        Dimension d = getSize();

        //center String/text
        int cx = (d.width - width) / 2;
        int cy = (d.height - fm.getHeight()) / 2 + fm.getAscent();

        g2.drawString(s, cx, cy);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 100);
    }
}

【讨论】:

  • 还可以考虑TextLayout 以获得更好的指标,如here 所示。
  • 为什么这些值是硬编码的?还有双缓冲呢?
  • @RomanC 虽然我完全支持灵活的 API,但这只是一个示例并演示了 OP 的基本要求。 +1
  • @trashgod 添加了 FontMetrics :)
  • @romanc 我不认为这是一个坏例子。 OP 对布局没有要求,他们想绘制文本。如果我们开始第二次猜测需求,我们不仅会浪费时间,还会在答案中引入不相关性。我同意,当我们看到不好的做法时,我们应该纠正它并鼓励好的做法,但我们只能猜测这么多。在这种情况下,我认为不需要全力以赴地提供属性来设置文本位置来回答 OPs 问题......恕我直言
猜你喜欢
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
相关资源
最近更新 更多