所有文本构件都可以绘制和编辑存储在实现了Document接口的类的模型对象中的数据。JTextField和JTextArea构件使用的是
PlainDocument,该构件只储存普通文本的行序列,而不进行任何格式化。JEditorPane可以展示和编辑各种格式的样式文本,特别
是HTML,StyleDocument接口描述了对样式、字体和颜色的额外需求,而HTMLDocument类实现了这个接口。
应该让文档来通知我们数据发生变化,方法是在文档上安装文档监听器DocumentListener。
JFormattedTextField类,当格式化文本框失去焦点时,格式器会检查用户输入的文本字符串。失去焦点的默认行为称为提交或回复。
过滤器:防止用户键入非法字符。过滤器可以拦截插入命令,并修改字符串或放弃插入操作。通过过滤机制避免所有无效字符串是不可
能的。
校验器:在任意JComponent上附着,可以就无效输入对用户发出警告。必须扩展InputVerifier类并定义verify方法。如果该构件失
去焦点,那么校验器就会被查询。如果校验器报告该构件无效,那么该构件就会立即重新获得焦点,用户就被强制要求在进行其他输入之前先
订正刚输入的内容。
标准格式器:NumberFormat类、DateFormat类、DefaultFormatter类、MaskFormatter类。
定制格式器:需要扩展DefaultFormatter类,并覆盖String valueToString(Object value)、
Object stringToValue(String text)。
JSpinner是包含一个文本框以及两个在文本框旁边的小按钮的构件。当点击按钮时,文本框的值就会递增或递减。微调器中的值可以是
数字、日期、列表中的值,或是更为普遍的情况,即前驱和后继可以确定的任何值序列。可以用微调器迭代任何值集合,只需将一个
SpinnerListModel传递给JSpinner构造器即可。通过定义自已的微调器模型,可以在微调器中显示任意的序列,需要扩展
AbstractSpinnerModel类并定义Object getValue();void setValue(Object value);Object getNextValue();
Object getPreviousVaule().
public class TextDemo extends JFrame { public static void main(String[] args){ new TextDemo().setVisible(true); } public TextDemo(){ setTitle("TextDemo"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(WIDTH, HEIGHT); northPanel = new JPanel(); //跟踪文本构件 MyDocumentListener myDocumentListener = new MyDocumentListener(); northPanel.add(new JLabel("Red:")); redField = new JTextField("255", 3); redField.getDocument().addDocumentListener(myDocumentListener); northPanel.add(redField); northPanel.add(new JLabel("Green:")); greenField = new JTextField("255", 3); greenField.getDocument().addDocumentListener(myDocumentListener); northPanel.add(greenField); northPanel.add(new JLabel("Blue:")); blueField = new JTextField("255", 3); blueField.getDocument().addDocumentListener(myDocumentListener); northPanel.add(blueField); setColor(); centerPanel = new JPanel(); //格式化文本设置过滤器 filterFormattedTextField = new JFormattedTextField( new InternationalFormatter(NumberFormat.getIntegerInstance()){ protected DocumentFilter getDocumentFilter(){ return filter; } private DocumentFilter filter = new MyFilter(); } ); filterFormattedTextField.setValue(new Integer(1000)); //格式化文本设置校验器 verifiedFormattedTextField = new JFormattedTextField(NumberFormat.getIntegerInstance()); verifiedFormattedTextField.setValue(new Integer(1000)); verifiedFormattedTextField.setInputVerifier(new MyVerifier()); centerPanel.add(new JLabel("Filter:")); centerPanel.add(filterFormattedTextField); centerPanel.add(new JLabel("Verified:")); centerPanel.add(verifiedFormattedTextField); //格式化文本 try{ MaskFormatter formatter = new MaskFormatter("###-##-####"); formatter.setPlaceholderCharacter(' '); formattedTextField = new JFormattedTextField(formatter); formattedTextField.setValue("078-25-4646"); centerPanel.add(new JLabel("Mask:")); centerPanel.add(formattedTextField); }catch (Exception e) { e.printStackTrace(); } southPanel = new JPanel(); boundSpinner = new JSpinner(new SpinnerNumberModel(5, 0, 10, 0.5)); southPanel.add(boundSpinner); String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); fontSpinner = new JSpinner(new SpinnerListModel(fonts){ public Object getNextValue() { return super.getPreviousValue(); } public Object getPreviousValue() { return super.getNextValue(); } }); southPanel.add(fontSpinner); //定制JSpinner spinner = new JSpinner(new MySpinnerModel("meat")); southPanel.add(spinner); add(northPanel, BorderLayout.NORTH); add(centerPanel, BorderLayout.CENTER); add(southPanel, BorderLayout.SOUTH); pack(); } private void setColor(){ try{ int red = Integer.parseInt(redField.getText().trim()); int green = Integer.parseInt(greenField.getText().trim()); int blue = Integer.parseInt(blueField.getText().trim()); northPanel.setBackground(new Color(red, green, blue)); }catch (Exception e) { } } //跟踪文本框的修改 private class MyDocumentListener implements DocumentListener{ public void changedUpdate(DocumentEvent event) { } public void insertUpdate(DocumentEvent event) { setColor(); } public void removeUpdate(DocumentEvent event) { setColor(); } } //设置过滤器 private class MyFilter extends DocumentFilter{ public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException{ System.out.println("string:" + string); StringBuilder builder = new StringBuilder(string); for(int i=builder.length()-1;i>=0;i--){ int cp = builder.codePointAt(i); if(!Character.isDigit(cp) && cp != '-'){ builder.deleteCharAt(i); if(Character.isSupplementaryCodePoint(cp)){ i--; builder.deleteCharAt(i); } } } super.insertString(fb, offset, builder.toString(), attr); } public void replace(FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException{ if(string != null){ StringBuilder builder = new StringBuilder(string); for(int i=builder.length()-1;i>=0;i--){ int cp = builder.codePointAt(i); if(!Character.isDigit(cp)&&cp!='-'){ builder.deleteCharAt(i); if(Character.isSupplementaryCodePoint(cp)){ i--; builder.deleteCharAt(i); } } } string = builder.toString(); } super.replace(fb, offset, length, string, attr); } } //设置校验器 private class MyVerifier extends InputVerifier{ public boolean verify(JComponent component) { JFormattedTextField field = (JFormattedTextField)component; return field.isEditable(); } } //自定义微调器 private class MySpinnerModel extends AbstractSpinnerModel{ public MySpinnerModel(String word) { this.word = word; } public Object getNextValue() { int[] codePoints = toCodePointArray(word); for(int i = codePoints.length - 1;i>0;i--){ if(codePoints[i-1]