简体   繁体   English

如何在不使用 HTML 的情况下向 JLabel 添加换行符

[英]How to add a newline to JLabel without using HTML

How can I add a new line to a JLabel ?如何向JLabel添加新行? I know if I use simple HTML, it will work.我知道如果我使用简单的 HTML,它会起作用。 But if I use HTML, JLabel is not showing the font which embedded with the application.但是如果我使用 HTML, JLabel不会显示嵌入到应用程序中的字体。 I am embedding the font using the method - createFont() and using JLabel.setFont() for applying the font.我使用方法 - createFont()嵌入字体并使用JLabel.setFont()来应用字体。

SwingX supports multiline labels: SwingX支持多行标签:

   JXLabel label = new JXLabel();
   label.setLineWrap(true);


I don't think there is direct(and easy) way of doing JLabel with multiple lines without recurring to HTML.我认为没有直接(且简单)的方法可以在不重复 HTML 的情况下使用多行执行 JLabel。 You can use JTextArea instead.您可以改用 JTextArea。

JTextArea textArea = new JTextArea();
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setOpaque(false);
textArea.setBorder(BorderFactory.createEmptyBorder());
add(textArea, BorderLayout.CENTER);

It should look almost the same.它应该看起来几乎一样。 If you have different fonts for different components, you can add the following line to ensure that the font of JTextArea is the same with JLabel如果不同组件的字体不同,可以添加下面这行,保证JTextArea的字体和JLabel一样

textArea.setFont(UIManager.getFont("Label.font"));

Hope this helps.希望这可以帮助。

I am Embedding the font using the method - createFont() ) and using JLabel.setFont() for applying the font.我正在使用方法 - createFont() ) 嵌入字体并使用JLabel.setFont()来应用字体。

Instead try setting it in the HTML, as shown here .取而代之的尝试,将其设置在HTML如图所示这里

JLabel is not originally intended for multiline text, from what I recall.据我回忆,JLabel 最初并不是用于多行文本。 You would need to override the various rendering methods to do the text line splitting manually.您需要覆盖各种呈现方法以手动进行文本行拆分。

Perhaps you should rather use a non-editable JTextArea if you want multiline labels.如果您想要多行标签,也许您应该使用不可编辑的 JTextArea。

