聆听 JTextField 的文本修剪/显示

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

这就是用户想要的:如果文本太长而无法容纳文本字段,请将其设置为工具提示。否则,应该没有工具提示。

问题:Swing 没有告诉我们它是否修剪了字段的文本。没有这样的属性,不会触发任何事件。

为了简单起见,请忘记工具提示。只需让打印消失即可(请参阅 MRE)。基本上,我需要“听”修剪/表演。

这是 MRE。更改窗口的大小以影响字段的宽度。

package demos.text.formattedTextField;

import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.DefaultFormatterFactory;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LayoutManager;
import java.text.ParseException;

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

    private static JPanel createMainPanel() {
        LayoutManager layout = new GridBagLayout();
        JPanel panel = new JPanel(layout);
        panel.add(createFormattedTextField(), constraints());
        return panel;
    }

    private static GridBagConstraints constraints() {
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.weightx = 1;
        constraints.fill = GridBagConstraints.BOTH;
        return constraints;
    }

    private static JFormattedTextField createFormattedTextField() {
        JFormattedTextField textField = new JFormattedTextField();
        DefaultFormatterFactory formatterFactory = new DefaultFormatterFactory();
        formatterFactory.setDisplayFormatter(new DefaultFormatter() {
            @Override
            public String valueToString(Object value) throws ParseException {
                return value instanceof Cat ? ((Cat) value).getName() : super.valueToString(value);
            }
        });
        textField.setFormatterFactory(formatterFactory);
        textField.setValue(createFormattedValue());
        return textField;
    }

    private static Cat createFormattedValue() {
        Cat cat = new Cat("mew".repeat(10));
        return cat;
    }

    private static void onTextTrim() {
        System.out.println("Text has been trimmed...");
    }

    private static void onTextShow() {
        System.out.println("Text is now fully displayed...");
    }

    static class Cat {
        private final String name;

        public Cat(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return super.toString();
        }

        public String getName() {
            return name;
        }
    }
}

enter image description here

enter image description here

这是 GPT 的建议,虽然可行,但在我看来很难看

        textField.addComponentListener(new ComponentAdapter() {
            private boolean isTrimmed = false;

            @Override
            public void componentResized(ComponentEvent e) {
                checkTextTrim(textField);
            }

            @Override
            public void componentShown(ComponentEvent e) {
                checkTextTrim(textField);
            }

            private void checkTextTrim(JFormattedTextField field) {
                FontMetrics metrics = field.getFontMetrics(field.getFont());
                String text = field.getText();
                int textWidth = metrics.stringWidth(text);
                int fieldWidth = field.getWidth();

                boolean currentlyTrimmed = textWidth > fieldWidth;

                if (currentlyTrimmed && !isTrimmed) {
                    isTrimmed = true;
                    onTextTrim();
                } else if (!currentlyTrimmed && isTrimmed) {
                    isTrimmed = false;
                    onTextShow();
                }
            }
        });
java swing
1个回答
0
投票

我不认为在条件改变时打印消息会让任务变得更容易。当我们仅在满足显示工具提示的先决条件(即当鼠标光标悬停在组件上或用户明确按下 control + f1 时)时检查条件时,要做的工作就更少了。

例如,您可以简单地更换线路

JFormattedTextField textField = new JFormattedTextField();

JFormattedTextField textField = new JFormattedTextField() {
    // needed because we have no static ToolTipText
    {   ToolTipManager.sharedInstance().registerComponent(this);  }

    @Override
    public String getToolTipText() {
        return getPreferredSize().width > getWidth()? getText(): null;
    }
};

要模仿某些外观的行为,直接在文本上显示剪切文本的工具提示,您可以添加

@Override
public Point getToolTipLocation(MouseEvent event) {
    return new Point(0, 0);
}

此组件。

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