繁体   English   中英

知道java swing中label的宽度如何得到高度?

[英]How to get the height when knowing the width of the label in java swing?

大家好,我现在正在使用 java swing。 我有一个这样的问题:我有一段很长的文本,并把它放在带有<html>标签的 label 中。

<html> My text </html>

如果文字太长,会按照label的宽度换行。如何计算换行的次数? 或换行后显示文本所需的高度

这是我的代码

public Test() {
        initComponents();
        setPreferredSize(new Dimension(200, 200));
        add(new JLabel("<html> "
                + "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like)."
                + "</html>"));
    }

在此处输入图像描述

如何知道显示文本所需的确切高度?

Oracle 有一个有用的教程,使用 Swing 创建 GUI 跳过学习 Swing 和 NetBeans IDE 部分。

这是我创建的 GUI。 您的代码不可运行。 当我让它可以运行时,你的 HTML 没有指定任何换行符,所以没有任何换行符。

例子

通常,您将JTextArea用于非常长的文本。 您指定所需的行数和列数。 通过调整行和列,您可以间接调整组件的大小。

我将JTextArea放在JScrollPane中,因此组件的大小与文本的长度无关。 我有时会在JScrollPane中使用JTextArea作为我的说明对话框。

这是完整的可运行代码。

import java.awt.BorderLayout;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class LongJLabel implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new LongJLabel());

    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Long JLabel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createMainPanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));

        JTextArea textArea = new JTextArea(10, 40);
        textArea.setEditable(false);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setText("It is a long established fact that a reader will be "
                + "distracted by the readable content of a page when "
                + "looking at its layout. The point of using Lorem "
                + "Ipsum is that it has a more-or-less normal "
                + "distribution of letters, as opposed to using "
                + "'Content here, content here', making it look like "
                + "readable English. Many desktop publishing packages "
                + "and web page editors now use Lorem Ipsum as their "
                + "default model text, and a search for 'lorem ipsum' "
                + "will uncover many web sites still in their infancy. "
                + "Various versions have evolved over the years, "
                + "sometimes by accident, sometimes on purpose "
                + "(injected humour and the like).");
        JScrollPane scrollPane = new JScrollPane(textArea);
        textArea.setCaretPosition(0);
        panel.add(scrollPane);

        return panel;
    }

}

获得所需的确切高度似乎并非易事。 尽管您可以使用“有根据的猜测”方法来计算所需的高度。

String text = "Your text here";
JLabel label = new JLabel("<html> "
    + text
    + "</html>");
//You can get very useful Information via the Font Metrics class
FontMetrics fm = label.getFontMetrics(label.getFont());

//Here you need a reference to your window so you can get the width of it.
//Via the stringWidth function you get the width of the text when written as one line
//Subtracting 40 is to counter the effect, that the text is broken after each line
//The (int) (...) + 1 is just to round up
int lines = (int) (fm.stringWidth(text) / (window.getWidth() - 40f)) + 1;

//last you can set the window height however you like but watch out
//since the window top margin has to be minded
window.setSize(200, lines * fm.getHeight() + 30);

我查看了 class javax.swing.JLabel的代码并进行了一些实验,发现当JLabel的文本以<html>开头时,设置了一个名为html的客户端属性,并且该属性值的类型为javax.swing.text.View

请注意,如果JLabel文本不是<html>开头,则没有html [client] 属性。

View有方法getPreferredSpan ,它返回整个文本的宽度( JLabel的)和单行的高度(取决于调用该方法时使用的参数——见下面的代码)。

假设您希望分配的总宽度是任意的(在您问题的代码中我相信宽度是 200),您可以计算需要多少行。 从那里您可以计算出所需的高度。

我仍然没有发现为什么计算出的行数比要求的行数小2,所以我在计算值上加了2。

另请注意,我设置了JLabel的首选大小,而不是window (即JFrame ),并且还调用了方法pack ,以便window大小适合JLabel首选大小。

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.text.View;

public class Test {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            String text = "<html>It is a long established fact that a reader will be distracted " +
                          "by the readable content of a page when looking at its layout. The " +
                          "point of using Lorem Ipsum is that it has a more-or-less normal " +
                          "distribution of letters, as opposed to using 'Content here, content " +
                          "here', making it look like readable English. Many desktop publishing " +
                          "packages and web page editors now use Lorem Ipsum as their default " +
                          "model text, and a search for 'lorem ipsum' will uncover many web " +
                          "sites still in their infancy. Various versions have evolved over the " +
                          "years, sometimes by accident, sometimes on purpose (injected humour " +
                          "and the like).";
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JLabel label = new JLabel(text);
            View view = (View) label.getClientProperty("html");
            float textWidth = view.getPreferredSpan(View.X_AXIS);
            float charHeight = view.getPreferredSpan(View.Y_AXIS);
            double lines = Math.ceil(textWidth / 200) + 2;
            double height = lines * charHeight;
            label.setPreferredSize(new Dimension(200, (int) Math.ceil(height)));
            frame.add(label);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        });
    }
}

暂无
暂无

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

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