基本文本组件(三)

15.4 JPasswordField类

JPasswordField组件被设计用来处理密码输入。密码文本域会显示一个特殊的输入掩码,而不会回显用户的输入。其作用类似于具有*输入掩码的JTextField。我们不能取消掩码设置,也不能剪切或是复制密码组件的内容。其目的就是为了强强安全性。

15.4.1 创建JPasswordField

与JTextField相同,JPasswordField类有五个构造函数:

public JPasswordField()
JPasswordField passwordField = new JPasswordField();
public JPasswordField(String text)
JPasswordField passwordField = new JPasswordField("Initial Password");
public JPasswordField(int columnWidth)
JPasswordField passwordField = new JPasswordField(14);
public JPasswordField(String text, int columnWidth)
JPasswordField passwordField = new JPasswordField("Initial Password", 14);
public JPasswordField(Document model, String text, int columnWidth)
JPasswordField passwordField = new JPasswordField(aModel, "Initial Password", 14);

使用无参数的构造函数,我们可以获得一个空的,零列宽的输入域,默认的初始化Document模型,以及*回显字符。尽管我们可以在构造函数中指定初始化文本,但是通常我们所要做的是提示用户输入密码来验证用户的标识,而不是确定用户是否可以提交一个表单。所以,JPasswordField的本意是在启动时是空的。类似于JTextField,我们也可以指定初始宽度,假定JPasswordField所在的窗口的布局管理器将处理这种请求。

我们也可以在构造函数中指定密码域的Document数据模型。当指定Document数据模型时,我们应该指定一个null初始化文本参数;否则,文档的当前内容就会被密码域的初始文本所替换。另外,我们不应尝试在JPasswordField中使用自定义的Document。因为组件在已输入多少字符之外并不会显示任何可视化的回馈,如果我们尝试将输入限制为数字数据,这会使用户感到迷惑。

15.4.2 JPasswordField属性

表15-6显示了JPasswordField的四个属性。


设置echoChar属性可以使得我们使用默认星号字符以外的掩码字符。如查echoChar属性被设置为字符\u0000(0),public boolean echoCharIsSet()方法会返回false。在其他的情况下,方法会返回true。

注意,JPasswordField有一个受保护的只读的text属性,我们应避免使用这个属性。相反,我们应使用password属性,因为他会返回一个char[]并在使用之后立即清除。一个String必须等待垃圾回收器来翻译。

15.4.3 自定义JPasswordField观感

JPasswordField是JTextField的一个子类。在所有预定义的观感类型下,他与JTextField具有相同的外观(如图15-15所示)。一个不同就是当前的echoChar属性设置隐藏内容。如图15-16所示。顶部的文本组件是一个JTextField;而底部则是一个JPasswordField。


表15-7显示了JPasswordField的17个UIResource相关的属性。




15.5 JFormattedTextField类

JFormattedTextField提供了格式化文本输入的支持。当这个组件创建时,我们为输入定义了一个掩码。这个掩码可以是以下四种格式之一:一个java.text.Format对象,一个AbstractFormatter,一个AbstractFormatterFactory或是一个不同类型的实际值(例如3.141592)。

依据我们希望用户输入的数据类型,系统为我们的使用提供了一些抽象格式器。例如,NumberFormatter可以用来输入数字,而DateFormatter可以用来输入整个日期。同时还有一个MaskFormatter用于描述具有编辑字行串的输入,例如用于美国社会保险号码的“XXX-XX-XXX”。如果我们希望不同的显示与编辑格式,我们可以使用AbstractFormatterFactory。我们将会在第16章中了解到关于格式器与格式器工厂的更多内容。

15.5.1 创建JFormattedTextField

JFormattedTextField类有六个构造函数:

