JTextField into which predefined text can be added to editable but different text?

After going through Java swing, I ran into this problem. I have a JTextField that has predefined and non-editable text. the user should be able to add other text to it, but without editing the predefined text. Is there any way to get this solution or any other?

+4
source share
5 answers

I have a JTextField that has predefined and non-editable text. the user should be able to add other text to it, but without editing a predefined text. Is there any method to get this solution or any other?

use

originally made by @camickr

enter image description here

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); } } 
  • I would suggest using OverlayLayout (JLabel over JTextField), changing Insets (input area) in JTextField for JLabels area, otherwise any formatting in JTextField will make the code and sentence in this stream completely useless and with a strange exit to the Swing GUI

  • eg. JTextField.setHorizontalAlignment(JTextField.RIGHT);


EDIT

  • put JLabel and JTextField in JPanel, pretty simple and without side effects

  • change in FlowLayout for JPanel

  • it is required to call revalidate () and repaint () in case of text change in JLabel

enter image description here

 import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; public class NavigationFilterBias { private JFrame frame = new JFrame("Navigation Filter Example"); private JPanel panel = new JPanel(); private JLabel label = new JLabel(" $ "); private JTextField textField = new JTextField(); public NavigationFilterBias() { panel.setBorder(textField.getBorder()); panel.setBackground(textField.getBackground()); panel.setLayout(new BorderLayout()); panel.add(label,BorderLayout.WEST); textField.setBorder(null); panel.add(textField,BorderLayout.CENTER); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(panel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String args[]) throws Exception { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { NavigationFilterBias exam = new NavigationFilterBias(); } }); } } 
+2
source

You can simply use 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(); } }); } } 
+2
source

Take a look at DocumentFilter . This should allow you to define a "protected" area of ​​text.

Examples here and here

+1
source

Although I believe DocumentFilter is a logical and universal solution, here is a short solution. It simply creates a JTextField with an internal left margin in which the fixed text is written.

 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()); } } 
+1
source

Alternative solution:
1. Put the $ symbol in the JTextField
2. Remove the dollar sign when the JTextField gets focus. 3. Let the user change the full text
4. When he typed the text ( see here ), add the symbol $ symbole back

But it would be easier to add a label next to the JTextField

-1
source

All Articles