动态多行工具提示

问题描述 投票:0回答:1

想象一个组件有一个动态工具提示。

可能会很长。在这种情况下,用户希望将其分成多行。最终目标是永远不要用屏幕边缘剪切工具提示。例如,在低分辨率的屏幕上,长工具提示可能会超过屏幕总宽度。

tooltip's too long for screen resolution, hence cut

我怎样才能实现它?

请记住,文本是动态的,我无法将其包裹在

<html></html>
中并散布
<br>
标签。

package demos.text.field;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import java.awt.Container;

public class TextFieldDemo {
    public static void main(String[] args) {
        Container mainPanel = createMainPanel();
        JFrame frame = new JFrame("Text field demo");
        frame.setContentPane(mainPanel);
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static JPanel createMainPanel() {
        JPanel panel = new JPanel();
        panel.add(createTextField());
        return panel;
    }

    private static JTextField createTextField() {
        JTextField textField = new JTextField("Text field with a tooltip");
        textField.setToolTipText("A " + "very ".repeat(10) + "long tooltip that must be split");
        return textField;
    }
}

Java 8。

java swing
1个回答
0
投票

String
分成更小的部分并不是一件容易的事。 这是一种方法。

  • 获取线段
  • 找到最后一个空格
  • 在线段后添加断点

splitText
方法有两个参数,
String
和线段的宽度。 宽度必须是合理的数字,以便段在段末尾附近有一个空间。

这是完整的可运行代码。

import java.awt.BorderLayout;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TextFieldDemo implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TextFieldDemo());
    }
    
    private String toolTipString;
    
    public TextFieldDemo() {
        String text = "A " + "very ".repeat(10) + "long tooltip that must be split.";
        this.toolTipString = splitText(text, 30);
    }
    
    private String splitText(String text, int width) {
        if (text.length() <= width) {
            return "<html>" + text + "</html>"; 
        }
        
        StringBuilder builder = new StringBuilder();
        int startIndex = 0;
        int endIndex = width;
        int finalIndex = text.length();

        do {
            String s = text.substring(startIndex, endIndex);
            int tempIndex = s.length() - 1;

            // Find last space
            if (tempIndex >= (width - 1)) {
                tempIndex = s.lastIndexOf(' ');
                tempIndex += startIndex;
            } else {
                tempIndex = finalIndex;
            }
            
            // Append break
            builder.append(text.substring(startIndex, tempIndex));
            if (tempIndex < finalIndex) {
                builder.append("<br>");
            }
            
            // Set next text segment
            startIndex = tempIndex + 1;
            endIndex = Math.min(startIndex + width, finalIndex);
            
        } while (startIndex < finalIndex);
        
        return "<html>" + builder.toString() + "</html>"; 
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Text field demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JPanel createMainPanel() {
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
        panel.add(createTextField());
        return panel;
    }

    private JTextField createTextField() {
        JTextField textField = new JTextField(30);
        textField.setText("Text field with a tooltip");
        textField.setToolTipText(toolTipString);
        return textField;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.