public JFormattedTextField()
JFormattedTextField formattedField = new JFormattedTextField();
public JFormattedTextField(Format format)
DateFormat format = new SimpleDateFormat("yyyy--MMMM--dd");
JFormattedTextField formattedField = new JFormattedTextField(format);
public JFormattedTextField(JFormattedTextField.AbstractFormatter formatter)
DateFormat displayFormat = new SimpleDateFormat("yyyy--MMMM--dd");
DateFormatter displayFormatter = new DateFormatter(displayFormat);
JFormattedTextField formattedField = new JFormattedTextField(displayFormatter);
public JFormattedTextField(JFormattedTextField.AbstractFormatterFactory factory)
DateFormat displayFormat = new SimpleDateFormat("yyyy--MMMM--dd");
DateFormatter displayFormatter = new DateFormatter(displayFormat);
DateFormat editFormat = new SimpleDateFormat("MM/dd/yy");
DateFormatter editFormatter = new DateFormatter(editFormat);
DefaultFormatterFactory factory = new DefaultFormatterFactory(
  displayFormatter, displayFormatter, editFormatter);
JFormattedTextField formattedField = new JFormattedTextField(factory);
public JFormattedTextField(JFormattedTextField.AbstractFormatterFactory factory,
  Object currentValue)
DateFormat displayFormat = new SimpleDateFormat("yyyy--MMMM--dd");
DateFormatter displayFormatter = new DateFormatter(displayFormat);
DateFormat editFormat = new SimpleDateFormat("MM/dd/yy");
DateFormatter editFormatter = new DateFormatter(editFormat);
DefaultFormatterFactory factory = new DefaultFormatterFactory(
  displayFormatter, displayFormatter, editFormatter);
JFormattedTextField formattedField = new JFormattedTextField(factory, new Date());
public JFormattedTextField(Object value)
JFormattedTextField formattedField = new JFormattedTextField(new Date());

无参数的构造函数需要我们在稍后进行配置。其他的构造函数允许我们配置内容将会接受什么以及如何接受。

15.5.2 JFormattedTextField属性

表15-8显示了JFormattedTextField的八个属性。我们不必像使用JTextField时一样,通过text属性将JFormattedTextField的内容获取为一个String,而是可以通过value属性将其获取为一个Object。所以,如果我们的格式器用于一个Date对象,我们所获得的值可以转换为java.util.Date类型。


列表15-14演示了具有自定义格式器与工厂的JFormattedTextField的用户。注意,当我们编辑底部的文本域时,显示格式与编辑格式是不同的。

/**
 * 
 */
package swingstudy.ch15;
 
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
 
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;
 
/**
 * @author mylxiaoyi
 *
 */
public class FormattedSample {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Runnable runner = new Runnable() {
			public void run() {
				JFrame frame = new JFrame("Formatted Example");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
				JPanel datePanel = new JPanel(new BorderLayout());
				JLabel dateLabel =  new JLabel("Date: ");
				dateLabel.setDisplayedMnemonic(KeyEvent.VK_D);
				DateFormat format = new SimpleDateFormat("yyyy--MMMM--dd");
				JFormattedTextField dateTextField = new JFormattedTextField(format);
				dateLabel.setLabelFor(dateTextField);
				datePanel.add(dateLabel, BorderLayout.WEST);
				datePanel.add(dateTextField, BorderLayout.CENTER);
				frame.add(datePanel, BorderLayout.NORTH);
 
				JPanel date2Panel = new JPanel(new BorderLayout());
				JLabel date2Label = new JLabel("Date 2: ");
				date2Label.setDisplayedMnemonic(KeyEvent.VK_A);
				DateFormat displayFormat = new SimpleDateFormat("yyyy--MMMM--dd");
				DateFormatter displayFormatter = new DateFormatter(displayFormat);
				DateFormat editFormat = new SimpleDateFormat("MM/dd/yy");
				DateFormatter editFormatter = new DateFormatter(editFormat);
				DefaultFormatterFactory factory = new DefaultFormatterFactory(displayFormatter, displayFormatter, editFormatter);
				JFormattedTextField date2TextField = new JFormattedTextField(factory, new Date());
				date2Label.setLabelFor(date2TextField);
				date2Panel.add(date2Label, BorderLayout.WEST);
				date2Panel.add(date2TextField, BorderLayout.CENTER);
				frame.add(date2Panel, BorderLayout.SOUTH);
 
				ActionListener actionListener = new ActionListener() {
					public void actionPerformed(ActionEvent event) {
						JFormattedTextField source = (JFormattedTextField)event.getSource();
						Object value = source.getValue();
						System.out.println("Class: "+value.getClass());
						System.out.println("Value: "+value);
					}
				};
				dateTextField.addActionListener(actionListener);
				date2TextField.addActionListener(actionListener);
 
				frame.setSize(250, 100);
				frame.setVisible(true);
			}
		};
		EventQueue.invokeLater(runner);
	}
 
}


