Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JTextField中的预定义文本不可编辑,但可以附加其他文本?_Java_Swing_Jtextfield - Fatal编程技术网

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

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

在使用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);
        }
    }
    

    • 我建议使用OverlayLayout(JLabel overjtextfield),方法是将JTextField中的inset(输入区域)更改为JLabels区域,否则JTextField中的任何格式都会使该线程中的代码和建议变得毫无用处,并向Swing GUI输出奇怪

    • e、 g.
      JTextField.setHorizontalAlignment(JTextField.RIGHT)


    编辑

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

    • 更改JPanel的内置流程布局

    • 如果JLabel中的文本发生更改,则需要调用revalidate()和repaint()

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

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


    但是在JTextField旁边添加标签要容易得多

    您只需使用
    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();
                }
            });
        }
    
    }
    
    导入java.awt.FlowLayout;
    导入javax.swing.JFrame;
    导入javax.swing.JTextField;
    导入javax.swing.SwingUtilities;
    导入javax.swing.text.AbstractDocument;
    导入javax.swing.text.AttributeSet;
    导入javax.swing.text.BadLocationException;
    导入javax.swing.text.DocumentFilter;
    公共类TestDocumentFilter{
    私有静态最终字符串文本\u NOT\u TO\u TOUCH=“你不能碰这个!”;
    私有void initUI(){
    JFrame=newJFrame(TestDocumentFilter.class.getSimpleName());
    frame.setLayout(新的FlowLayout());
    最终JTextField textfield=新JTextField(50);
    textfield.setText(文本不可触摸);
    ((AbstractDocument)textfield.getDocument()).setDocumentFilter(新DocumentFilter()){
    @凌驾
    public void insertString(FilterBypass fb,int offset,String String,AttributeSet attr)引发BadLocationException{
    如果(偏移量0){
    超级。删除(fb、偏移、长度);
    }
    }
    });
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(textfield);
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    }
    公共静态void main(字符串[]args){
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    新建TestDocumentFilter().initUI();
    }
    });
    }
    }
    
    虽然我相信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
    的一部分。代码的其余部分只是为了显示一个完全工作的示例,以避免出现诸如“我尝试了,但它没有工作”之类的注释paintComponent
    中的code>非常危险。你应该称之为外部的绘画机制。
    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());
        }
    }