Java JTextField中的预定义文本不可编辑,但可以附加其他文本?

Java JTextField中的预定义文本不可编辑,但可以附加其他文本?,java,swing,jtextfield,Java,Swing,Jtextfield,在使用JavaSwing时,我遇到了这个问题。 我有一个JTextField,它有预定义的、不可编辑的文本。用户应该能够向其附加其他文本,但无需编辑预定义文本。是否有任何方法可以获得此解决方案或任何其他解决方案 我有一个JTextField,它有预定义的、不可编辑的文本。这个 用户应该能够向其附加其他文本,但无需编辑 预定义文本。是否有任何方法可以获得此解决方案或其他解决方案 其他的 使用 与 最初由@camickr制作 import java.awt.event.*; import javax

在使用JavaSwing时,我遇到了这个问题。 我有一个JTextField,它有预定义的、不可编辑的文本。用户应该能够向其附加其他文本,但无需编辑预定义文本。是否有任何方法可以获得此解决方案或任何其他解决方案

我有一个JTextField,它有预定义的、不可编辑的文本。这个 用户应该能够向其附加其他文本,但无需编辑 预定义文本。是否有任何方法可以获得此解决方案或其他解决方案 其他的

使用

最初由@camickr制作

import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class NavigationFilterPrefixWithBackspace extends NavigationFilter {

    private int prefixLength;
    private Action deletePrevious;

    public NavigationFilterPrefixWithBackspace(int prefixLength, JTextComponent component) {
        this.prefixLength = prefixLength;
        deletePrevious = component.getActionMap().get("delete-previous");
        component.getActionMap().put("delete-previous", new BackspaceAction());
        component.setCaretPosition(prefixLength);
    }

    @Override
    public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {
        fb.setDot(Math.max(dot, prefixLength), bias);
    }

    @Override
    public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {
        fb.moveDot(Math.max(dot, prefixLength), bias);
    }

    class BackspaceAction extends AbstractAction {

        private static final long serialVersionUID = 1L;

        @Override
        public void actionPerformed(ActionEvent e) {
            JTextComponent component = (JTextComponent) e.getSource();
            if (component.getCaretPosition() > prefixLength) {
                deletePrevious.actionPerformed(null);
            }
        }
    }

    public static void main(String args[]) throws Exception {
        JTextField textField = new JTextField(" $ ", 20);
        textField.setNavigationFilter(new NavigationFilterPrefixWithBackspace(textField.getDocument().getLength(), textField));
        JFrame frame = new JFrame("Navigation Filter Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(textField);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
我建议在JTextField上使用OverlayLayout JLabel,方法是将JTextField中的Insets输入区域更改为JLabels区域,否则JTextField中的任何格式都会使此线程中的代码和建议变得毫无用处,并向Swing GUI提供奇怪的输出

e、 g.JTextField.setHorizontalAlignment JTextField.RIGHT

编辑

将JLabel和JTextField放到JPanel,非常简单,没有副作用

更改JPanel的内置流程布局

如果JLabel中的文本发生更改,则需要调用重新验证并重新绘制

看一看。它应该允许您定义文本的保护区域

示例和替代解决方案: 1.将$symbole放入jtext字段 2.当JTextField获得焦点时,删除美元符号 3.让用户修改全文 4.当他输入完后,再加上$SYMBOL

但是在JTextField旁边添加标签要容易得多,您只需使用DocumentFilter即可:


虽然我相信DocumentFilter是一个逻辑性和通用性很强的解决方案,但这里是一个简短的解决方案。它只是生成一个具有左内边距的JTextField,其中写入了固定文本

public class PrefixTextField extends JTextField {
    private String prefix;
    private JLabel label;

    public PrefixTextField(String prefix) {
        this.prefix = prefix;
        label = new JLabel(prefix + '\u00a0');
    }

    @Override
    protected void paintComponent(Graphics g) {
        int w = SwingUtilities.computeStringWidth(
                getFontMetrics(getFont()), prefix);
        setMargin(new Insets(3, 3 + w, 3, 3));
        super.paintComponent(g);
        SwingUtilities.paintComponent(g, label, this.getParent(),
                2 + 3, 0, getWidth(), getHeight());
    }
}

为什么不在文本字段前放置一个带有不可编辑文本的标签,如中所示?告诉我是否只想使用JTextfield?是的,我只需要使用JTextfield您可以查看最新SwingX版本中的BuddySupport API字符串的预定义文本部分是什么?那就是当你调用textField.getText时,你应该只得到用户输入的文本,还是也应该得到预定义的文本?我不能使用JComboBox,因为我必须使用一个包含一些文本$的JTextField,我希望用户在不编辑/删除美元符号的情况下输入数字。令人惊讶的是,说到Java,简单地使用这个词实际上是很好的,即使代码可能有100行长……实际上,我正在编辑一个已经存在的代码。因此,插入这么长的代码可能有点冒险。有什么简单的解决方案,比如使用方法或其他什么吗?@sanjeeda你不需要全部代码,只需要DocumentFilter的一部分。代码的其余部分只是为了显示一个完全可以工作的示例,以避免出现我尝试过的注释,但它不起作用;这是非常危险的。你应该称之为外部的绘画机制。
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class TestDocumentFilter {

    private static final String TEXT_NOT_TO_TOUCH = "You can't touch this!";

    private void initUI() {
        JFrame frame = new JFrame(TestDocumentFilter.class.getSimpleName());
        frame.setLayout(new FlowLayout());
        final JTextField textfield = new JTextField(50);
        textfield.setText(TEXT_NOT_TO_TOUCH);
        ((AbstractDocument) textfield.getDocument()).setDocumentFilter(new DocumentFilter() {
            @Override
            public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
                if (offset < TEXT_NOT_TO_TOUCH.length()) {
                    return;
                }
                super.insertString(fb, offset, string, attr);
            }

            @Override
            public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                if (offset < TEXT_NOT_TO_TOUCH.length()) {
                    length = Math.max(0, length - TEXT_NOT_TO_TOUCH.length());
                    offset = TEXT_NOT_TO_TOUCH.length();
                }
                super.replace(fb, offset, length, text, attrs);
            }

            @Override
            public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
                if (offset < TEXT_NOT_TO_TOUCH.length()) {
                    length = Math.max(0, length + offset - TEXT_NOT_TO_TOUCH.length());
                    offset = TEXT_NOT_TO_TOUCH.length();
                }
                if (length > 0) {
                    super.remove(fb, offset, length);
                }
            }
        });
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(textfield);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                new TestDocumentFilter().initUI();
            }
        });
    }

}
public class PrefixTextField extends JTextField {
    private String prefix;
    private JLabel label;

    public PrefixTextField(String prefix) {
        this.prefix = prefix;
        label = new JLabel(prefix + '\u00a0');
    }

    @Override
    protected void paintComponent(Graphics g) {
        int w = SwingUtilities.computeStringWidth(
                getFontMetrics(getFont()), prefix);
        setMargin(new Insets(3, 3 + w, 3, 3));
        super.paintComponent(g);
        SwingUtilities.paintComponent(g, label, this.getParent(),
                2 + 3, 0, getWidth(), getHeight());
    }
}