15.5.3 自定义JFormattedTextField观感

类似于JPasswordField,JFormattedTextField也是JTextField的一个子类。在所有的预定义的观感类型下,同样与JTextField具有相同的外观(如图15-15)。要自定义其显示,我们可以修改JFormattedTextField的16个UIResource相关的属性集合中的任何一个,如表15-9所示。


15.6 JTextArea类

JTextArea是用于多行输入的文本组件。类似于JTextField,JTextArea的数据模型是Document接口的PlainDocument实现。所以,JTextArea被限制为单属性文本。类似于其他的需要滚动的Swing组件,JTextArea本身不支持滚动。我们需要将JTextArea放在JScrollPane中来允许在JTextArea中进行滚动。

15.6.1 创建JTextArea

JTextArea有六个构造函数:

public JTextArea()
JTextArea textArea = new JTextArea();
public JTextArea(Document document)
Document document = new PlainDocument();
JTextArea textArea = new JTextArea(document);
public JTextArea(String text)
JTextArea textArea = new JTextArea("...");
public JTextArea(int rows, int columns)
JTextArea textArea = new JTextArea(10, 40);
public JTextArea(String text, int rows, int columns)
JTextArea textArea = new JTextArea("...", 10, 40);
public JTextArea(Document document, String text, int rows, int columns)
JTextArea textArea = new JTextArea(document, null, 10, 40);

除非特别指定,文本区域也可以存储零行与零列的内容。尽管这听起来像是一个严重的限制,我们只需要告诉文本区域来使得当前的LayoutManager处理我们的文本区域的尺寸。JTextArea的内容初始时是空的,除非使用起始文本字符串或是Document模型指定。

注意,其他的JTextArea初始设置包括一个Tab为八个位置以及关闭文字换行。要了解关于Tab的更多内容,可以查看第16章中的TabStop与TabSet类。

在创建了JTextArea之后,记得将JTextArea放在JScrollPane中。然后在屏幕上如果没有足够的空间,JScrollPane就会为我们管理滚动。

JTextArea textArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(textArea);
content.add(scrollPane);

图15-17显示了在JScrollPane之内以及在JScrollPane之外的JTextArea的样子。不在JScrollPanel中的JTextArea,我们不能看到超出屏幕边界的文本。依照设计,将光标移动进区域并不会使得顶部的内容向上移动。


15.6.2 JTextArea属性

表15-10显示了JTextArea的12个属性。


rows与columns属性直接来自于构造函数的参数。preferredScrollableViewportSize与scrollableTracksViewportWidth属性来自于用于滚动支持的Scrollable接口实现。font与preferredSize属性仅是自定义由JTextComponent继承的行为。

更为有趣的属性是lineCount,tabSize以及lineWrap与wrapStyledWorld。lineCount属性可以使得我们确定文本域中有多少行。这对于调整尺寸十分有用。tabSize属性可以使得我们控制文本区域中tab位置。默认情况下,这个值为8.

