Java核心技术(高级Swing)三文本构件

所有文本构件都可以绘制和编辑存储在实现了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构件

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]<codePoints[i]){ int j = codePoints.length - 1; while(codePoints[i-1]>codePoints[j])j--; swap(codePoints, i - 1, j); reverse(codePoints, i, codePoints.length - 1); return new String(codePoints, 0, codePoints.length); } } reverse(codePoints, 0, codePoints.length - 1); return new String(codePoints, 0, codePoints.length); } public Object getPreviousValue() { int[] codePoints = toCodePointArray(word); for(int i = codePoints.length - 1;i>0;i--){ if(codePoints[i-1]>codePoints[i]){ int j = codePoints.length - 1; while(codePoints[i-1]<codePoints[j])j--; swap(codePoints, i - 1, j); reverse(codePoints, i, codePoints.length - 1); return new String(codePoints, 0, codePoints.length); } } reverse(codePoints, 0, codePoints.length - 1); return new String(codePoints, 0, codePoints.length); } public Object getValue() { return word; } public void setValue(Object value) { if(!(value instanceof String)) throw new IllegalArgumentException(); word = (String)value; fireStateChanged(); } private int[] toCodePointArray(String str){ int[] codePoints = new int[str.codePointCount(0, str.length())]; for(int i = 0, j = 0;i < str.length();i++, j++){ int cp = str.codePointAt(i); if(Character.isSupplementaryCodePoint(cp)) i++; codePoints[j] = cp; } return codePoints; } private void swap(int[] a, int i, int j){ int temp = a[i]; a[i] = a[j]; a[j] = temp; } private void reverse(int[] a, int i, int j){ while(i<j){ swap(a, i, j); i++; j--; } } private String word; } private JTextField redField; private JTextField greenField; private JTextField blueField; private JPanel northPanel; private JPanel centerPanel; private JFormattedTextField filterFormattedTextField; private JFormattedTextField verifiedFormattedTextField; private JFormattedTextField formattedTextField; private JPanel southPanel; private JSpinner boundSpinner; private JSpinner fontSpinner; private JSpinner spinner; private static final int WIDTH = 500; private static final int HEIGHT = 400; }

你可能感兴趣的:(java,exception,swing,String,object,jcomponent)