`
shiren1118
  • 浏览: 130467 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
社区版块
存档分类
最新评论

第23章 定制文本组件

    博客分类:
  • java
阅读更多

第23章 定制文本组件

  Swing文本建立在由javax.swing.text包的类和接口提供的一个复杂的下层构件之上。一般使用 Swing文本组件(在前两章中介绍)不要求对Swing文本包有很深的了解。但如果要定制文本组件,则要对javax.swing.text包有一个基 本的掌握。本章提供了定制通用任务的例子。如彩色文本、设置字符和段落属性、实现定制视图等。

23.1 概览

  与其他Swing组件一样,文本组件由一个模型(Document接口的一个实现)和一个UI代表 (javax.swing.plaf.basic.BasicTextUI类的一个扩展)组成。文本组件还使用一个编辑器工具包(EditorKit类的 一个扩展)和一个视图(View类的一个扩展)。图23-1示出了一个类图,这个类图说明了Swing文本域、这个域模型、UI代表、编辑器工具包和视图 之间的静态关系(注:23.4节“视图”讨论了视图,所有的文本组件都有一个或多个视图)。其他的Swing文本组件有类似的类图。

23.2 属性集和风格常量

例23-1 使用属性集


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import java.util.*;
import java.io.FileReader;

public class Test extends JFrame {
private JTextPane textPane = new JTextPane();
private StyledDocument document =
(StyledDocument)textPane.getDocument();

public Test() {
Container contentPane = getContentPane();
readFile("text.txt");
setAttributes();

textPane.setFont(new Font("Dialog", Font.PLAIN, 18));
contentPane.add(new JScrollPane(textPane),
BorderLayout.CENTER);
}
private void setAttributes() {
SimpleAttributeSet attributes = new SimpleAttributeSet();

StyleConstants.setForeground(attributes, Color.blue);
StyleConstants.setUnderline(attributes, true);

document.setCharacterAttributes(5,9,attributes,false);

StyleConstants.setForeground(attributes, Color.red);
StyleConstants.setStrikeThrough(attributes, false);

document.setCharacterAttributes(15,9,attributes,true);
}
private void readFile(String filename) {
EditorKit kit = textPane.getEditorKit();
try {
kit.read(new FileReader(filename), document, 0);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Setting Attributes",300,300,450,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

static {
resources = ResourceBundle.getBundle(
"GJApp", Locale.getDefault());
};

private GJApp() {}

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}


 

23.3 定制动作

 

例23-2 实现定制动作


import java.io.File;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.FileReader;

public class Test extends JFrame {
private JTextPane textPane = new JTextPane();
private StyledDocument document =
(StyledDocument)textPane.getDocument();
private StyledEditorKit kit =
(StyledEditorKit)textPane.getEditorKit();
private JColorChooser chooser = new JColorChooser();
private int CharacterMode = 0, ParagraphMode = 1;

public Test() {
Container contentPane = getContentPane();
readFile("text.txt");

textPane.setFont(new Font("Dialog", Font.PLAIN, 18));

contentPane.add(new JScrollPane(textPane),
BorderLayout.CENTER);

setJMenuBar(createMenuBar());
}
private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit");

editMenu.add(new ForegroundFromChooserAction(
"Character Foreground Color ... ",
CharacterMode));

editMenu.add(new ForegroundFromChooserAction(
"Paragraph Foreground Color ... ",
ParagraphMode));

menuBar.add(editMenu);
return menuBar;
}
private void readFile(String filename) {
try {
kit.read(new FileReader(filename), document, 0);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Custom Actions",300,300,650,275);
}
class ForegroundFromChooserAction
extends StyledEditorKit.StyledTextAction {

protected Color fg;
protected JColorChooser chooser = new JColorChooser();
protected int mode;

public ForegroundFromChooserAction(String nm, int mode) {
super(nm);
this.mode = mode;
}
public void actionPerformed(ActionEvent e) {
JEditorPane editor = getEditor(e);
if (editor != null) {
AttributeSet attributes =
textPane.getCharacterAttributes();
Color c =
StyleConstants.getForeground(attributes);

Color fg = chooser.showDialog(Test.this,
"Choose Color for Text",
c == null ? Color.black : c);
/*
if ((e != null) && (e.getSource() == editor)) {
String s = e.getActionCommand();
try {
fg = Color.decode(s);
}
catch(NumberFormatException ex) {
ex.printStackTrace();
}
}
*/
if (fg != null) {
MutableAttributeSet attr =
new SimpleAttributeSet();
StyleConstants.setForeground(attr, fg);

if(mode == CharacterMode)
setCharacterAttributes(editor, attr, false);
else
setParagraphAttributes(editor, attr, false);

textPane.setCaretPosition(
textPane.getSelectionStart());
} else {
Toolkit.getDefaultToolkit().beep();
}
}
}
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

static {
resources = ResourceBundle.getBundle(
"GJApp", Locale.getDefault());
};

private GJApp() {}

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}


23.4 视图

 

例23-3 实现一个定制视图


import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Test extends JFrame {
JEditorPane editorPane = new JEditorPane();
Vector positions = new Vector();
Position.Bias bias = Position.Bias.Forward;

class CustomView extends WrappedPlainView {
public CustomView(Element elem) {
super(elem);
}
public void paint(Graphics g, Shape a) {
super.paint(g,a);

Enumeration e = positions.elements();
Position p;

while(e.hasMoreElements()) {
try {
p = (Position)e.nextElement();
int offset = p.getOffset();

Shape s = modelToView(p.getOffset(), a, bias);
Rectangle r = s.getBounds();

// black border
g.setColor(Color.black);
g.drawRect(r.x, r.y, 6, 6);

// red fill
g.setColor(Color.red);
g.fillRect(r.x+1, r.y+1, 5, 5);
}
catch(BadLocationException ex) {
ex.printStackTrace();
}
}
}
};
class CustomEditorKit extends DefaultEditorKit
implements ViewFactory {
public ViewFactory getViewFactory() {
return this;
}
public View create(Element elem) {
return new CustomView(elem);
}
};
public Test() {
JPanel panel = new JPanel();
JButton button = new JButton("Insert Position");
Container contentPane = getContentPane();
panel.add(button);

editorPane.setEditorKit(new CustomEditorKit());
editorPane.setFont(new Font("Serif", Font.ITALIC, 36));

contentPane.add(panel, BorderLayout.NORTH);
contentPane.add(editorPane, BorderLayout.CENTER);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Document doc = editorPane.getDocument();
int p = editorPane.getCaretPosition();

positions.addElement(doc.createPosition(p));
editorPane.repaint();
}
catch(BadLocationException ex) {
ex.printStackTrace();
}
}
});
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Custom Text Views",300,300,450,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
}


23.5 风格和风格的相关内容

 

例23-4 使用风格的相关内容


import java.io.File;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.FileReader;

public class Test extends JFrame {
private JTextPane textPane = new JTextPane();
private Hashtable actionTable = new Hashtable();
private JCheckBoxMenuItem titleItem, bodyItem;

public Test() {
Container contentPane = getContentPane();

textPane.setEditorKit(new ChapterEditorKit());
textPane.setFont(new Font("Dialog", Font.PLAIN, 18));

// must load action table after setting editor kit ...
loadActionTable();

readFile("text.txt");

contentPane.add(new JScrollPane(textPane),
BorderLayout.CENTER);
contentPane.add(GJApp.getStatusArea(),BorderLayout.SOUTH);

setJMenuBar(createMenuBar());
}
private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit"),
styleMenu = new JMenu("Paragraph Styles");

styleMenu.add(getAction(ChapterStyleContext.titleStyle));
styleMenu.add(getAction(ChapterStyleContext.bodyStyle));

editMenu.add(styleMenu);
menuBar.add(editMenu);
return menuBar;
}
private void readFile(String filename) {
EditorKit kit = textPane.getEditorKit();
Document doc = textPane.getDocument();

try {
kit.read(new FileReader(filename), doc, 0);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
private void loadActionTable() {
Action[] actions = textPane.getActions();

for(int i=0; i < actions.length; ++i) {
actionTable.put(actions[i].getValue(Action.NAME),
actions[i]);
}
}
private Action getAction(String name) {
return (Action)actionTable.get(name);
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Custom EditorKits & Style Contexts",
300,300,650,275);
}
}
class ChapterEditorKit extends StyledEditorKit {
private CaretListener caretListener = new Listener();
private static ChapterStyleContext context =
new ChapterStyleContext();

private static Action[] defaultActions = new Action[] {
new ParagraphStyleAction(
ChapterStyleContext.titleStyle,
context.getStyle(ChapterStyleContext.titleStyle)),
new ParagraphStyleAction(
ChapterStyleContext.bodyStyle,
context.getStyle(ChapterStyleContext.bodyStyle)),
};
public Action[] getActions() {
return TextAction.augmentList(super.getActions(),
defaultActions);
}
public void install(JEditorPane editorPane) {
editorPane.addCaretListener(caretListener);
}
public void deinstall(JEditorPane editorPane) {
editorPane.removeCaretListener(caretListener);
}
static class Listener implements CaretListener {
public void caretUpdate(CaretEvent e) {
int dot = e.getDot(), mark = e.getMark();

if (dot == mark) {
JTextComponent c = (JTextComponent) e.getSource();
StyledDocument document =
(StyledDocument) c.getDocument();
Element elem = document.getParagraphElement(dot);
AttributeSet set = elem.getAttributes();
String name = (String)set.getAttribute(
StyleConstants.NameAttribute);

GJApp.showStatus(name);
}
}
}
static class ParagraphStyleAction
extends StyledEditorKit.StyledTextAction {
private Style style;

public ParagraphStyleAction(String nm, Style style) {
super(nm);
this.style = style;
}
public void actionPerformed(ActionEvent e) {
setParagraphAttributes(getEditor(e), style, false);
GJApp.showStatus(style.getName());
}
}
}
class ChapterStyleContext extends StyleContext {
public static String titleStyle = "title",
bodyStyle = "body";

public static String[] defaultStyleNames = new String[] {
new String(titleStyle),
new String(bodyStyle) };

public ChapterStyleContext() {
Style root = getStyle(DEFAULT_STYLE);

for(int i=0; i < defaultStyleNames.length; ++i) {
String name = defaultStyleNames[i];
Style s = addStyle(name, root);

if(name.equals(titleStyle)) {
StyleConstants.setFontFamily(s, "Dialog");
StyleConstants.setFontSize(s, 24);
StyleConstants.setBold(s, true);
StyleConstants.setUnderline(s, true);
}
else if(name.equals(bodyStyle)) {
StyleConstants.setFontFamily(s, "Times-Roman");
StyleConstants.setFontSize(s, 16);
}
}
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

static {
resources = ResourceBundle.getBundle(
"GJApp", Locale.getDefault());
};

private GJApp() {}

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}


23.6 元素

 

例23-5 元素层次


import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.FileReader;

public class Test extends JFrame {
private JTextComponent components[] = new JTextComponent[] {
new JTextField("initial content"), new JTextArea(10,20),
new JTextPane(), new JEditorPane(),
};
private String borderNames[] = new String[] {
"JTextField", "JTextArea", "JTextPane", "JEditorPane"
};
private JPanel textComponentPanel = new JPanel();
private ElementTreePanel treePanel =
new ElementTreePanel(components[0]);
private JSplitPane sp = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
new JScrollPane(textComponentPanel),
new JScrollPane(treePanel));

public Test() {
Container contentPane = getContentPane();
CaretListener listener = new Listener();

textComponentPanel.setBorder(
BorderFactory.createTitledBorder("Text Components"));

for(int i=0; i < components.length; ++i) {
JTextComponent c = (JTextComponent)components[i];

c.addCaretListener(listener);
c.setBorder(
BorderFactory.createTitledBorder(borderNames[i]));

if(i != 0) // JTextField
readFile(c, "text.txt");

if(i == 3) { // JEditorPane
JEditorPane
editorPane = (JEditorPane)c;

String url = "file:" +
System.getProperty("user.dir") +
System.getProperty("file.separator") +
"java.util.Hashtable.html";

editorPane.setEditable(false);
try {
editorPane.setPage(url);
}
catch(Exception ex) { ex.printStackTrace(); }

JScrollPane sp = new JScrollPane(c);
sp.setPreferredSize(new Dimension(450,450));
panel.add(sp);
}
else
panel.add(c);
}
sp.setDividerLocation(600);

contentPane.add(sp, BorderLayout.CENTER);
}
class Listener implements CaretListener {
public void caretUpdate(CaretEvent e) {
JTextComponent c = (JTextComponent)e.getSource();

if(c != treePanel.getEditor()) {
sp.setRightComponent(treePanel =
new ElementTreePanel(c));
}
}
}
private void readFile(JTextComponent c, String filename) {
try {
c.read(new FileReader(filename), null);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Element Hierarchies",300,300,800,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

private GJApp() {}

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

分享到:
评论

相关推荐

    SAP ABAP/4 开发宝典中文版

    第二章 ABAP/4程序语法和格式 12 第三章 将数据输出到屏幕 19 第四章 处理文本摘要 29 第五章 处理数据 35 第六章 控制ABAP/4程序流 61 第七章 创建和处理内表 91 第八章 模块化ABAP/4程序 122 第九章 使用字段符号 ...

    Tcl_TK编程权威指南pdf

    第23章 打包摆放布局管理器(pack) 朝一侧摆放 水平与垂直难叠 空腔模型( cavity model) 打包摆放空间(packing space)与显w空间(display space) 尺寸调整与一expand 挂靠 摆放顺序 选择用于摆放的父...

    Microsoft visual c++ 6.0 programmer's Guide 程序员指南

    第二部分 编辑器 第3章 文本编辑器 启动文本编辑器 文档 浏览文档 文本搜索 编程辅助工具 Advanced(高级)命令 未结合命令 宏的基础 定制编辑器 在Developer Studio之外编辑文本 第4章 资源 系统资源 RC资源脚本...

    IDL帮助(中文).doc

    第二章 简单的图形显示 25 本章概述 25 IDL中简单的图形显示 25 创建线画图 25 定制线画图 28 改变线条的线型和粗细 28 用符号代替线条显示数据 29 用不同的颜色绘制线画图 31 限定线画图的范围 31 改变线画图的风格...

    IDL入门教程.doc

    第二章 简单的图形显示 25 本章概述 25 IDL中简单的图形显示 25 创建线画图 25 定制线画图 28 改变线条的线型和粗细 28 用符号代替线条显示数据 29 用不同的颜色绘制线画图 31 限定线画图的范围 31 改变线画图的风格...

    Visual Basic 6编程技术大全 中译本扫描版带书签 2/2

    第二部分用户界面313 第9章先进的窗体和对话框313 9.1窗体的标准用法313 9.1.1窗体作为对象313 9.1.2可复用窗体317 9.1.3窗体作为对象浏览器321 9.1.4动态控件创建324 9.1.5数据驱动窗体328 9.2 MDI窗体333 9.2.1 ...

    Visual Basic 6编程技术大全 中译本扫描版带书签 1/2

    第二部分用户界面313 第9章先进的窗体和对话框313 9.1窗体的标准用法313 9.1.1窗体作为对象313 9.1.2可复用窗体317 9.1.3窗体作为对象浏览器321 9.1.4动态控件创建324 9.1.5数据驱动窗体328 9.2 MDI窗体333 9.2.1 ...

    python入门到高级全栈工程师培训 第3期 附课件代码

    第23章 01 re模块之转义字符 02 re模块之分组 03 re模块之方法 04 re模块总结 05 logging模块 06 re模块补充 07 configparse模块 08 hashlib模块 09 计算器作业以及思路 10 模块导入补充 第24章 01 面向对象设计 ...

    flex3的cookbook书籍完整版dpf(包含目录)

    第二十三章.Adobe Integrated Runtime API(694) 23.1节.借助FlexFramework创建一个AIR程序 23.2节.理解AIR命令行工具 23.3节.打开和管理本地窗体 23.4节.创建本地菜单 23.5节.读写文件 23.6节.对象序列化 23.7节....

    Delphi 5编程实例与技巧

    第二部分 Delphi编程的核心技能 第3章 窗体和组件 53 3.1 窗体和组件 53 3.1.1 窗体 54 3.1.2 组件 56 3.1.3 在窗体中使用组件 57 3.2 文本组件 60 3.3 特殊输入组件 61 3.4 按钮及其分类组件 63 3.5 列表组件 64 ...

    DELPHI 5编程实例与技巧

    第二部分 Delphi编程的核心技能 第3章 窗体和组件 53 3.1 窗体和组件 53 3.1.1 窗体 54 3.1.2 组件 56 3.1.3 在窗体中使用组件 57 3.2 文本组件 60 3.3 特殊输入组件 61 3.4 按钮及其分类组件 63 3.5 列表组件 64 ...

Global site tag (gtag.js) - Google Analytics