lineWrap与wrapStyleWord属性配合使用。默认情况下,较长行的换行是禁止的。如果我们允许换行(通过将lineWrap属性设置为true),较长行换行的时机依赖于wrapStyleWord属性设置。初始时,这个属性为false,意味着如果lineWrap属性为true,将会在字符边界处换行。如果lineWrap与wrapStyleWord都为true,那么一行中不会适的单词将会被换到下一行,类似于字处理器中的样子。所以,要获得大多数人所希望的单词换行的功能,我们应将JTextArea的两个属性都设置为true:

JTextArea textArea = new JTextArea("...");
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(textArea);

注意,Ctrl-Tab与Shift-Ctrl-Tab键的组合可以使得用户在JTextArea组件中变换焦点,而无需继承组件生成新类。

15.6.3 处理JTextArea事件

JTextArea并没有特定的事件。我们可以使用由JTextComponent继承的监听器中的一个或是关联一个InputVerifier。

有时,我们会在屏幕上放置一个JTextArea并在用户按下按钮之后获取其内容。而在另外一些时间,会涉及到更多的规划,此时我们希望在输入时监视输入,并且也许会进行相应的转换,例如:-)或是简单的笑脸。

15.6.4 自定义JTextArea观感

每一个可安装的Swing观感都提供了不同的JTextArea外观以及默认的UIResource值集合。图15-18显示在JTextArea组件在预安装的观感类型下的外观。注意,每一个外观上的基本区别在于JScrollPane的滚动条,他并不是JTextArea的实际部分。


表15-11显示了JTextArea的15个UIResource相关的属性集合。


15.7 JEditorPane类

JEditorPane类提供了显示与编辑多属性文本的功能。虽然JTextField与JTextArea只支持单颜色,单字体内容,JEditorPane允许我们使用各种风格(例如粗体,14点Helvetica,段落右对齐)或是HTML查看器的外观来标记我们的内容,如图15-19所示。


注意,JEditorPane的HTML支持只在具有某些扩展的HTML 3.2级别上可用,而编写本书时HTML 4.0x是当前的版本。级联样式表(CSS)被部分支持。

JEditorPane借助于一个特定的文本标记机制的EditorKit来支持多属性文本的显示与编辑。存在预定义的工具集来支持原始文本,HTML文档以及RTF文档。因为内容是多属性的,PlainDocument模型不再够用。相反,Swing以DefaultStyledDocument类的形式提供了一个StyledDocument来维护文档模型。其余的部分是一个新的HyperlinkListsener/HyperlinkEvent事件处理对用来监视文档中的超连接操作。

15.7.1 创建JEditorPane

JEditorPane有四个构造函数:

public JEditorPane()
JEditorPane editorPane = new JEditorPane();
public JEditorPane(String type, String text)
String content = "<H1>Got Java?</H1>";
String type = "text/html";
JEditorPane editorPane = new JEditorPane(type, content);
public JEditorPane(String urlString) throws IOException
JEditorPane editorPane = new JEditorPane("http://www.apress.com");
public JEditorPane(URL url) throws IOException
URL url = new URL("http://www.apress.com");
JEditorPane editorPane = new JEditorPane(url);

无参数的构造函数创建了一个空的JEditorPane。如果我们要初始化内容,我们可以直接指定文本或是其MIME类型。或者是我们可以指定获取内容的URL。URL可以作为一个String或是一个URL对象来指定。当我们将内容指定为一个URL,JEditorPane会由响应来确定MIME类型。

15.7.2 JEditorPane属性

表15-12显示了JEditorPane的11个属性。这些属性中的大部分仅是自定义父类的行为。


注意,page属性是非标准的,因为他有两个setter方法,但是只有一个getter方法。