Most of the following code is taken from BasicLabelUI and/or WindowsLabelUI but I added code to make it work with multiple lines.以下大部分代码取自 BasicLabelUI 和/或 WindowsLabelUI,但我添加了代码以使其适用于多行。 This was the minimum amount of copied code I could get to work.这是我可以开始工作的最少复制代码量。 You can set the separator character between the lines with setSeparator or by changing the default on the instantiation of LinesAndIndex.您可以使用 setSeparator 或通过更改 LinesAndIndex 实例化的默认值来设置行之间的分隔符。 I have not done extensive testing on this but it works for me so far.我还没有对此进行广泛的测试,但到目前为止它对我有用。 When using HTML the mnemonic did not work so I created this.使用 HTML 时,助记符不起作用,所以我创建了这个。 If you have a better way to accomplish this please correct the code.如果您有更好的方法来完成此操作,请更正代码。

    import com.sun.java.swing.plaf.windows.WindowsLabelUI;
    import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
    import java.awt.Color;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Insets;
    import java.awt.Rectangle;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.Icon;
    import javax.swing.JComponent;
    import javax.swing.JLabel;
    import javax.swing.UIManager;
    import javax.swing.plaf.LabelUI;
    import javax.swing.plaf.basic.BasicGraphicsUtils;
    import javax.swing.plaf.basic.BasicHTML;
    import javax.swing.text.View;

    public class MultiLineLabelUI extends WindowsLabelUI {
        private static MultiLineLabelUI multiLineLabelUI;
        private LinesAndIndex lai = new LinesAndIndex(',');
        private Rectangle paintIconR = new Rectangle();
        private Rectangle paintTextR = new Rectangle();
        public static LabelUI createUI(JComponent c) {
            if (multiLineLabelUI == null) {
                multiLineLabelUI = new MultiLineLabelUI();
            }
            return multiLineLabelUI;
        }
        private int getBaseline(JComponent c, int y, int ascent, int w, int h) {
            View view = (View) c.getClientProperty(BasicHTML.propertyKey);
            if (view != null) {
                int baseline = BasicHTML.getHTMLBaseline(view, w, h);
                if (baseline < 0) {
                    return baseline;
                }
                return y + baseline;
            }
            return y + ascent;
        }
        public char getSeparator() {
            return lai.getSeparator();
        }
        public void setSeparator(char ch) {
            lai.setSeparator(ch);
        }
        private String layout(JLabel label, FontMetrics fm,
                int width, int height, int lineCnt, int curLine, String text) {
            Insets insets = label.getInsets(null);
            Icon icon = (label.isEnabled()) ? label.getIcon()
                    : label.getDisabledIcon();
            Rectangle paintViewR = new Rectangle();
            paintViewR.width = width - (insets.left + insets.right);
            paintViewR.height = (height - (insets.top + insets.bottom)) / lineCnt;
            paintViewR.x = insets.left;
            paintViewR.y = insets.top + (paintViewR.height * curLine);
            paintIconR.x = 0;
            paintIconR.y = 0;
            paintIconR.width = 0;
            paintIconR.height = 0;
            paintTextR.x = 0;
            paintTextR.y = 0;
            paintTextR.width = 0;
            paintTextR.height = 0;
            return layoutCL(label, fm, text, icon, paintViewR, paintIconR,
                    paintTextR);
        }
        protected void paintEnabledText(JLabel l, Graphics g,
                String s, int textX, int textY, int curLine) {
            int mnemonicIndex = lai.getMnemonicIndex();
            // W2K Feature: Check to see if the Underscore should be rendered.
            if (WindowsLookAndFeel.isMnemonicHidden() == true) {
                mnemonicIndex = -1;
            }
            if (curLine != lai.getMnemonicLineIndex()) {
                mnemonicIndex = -1;
            }

            g.setColor(l.getForeground());
            BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemonicIndex,
                    textX, textY);
        }
        protected void paintDisabledText(JLabel l, Graphics g,
                String s, int textX, int textY, int curLine) {
            int mnemonicIndex = lai.getMnemonicIndex();
            // W2K Feature: Check to see if the Underscore should be rendered.
            if (WindowsLookAndFeel.isMnemonicHidden() == true) {
                mnemonicIndex = -1;
            }
            if (curLine != lai.getMnemonicLineIndex()) {
                mnemonicIndex = -1;
            }
            if (UIManager.getColor("Label.disabledForeground") instanceof Color
                    && UIManager.getColor("Label.disabledShadow") instanceof Color) {
                g.setColor(UIManager.getColor("Label.disabledShadow"));
                BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemonicIndex,
                        textX + 1, textY + 1);
                g.setColor(UIManager.getColor("Label.disabledForeground"));
                BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemonicIndex,
                        textX, textY);
            } else {
                Color background = l.getBackground();
                g.setColor(background.brighter());
                BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemonicIndex,
                        textX + 1, textY + 1);
                g.setColor(background.darker());
                BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemonicIndex,
                        textX, textY);
            }
        }
        @Override
        public void paint(Graphics g, JComponent c) {
            JLabel label = (JLabel) c;
            String text = label.getText();
            Icon icon = (label.isEnabled())
                    ? label.getIcon()
                    : label.getDisabledIcon();

            if ((icon == null) && (text == null)) {
                return;
            }
            char mnemonic = (char) label.getDisplayedMnemonic();
            lai.splitText(text, mnemonic);
            List<String> lines = lai.getLines();

            FontMetrics fm = label.getFontMetrics(g.getFont());
            String[] clippedText = new String[lines.size()];
            for (int i = 0; i < lines.size(); i++) {
                clippedText[i] = layout(label, fm, c.getWidth(), c.getHeight(),
                        lines.size(), i, lines.get(i));

                if (icon != null && i == 0) {
                    icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
                }

                if (text != null) {
                    int textX = paintTextR.x;
                    int textY = paintTextR.y + fm.getAscent();

                    if (label.isEnabled()) {
                        paintEnabledText(label, g, clippedText[i], textX,
                                textY, i);
                    } else {
                        paintDisabledText(label, g, clippedText[i], textX,
                                textY, i);
                    }
                }
            }
        }
        @Override
        public int getBaseline(JComponent c, int width, int height) {
            super.getBaseline(c, width, height);
            JLabel label = (JLabel) c;
            String text = label.getText();
            if (text == null || "".equals(text) || label.getFont() == null) {
                return -1;
            }
            char mnemonic = (char) label.getDisplayedMnemonic();
            lai.splitText(text, mnemonic);
            List<String> lines = lai.getLines();
            FontMetrics fm = label.getFontMetrics(label.getFont());
            String[] clippedText = new String[lines.size()];
            for (int i = 0; i < lines.size(); i++) {
                clippedText[i] = layout(label, fm, width, height, lines.size(), i,
                        lines.get(i));
            }
            return getBaseline(label, paintTextR.y, fm.getAscent(),
                    paintTextR.width, paintTextR.height);
        }

        private static class LinesAndIndex {
            private char sep;
            private List<String> lines;
            private int mnemonicLineIndex;
            private int mnemonicIndex;
            LinesAndIndex(char sep) {
                mnemonicLineIndex = -1;
                mnemonicIndex = -1;
                lines = new ArrayList<String>();
                this.sep = sep;
            }
            public char getSeparator() {
                return sep;
            }
            public void setSeparator(char sep) {
                this.sep = sep;
            }
            public List<String> getLines() {
                return lines;
            }
            public int getMnemonicLineIndex() {
                return mnemonicLineIndex;
            }
            public int getMnemonicIndex() {
                return mnemonicIndex;
            }
            public void splitText(String text, char mnemonic) {
                if (text == null) {
                    return;
                }
                lines.clear();
                mnemonicLineIndex = -1;
                mnemonicIndex = -1;
                char um = Character.toUpperCase(mnemonic);
                char lm = Character.toLowerCase(mnemonic);
                int umi = Integer.MAX_VALUE;
                int lmi = Integer.MAX_VALUE;
                int umli = -1;
                int lmli = -1;
                for (int i = 0, j = 0, k = 0; i < text.length(); i++) {
                    if (text.charAt(i) == sep) {
                        lines.add(text.substring(j, i));
                        j = i + 1;
                        k++;
                    } else if (text.charAt(i) == um) {
                        if (umi == Integer.MAX_VALUE) {
                            umi = i - j;
                            umli = k;
                        }
                    } else if (text.charAt(i) == lm) {
                        if (lmi == Integer.MAX_VALUE) {
                            lmi = i - j;
                            lmli = k;
                        }
                    }
                    if (i == text.length() - 1) {
                        lines.add(text.substring(j, i + 1));
                    }
                }
                mnemonicLineIndex = (lmi < umi) ? lmli : umli;
                mnemonicIndex = (lmi < umi) ? lmi : umi;
            }
        }

    }

1) if you want to Multiline JComponents without using JLabel, then you have to look for TextComponent as are JTextArea, JTextPane, JEditorPane, if should't be editable then myTextComponent#setEditable(false); 1) 如果你想在不使用 JLabel 的情况下多行 JComponents,那么你必须像 JTextArea、JTextPane、JEditorPane 一样寻找TextComponent ,如果不应该是可编辑的,那么myTextComponent#setEditable(false);

2) I never see problem with Html & Font & Color in Swing, for example: 2)我从来没有在 Swing 中看到 Html & Font & Color 的问题,例如:

在此处输入图片说明

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

public class ButtonFg extends JFrame {

    private static final long serialVersionUID = 1L;

    public ButtonFg() {
        JButton button = new JButton("<html> - myText <br>"
                + " - myText <br>"
                + " - myText <br>"
                + " - myText </html>");
        button.setForeground(Color.blue);
        button.setFont(new Font("Serif", Font.BOLD, 28));
        button.setFocusPainted(false);
        add(button);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocation(150, 150);
        pack();
    }

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

            @Override
            public void run() {
                new ButtonFg().setVisible(true);
            }
        });
    }
}

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

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