JTextField,其中可以将不可编辑但其他文本的预定义文本追加到其中?
在经历Java swing时我遇到了这个问题。 我有一个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(); } }); } }
我有一个JTextField,它有预定义的,不可编辑的文本。 用户应该能够将其他文本附加到其中但不编辑预定义文本。 是否有任何方法可以获得此解决方案或任何其他方法?
使用
-
JComboBox(不可编辑)
-
带有SpinnerListModel的 JSpinner
最初由@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 over JTextField),通过在JTextField中为JLabels区域更改Insets(输入区域),否则JTextField中的任何格式化都会使此线程中的代码和建议毫无用处,并且对Swing GUI有奇怪的输出
-
例如
JTextField.setHorizontalAlignment(JTextField.RIGHT);
编辑
-
将JLabel和JTextField放到JPanel,非常简单,没有副作用
-
为JPanel更改内置的FlowLayout
-
在更改JLabel中的文本的情况下,需要调用revalidate()和repaint()
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(); } }); } }
看看DocumentFilter
。 它应该允许您定义文本的“受保护”区域。
这里和这里的例子
虽然我相信DocumentFilter是合乎逻辑的多function解决方案,但这里只是一个简短的解决方案。 它只是创建一个内部左边距的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()); } }
替代方案:
1.将$ symbole放在JTextField中
2.当JTextField获得焦点时,删除美元符号
3.让用户修改全文
4.当他完成打字( 见这里 )后,再添加$ symbole
但是在JTextField旁边添加标签会更容易
- TransactionEventHandler在Node.setProperty()上给出javax.transaction.SystemException
- 图像resize质量(Java)
- 如何强制JSON-lib的JSONObject.put(..)转义包含JSON的字符串?
- java.lang.NoSuchFieldError:INSTANCE
- 如何在Jenkins上运行TestNG测试
- 如何在不破坏默认实现的情况下为JPanel实现MouseWheelListener?
- 2个节点之间的最长路径
- Spring事务管理器(注释样式)运行时错误
- 通过localhost上的Java EE读取电子邮件Outlook