JEditorPane的四个有趣属性是editorKit,contentType,page与text。editorKit属性是依据编辑器面板中的内容类型来配置的。我们将会在第16章中进行详细探讨其DefaultEditorKit,StyledEditorKit与HTMLEditorKit实现。contentType属性表示文档中内容类型的MIME类型。当我们在构造函数中(或是其他位置)设置内容时,这个属性会被自动设置。如果编辑器工具集不能确定MIME类型,我们可以进行手动设置。三个内建支持的数据类型是text/html,text/plain与text/rtf,通过预定义编辑器工具集的getContentType()方示可以获取这些类型。

page属性可以使得我们修改所显示的内容来反映一个特定URL的内容,从而我们可以以某种方式使用这些内容。text属性使得我们确定哪些文本内容基于当前的Document模型。

15.7.3 处理JEditorPane事件

因为JEditorPane仅是一个具有一些特殊显示特性的另一个文本区域组件,他支持与JTextArea组件相同的用于事件处理的监听器。另外,JEditorPane提供了一个特殊的监听器事件组合来处理文档中的超链接。

HyperlinkListener接口定义了一个方法,public void hyperlinkUpdate(HyperlinkEvent hyperlinkEvent),他使用一个HyperlinkEvent来响应-不要惊奇-超链接事件。事件包含一个报告事件类型的HyperlinkEvent.EventType并且使得我们进行不同的响应,或者是当选中时跟随链接或者是当在超链接上移动鼠标时改变光标(尽管这是默认发生的)。

下面是HyperlinkListener定义:

public interface HyperlinkListener implements EventListener {
  public void hyperlinkUpdate(HyperlinkEvent hyperlinkEvent);
}
And, here is the HyperlinkEvent definition:
public class HyperlinkEvent extends EventObject {
  // Constructors
  public HyperlinkEvent(Object source, HyperlinkEvent.EventType type, URL url);
  public HyperlinkEvent(Object source, HyperlinkEvent.EventType type, URL url,
    String description);
  public HyperlinkEvent(Object source, HyperlinkEvent.EventType type, URL url,
    String description, Element sourceElement)
  // Properties
  public String getDescription();
  public HyperlinkEvent.EventType getEventType();
  public Element getSourceElement();
  public URL getURL();
}

超链接类型将会是HyperlinkEvent.EventType类的三个常量之一:

  • ACTIVATED:通常涉及到在合适的内容上进行鼠标点击
  • ENTERED:在超链接内容上移动鼠标
  • EXITED:将鼠标移出超链接内容

所以,如果我们希望在工具栏上创建一个显示URL的HyperlinkListener,当在超链接之前并在激活时跟随超链接,我们可以创建我们自己的最简单的HTML帮助查看器。列表15-15中的HyperlinkListener实现将会为我们实现这一技巧。在监听器中提供了一些println语句,当鼠标位于URL之上并且URL被激活时显示URL。

/**
 * 
 */
package swingstudy.ch15;
 
import java.awt.EventQueue;
import java.awt.Frame;
import java.io.IOException;
import java.net.URL;
 
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.Document;
 
/**
 * @author mylxiaoyi
 *
 */
public class ActivatedHyperlinkListener implements HyperlinkListener {
 
	Frame frame;
	JEditorPane editorPane;
 
	public ActivatedHyperlinkListener(Frame frame, JEditorPane editorPane) {
		this.frame = frame;
		this.editorPane = editorPane;
	}
	/* (non-Javadoc)
	 * @see javax.swing.event.HyperlinkListener#hyperlinkUpdate(javax.swing.event.HyperlinkEvent)
	 */
	@Override
	public void hyperlinkUpdate(HyperlinkEvent event) {
		// TODO Auto-generated method stub
 
		HyperlinkEvent.EventType type= event.getEventType();
		final URL url = event.getURL();
		if(type==HyperlinkEvent.EventType.ENTERED) {
			System.out.println("URL: "+url);
		}
		else if(type==HyperlinkEvent.EventType.ACTIVATED) {
			System.out.println("Activated");
			Runnable runner = new Runnable() {
				public void run() {
					Document doc = editorPane.getDocument();
					try {
						editorPane.setPage(url);
					}
					catch(IOException ioException) {
						JOptionPane.showMessageDialog(frame, "Error following link", "Invalid link", JOptionPane.ERROR_MESSAGE);
						editorPane.setDocument(doc);
					}
				}
			};
			EventQueue.invokeLater(runner);
		}
	}
}

