【问题标题】:How to add a newline to JLabel without using HTML如何在不使用 HTML 的情况下向 JLabel 添加换行符
【发布时间】:2011-11-12 00:27:03
【问题描述】:

如何在JLabel 中添加新行?我知道如果我使用简单的 HTML,它会起作用。但如果我使用 HTML,JLabel 不会显示嵌入应用程序的字体。我正在使用方法嵌入字体 - createFont() 并使用 JLabel.setFont() 来应用字体。

【问题讨论】:

    标签: java swing jlabel multiline


    【解决方案1】:

    SwingX 支持多行标签:

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

    【讨论】:

    • 在使用多行文本时,JXLabel 是否有“正确的”基线?请注意,“正确”对不同的人可能意味着不同的东西;-)
    • @jfpoilpret - 不知道。什么是正确的基线?
    • 对我来说,正确的基线是标签第一行第一个字符的基线。但是我敢肯定,您会发现其他人更喜欢以标签的整个高度为中心的基线。其他人可能还希望基线是标签中最后一行的第一个字符的基线。这实际上取决于人们希望标签在他们的布局中如何对齐。我认为我的第一个建议最有意义。
    【解决方案2】:


    我认为没有直接(和简单)的方式来使用多行执行 JLabel 而不会重复到 HTML。您可以改用 JTextArea。

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

    它应该看起来几乎一样。如果不同的组件有不同的字体,可以添加下面一行,保证JTextArea的字体和JLabel一致

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

    希望这会有所帮助。

    【讨论】:

    【解决方案3】:

    我正在使用方法嵌入字体 - createFont()) 并使用 JLabel.setFont() 来应用字体。

    尝试在 HTML 中设置它,如 here 所示。

    【讨论】:

    • 从我的观点来看,使用 HTML 的主要问题是基线的丢失,现在大多数 LayoutManagers 都在使用它(恕我直言,这是一个很好的观点)
    【解决方案4】:

    据我回忆,JLabel 最初并非用于多行文本。您需要覆盖各种渲染方法才能手动进行文本行拆分。

    如果您想要多行标签,也许您应该使用不可编辑的 JTextArea。

    【讨论】:

      【解决方案5】:

      1) 如果你想在不使用 JLabel 的情况下多行 JComponents,那么你必须像 JTextArea、JTextPane、JEditorPane 一样寻找 TextComponent,如果不应该是可编辑的,那么 myTextComponent#setEditable(false);

      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);
                  }
              });
          }
      }
      

      【讨论】:

        【解决方案6】:

        以下大部分代码取自 BasicLabelUI 和/或 WindowsLabelUI,但我添加了代码以使其适用于多行。这是我可以开始工作的最少复制代码量。您可以使用 setSeparator 或通过更改 LinesAndIndex 实例化的默认值来设置行之间的分隔符。我没有对此进行广泛的测试,但到目前为止它对我有用。使用 HTML 时,助记符不起作用,所以我创建了这个。如果您有更好的方法来完成此操作,请更正代码。

            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;
                    }
                }
        
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-25
          • 1970-01-01
          • 2013-07-12
          • 2011-11-26
          • 2010-10-12
          • 2015-10-11
          • 1970-01-01
          相关资源
          最近更新 更多