提示,不要忘记调用setEditable(false)方法将JEditorPane设置为只读。否则,查看器就成为了编辑器。

列表15-16是使用我们新创建的ActivatedHyperlinkListener类的完整示例。他所创建的窗体类似于前面图15-19中所示的页面,尽管是在图片中,About链接已经被跟随。

/**
 * 
 */
package swingstudy.ch15;
 
import java.awt.EventQueue;
import java.io.IOException;
 
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.event.HyperlinkListener;
 
 
 
/**
 * @author mylxiaoyi
 *
 */
public class EditorSample {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Runnable runner = new Runnable() {
			public void run() {
				JFrame frame = new JFrame("EditorPane Example");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
				try {
					JEditorPane editorPane = new JEditorPane("http://www.google.com");
					editorPane.setEditable(false);
 
					HyperlinkListener hyperlinkListener = new ActivatedHyperlinkListener(frame, editorPane);
					editorPane.addHyperlinkListener(hyperlinkListener);
					JScrollPane scrollPane = new JScrollPane(editorPane);
					frame.add(scrollPane);
				}
				catch(IOException e) {
					System.err.println("Unable to load: "+e);
				}
 
				frame.setSize(640, 480);
				frame.setVisible(true);
			}
		};
		EventQueue.invokeLater(runner);
	}
 
}

15.7.4 自定义JEditorPane观感

JEditorPane的外观类似于JTextArea。尽管所支持的内容不同,观感相关的属性通常是不同的。

表15-13显示了JEditorPane的15个UIResource相关的属性集合。属性的名字于JTextArea设置中的属性名字。


15.8 JTextPane类

JTextPane是JEditorPane的一种特殊形式,特别设计用来编辑(与显示)格式化文本。他与JEditorPane的唯一不同在于提供显示内容的方式,因为文本并不是像在HTML或是RTF文档中一样使用格式标记的。

JTextPane依赖设置文本属性的三个接口:AttributeSet用于基本的属性集合,MutableAttributeSet用于可修改的属性集合,Style用作与StyledDocument的部分相关联的属性集合。

本节将会介绍JTextPane。要了解关于在JTextPane中配置格式化内容不同部分的格式的信息可以查看第16章。

15.8.1 创建JTextPane

JTextPane只有两个构造函数:

public JTextPane()
JTextPane textPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane(textPane);
public JTextPane(StyledDocument document)
StyledDocument document = new DefaultStyledDocument();
JTextPane textPane = new JTextPane(document);
JScrollPane scrollPane = new JScrollPane(textPane);

无参数的构造函数初始时没有内容。第二个构造函数使得我们先创建Document,然后在JTextPane中使用。

提示,如果内容大于可用的屏幕空间,记得将我们的JTextPane放在JScrollPane中。

15.8.2 JTextPane属性

表15-14显示了JTextPane的八个属性。我们将会在第16章中详细探讨这些属性。



15.8.3 自定义JTextPane观感

JTextPane是JEditorPane的一个子类。他在所有预定义的观感类型下与JTextArea具有相同的外观(如图15-18所示)。尽管内容也许不同,但是观感是相同的。

表15-15中显示了JTextPane UIResource相关属性的可用集合。对于JTextPane组件,有15个不同的属性。其属性名字类似于JTextArea设置中的属性名字。


15.8.4 载入具有内容的JTextPane

列表15-17提供了一个向JTextPane载入StyledDocument内容的示例。这仅是向我们展示功能。Style,SimpleAttributeSet与StyledConstants的详细使用将会在第16章中进行探讨。

/**
 * 
 */
package swingstudy.ch15;
 
import java.awt.BorderLayout;
import java.awt.EventQueue;
 
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
 
/**
 * @author mylxiaoyi
 *
 */
public class TextPaneSample {
	private static String message = "In the beginning, there was COBOL, then there was FORTRAN, "+
	"then there was BASIC, ... and now there is Java.\n";
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Runnable runner = new Runnable() {
			public void run() {
				JFrame frame = new JFrame("TextPane Example");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
				StyleContext context = new StyleContext();
				StyledDocument document = new DefaultStyledDocument(context);
 
				Style style = context.getStyle(StyleContext.DEFAULT_STYLE);
				StyleConstants.setAlignment(style, StyleConstants.ALIGN_RIGHT);
				StyleConstants.setFontSize(style, 14);
				StyleConstants.setSpaceAbove(style, 4);
				StyleConstants.setSpaceBelow(style, 4);
 
				// Inset content
				try {
					document.insertString(document.getLength(), message, style);
				}
				catch(BadLocationException badLocationException) {
					System.err.println("Oops");
				}
 
				SimpleAttributeSet attributes = new SimpleAttributeSet();
				StyleConstants.setBold(attributes, true);
				StyleConstants.setItalic(attributes, true);
 
				// Insert content
				try {
					document.insertString(document.getLength(), "Hello Java", attributes);
				}
				catch(BadLocationException badLocationException) {
					System.err.println("Oops");
				}
 
				// Third style for icon/component
				Style labelStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
 
				Icon icon = new ImageIcon("Computer.gif");
				JLabel label = new JLabel(icon);
				StyleConstants.setComponent(labelStyle, label);
 
				// Insert content
				try {
					document.insertString(document.getLength(), "Ignored", labelStyle);
				}
				catch(BadLocationException badLocationException) {
					System.err.println("Oops");
				}
 
				JTextPane textPane = new JTextPane(document);
				textPane.setEditable(false);
				JScrollPane scrollPane = new JScrollPane(textPane);
				frame.add(scrollPane, BorderLayout.CENTER);
 
				frame.setSize(300, 150);
				frame.setVisible(true);
			}
		};
		EventQueue.invokeLater(runner);
	}
 
}

上述源码的关键行是调用insertString()与其style参数:

document.insertString(document.getLength(), message, style);

图15-20显示了具有一些段落内容的JTextPane的样子。注意,内容并没有限制为仅是广西;他也可以具有图片。


15.9 小结

在本章中,我们开始对Swing文本组件的细节进行探讨。我们首先了解了根文本组件,JTextComponent,以及为其他的文本组件定义了许多操作。然后我们探讨特定的文本组件,JTextField,JPasswordField,JFormattedTextField,JTextArea,JEditorPane与JTextPane。

我们同时探讨了构成不同的组件的各种片段。我们深入了基于Document接口,用于AbstractDocument与PlaintDocument类的文本组件模型。我们同时了解了使用DocumentFilter来创建自定义的组件限制文本组件的输入。噣上,我们探讨了用于显示光标与高亮文本的Caret与Highlighter接口,用于限制文本组件中移动的NavigationFilter,以及使得文本组件作为控制器的Keymap。类似于控制器,Keymap将用户的按钮转换为影响文本组件模型的特定动作。

我们同时了解了Swing文本组件中是如何处理事件的。除了基本的AWT事件处理类,Swing添加了一些特别设计的新类,使用CaretListener来监听光标移动,使用DocumentListener监听文档内容变化。而且通过InputVerifer还有一个通用的Swing输入验证支持。

在第16章中,我们将会进一步探讨Swing文本组件。本章仅是所有组件的基本特性,而下一章将会探讨使用TextAction,JFormattedField的格式化输入以及使用StyledDocument的配置Style对象的细节。同时我们还会在HTMLDocument标记中进行探讨。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值