构造JTextArea组件
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
构造JTextArea组件
9-4-1:构造JTextArea组件:
我们可以发现到JTextArea的构造函数和JTextField及JPasswordField的构造函数是相同雷同,而JTextArea多了一个字段的参数
值是因为JTextArea是二维的输入组件,在构造时不仅要设置字段长度也要设置行数。
我们来看下面这个范例:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextArea1{
public static void main(String[] args){
JFrame f=new JFrame("JTextArea1");
Container contentPane=f.getContentPane();
contentPane.setLayout(new BorderLayout());
JPanel p1=new JPanel();
p1.setLayout(new GridBagLayout());
GridBagConstraints gbc=new GridBagConstraints();
gbc.anchor=GridBagConstraints.WEST;
gbc.insets=new Insets(2,2,2,2);
p1.setBorder(BorderFactory.createTitledBorder("构造一般的JTextArea"));
JLabel l1=new JLabel("一:");
JLabel l2=new JLabel("二:");
JLabel l3=new JLabel("三:");
JLabel l4=new JLabel("四:");
JTextArea t1=new JTextArea();
JTextArea t2=new JTextArea(2,8);
JTextArea t3=new JTextArea("JTextArea3");
JTextArea t4=new JTextArea("JTextArea4",5,10);
t1.setText("JTextArea1");//setText()方法会将原来的内容清除
t2.append("JTextArea2");//append()方法会将设置的字符串接在原来JTextArea内容文字之后.
t4.setLineWrap(true);//设置换行
gbc.gridy=1;
gbc.gridx=0;
p1.add(l1,gbc);
gbc.gridx=1;
p1.add(t1,gbc);
gbc.gridy=2;
gbc.gridx=0;
p1.add(l2,gbc);
gbc.gridx=1;
p1.add(t2,gbc);
gbc.gridy=3;
gbc.gridx=0;
p1.add(l3,gbc);
gbc.gridx=1;
p1.add(t3,gbc);
gbc.gridy=4;
gbc.gridx=0;
p1.add(l4,gbc);
gbc.gridx=1;
p1.add(t4,gbc);
contentPane.add(p1);
f.pack();
f.show();
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
}
在JTextArea中我们可以使用setTabSize()方法设置[Tab]键的跳离距离,或是setFont()方法设置字体。
当我们输入的文字超过
JTextArea的右边界及下边界时,会看不到接下来打的内容,那该怎么办呢?你可以使用JScrollPane使JTextArea具备滚动的能力,
或是搭配setLineWrap()方法就能让文字自动换行。
JTextArea还提供一个setWrapStyleWord()方法,可以让换行的时候不会造成断
字的现象,这在Word或使用OutLook写信时都可以看到这个效果。
例如我们在行尾中输入“自动换行”四个字,但此行最多只能在容
纳两个字,因此JTextArea会将此四个字均移到下一行,不会造成“自动”在上行,"换行"在下行的情形。
这在处理英文输入上较为
重要,因为setWrapStyleWord()是利用空白当作是一个字输入的结果。
我们来看下面的范例:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextArea2{
public static void main(String[] args){
JFrame f=new JFrame("JTextArea2");
Container contentPane=f.getContentPane();
contentPane.setLayout(new BorderLayout());
JPanel p1=new JPanel();
p1.setLayout(new GridLayout(1,1));
p1.setBorder(BorderFactory.createTitledBorder("构造TextArea-使用GridLayout,加ScrollBar"));
JTextArea t1=new JTextArea(5,25);
t1.setTabSize(10);
t1.setFont(new Font("标楷体",Font.BOLD,16));
t1.setLineWrap(true);//激活自动换行功能
t1.setWrapStyleWord(true);//激活断行不断字功能
p1.add(new JScrollPane(t1));//将JTextArea放入JScrollPane中,这样就能利用滚动的效果看到输入超过JTextArea高度的
//文字.
contentPane.add(p1);
f.pack();
f.show();
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
}
我们再举一个例子,使JTextArea具有copy、paste、cut的功能:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextArea3 implements ActionListener{
JTextArea textarea=null;
JButton b1,b2,b3;
public JTextArea3(){
JFrame f=new JFrame("JTextArea3");
Container contentPane=f.getContentPane(); contentPane.setLayout(new BorderLayout());
textarea=new JTextArea(10,15);
JScrollPane scrollPane=new JScrollPane(textarea); JPanel panel=new JPanel();
panel.setLayout(new GridLayout(1,3));
b1=new JButton("Copy");
b1.addActionListener(this);
b2=new JButton("Paste");
b2.addActionListener(this);
b3=new JButton("Cut");
b3.addActionListener(this);
panel.add(b1);
panel.add(b2);
panel.add(b3);
contentPane.add(scrollPane,BorderLayout.CENTER); contentPane.add(panel,BorderLayout.SOUTH);
f.pack();
f.show();
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){ System.exit(0);
}
});
}
public static void main(String[] args){
new JTextArea3();
}
public void actionPerformed(ActionEvent e){
if (e.getSource()==b1){
textarea.copy();
}
if (e.getSource()==b2){
textarea.paste();
}
if (e.getSource()==b3){
textarea.cut();
}
}
}
9-4-2:JTextArea的事件处理:
由于JTextArea是一个二维的输入组件,因此[Enter]键在JTextArea中代表的意义只是单纯的换行字符而不再是一个事件驱动的
切入点。
那么我们该如何来处理JTextArea的事件呢?还记得我们在前面介绍过Listener的机制吗?相同的,我们一样需要使用
Listener的机制来处理发生在JTextArea中的事件,只是不再是以前提到的ActionListener了。
在JTextArea中使用的Listener有两
种,一个是UndoableEditListener,另一个是
DocumentListener.UndoableEditListener interface是负责纪录JTextArea中所有操作
发生的顺序并且可以运行还原上一步的功能。
这个功能在目前的软件中应用相当广泛,如文书编辑软件Word中的复原功能、小画家
中的复原功能,相信大家都有使用过。
DocumentListener interface则是纪录发生在JTextArea中所有的事件(如键入字符、删除
字符、剪下、贴上)并将所有的事件以树状的层次式结构组织起来;也就是说当JTextArea中的内容有任何变动时,会DocumentEvent
,此时必须使用DocumentListener接口中的方法来处理此事件。
我们来看下面这个范例,使JTextArea具有复原的功能:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/*由于会使用到复原和事件驱动功能,因此需要将javax.swing.undo和javax.swing.event两个package包含进来
*/
import javax.swing.undo.*;
import javax.swing.event.*;
/*JTextArea4类继承JFrame类并实作UndoableEditListener interface.实作UndoableEditListener interface就必须要编写其中的
*undoableEditHappened().
*/
public class JTextArea4 extends JFrame implements UndoableEditListener{
private UndoableEdit edit;
private JTextArea jta;
private JTextArea message;
private JMenuItem undoitem;
private JMenuItem redoitem;
public JTextArea4(){
super("JTextArea4");
jta = new JTextArea();
jta.getDocument().addUndoableEditListener(this);//将JTextArea加入
UndoableEditListener.
message = new JTextArea();
message.setEditable(false);//利用setEditable()方法将另一个JTextArea 设置为不可编辑.
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(1,1));
p1.setBorder(BorderFactory.createTitledBorder("Edit Area"));
p1.add(new JScrollPane(jta));
//--begin:分别将两个JTextArea通过JPanel放到JFrame中。
JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(1,1));
p2.setBorder(BorderFactory.createTitledBorder("Message"));
p2.add(new JScrollPane(message));
getContentPane().setLayout(new GridLayout(2,1));
getContentPane().add(p1);
getContentPane().add(p2);
//--end
//建立目录菜单并放置到JFrame中.
JMenuBar bar = new JMenuBar();
JMenu theMenu = new JMenu("Edit");
undoitem = new JMenuItem("Undo");
redoitem = new JMenuItem("Redo");
theMenu.add(undoitem);
theMenu.add(redoitem);
bar.add(theMenu);
updateMenuItem();//构造目录菜单
setJMenuBar(bar);
setSize(300,300);
//采用inner class方式,分别构造菜单选项被点选后的运行操作。
分别调用undo(),redo()方法来完成.
undoitem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
edit.undo();
updateMenuItem();//运行undo功能
message.append("- Undo -\n");
}
});
redoitem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
edit.redo();
updateMenuItem();//运行redo功能
message.append("- Redo -\n");
}
});
}//end of JTextArea4()
public void undoableEditHappened(UndoableEditEvent ev){
StringBuffer buf = new StringBuffer(200);
/*当用户在Text Area中有所操作时,就可以用getEdit()方法取得UndoableEdit对象,此对象纪录着刚刚用户的操作,因
*此可由些对象的undo()或redo()达到取消或复原的功能.
*/
edit = ev.getEdit();
buf.append("undoableEdit:");
buf.append(edit.getPresentationName());
buf.append("\n");
message.append(buf.toString());
updateMenuItem();
}//end of undoableEditHappened()
//判断是否此时是否可以运行undo或redo的功能,并且改变目录菜单的状态值. public void updateMenuItem(){
if (edit != null){
undoitem.setEnabled(edit.canUndo());
redoitem.setEnabled(edit.canRedo());
undoitem.setText(edit.getUndoPresentationName());
redoitem.setText(edit.getRedoPresentationName());
}else{
undoitem.setEnabled(false);
redoitem.setEnabled(false);
undoitem.setText("Undo");
redoitem.setText("Redo");
}
}//end of updateMenu()
public static void main(String args[]) {
JFrame f = new JTextArea4();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.show();
}//end of main()
}//end of class JTextArea4
我们在前面提到Enter键在JTextArea中不再是事件驱动的切入点,因此我们要利用Listener的机制来控制JTextArea的事件驱动。
但是,我们要怎么样知道在JTextArea中的数据内容呢?这就要了解JTextArea 的存储模式了,JTextArea把输入区内的每一行当成
一个独立的单无(Element),并依照Document内规划的树状结构来存储,也就是说在JTextArea的第一行属于Element 0、第二行属于
Element 1、第三行属于Element 2等等。
不论我们在费心的去处理。
接下来我们来看看,Element和DocumentListener interface的
用法。
我们改写JTextArea4.java加入DocumentListener,将程序存储为JTextArea5.java.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.undo.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class JTextArea5 extends JFrame implements UndoableEditListener,DocumentListener{
private UndoableEdit edit;
private JTextArea jta;
private JTextArea message;
private JMenuItem undoitem;
private JMenuItem redoitem;
public JTextArea5(){
super("JTextArea");
jta=new JTextArea();
jta.getDocument().addUndoableEditListener(this);
jta.getDocument().addDocumentListener(this);
message = new JTextArea();
message.setEditable(false);
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(1,1));
p1.setBorder(BorderFactory.createTitledBorder("Edit Area"));
p1.add(new JScrollPane(jta));
JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(1,1));
p2.setBorder(BorderFactory.createTitledBorder("Message")); p2.add(new JScrollPane(message));
getContentPane().setLayout(new GridLayout(2,1)); getContentPane().add(p1);
getContentPane().add(p2);
JMenuBar bar = new JMenuBar();
JMenu theMenu = new JMenu("Edit");
undoitem = new JMenuItem("Undo");
redoitem = new JMenuItem("Redo");
theMenu.add(undoitem);
theMenu.add(redoitem);
bar.add(theMenu);
updateMenuItem();
setJMenuBar(bar);
setSize(300,300);
undoitem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
edit.undo();
updateMenuItem();
message.append("- Undo -\n");
}
});
redoitem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
edit.redo();
updateMenuItem();
message.append("- Redo -\n");
}
});
} //end of JTextArea5
public void undoableEditHappened(UndoableEditEvent ev){ StringBuffer buf = new StringBuffer(200);
edit = ev.getEdit();
buf.append("undoableEdit:");
buf.append(edit.getPresentationName());
buf.append("\n");
message.append(buf.toString());
updateMenuItem();
}//end of undoableEditHappened()
public void updateMenuItem(){
if (edit != null){
undoitem.setEnabled(edit.canUndo());
redoitem.setEnabled(edit.canRedo());
undoitem.setText(edit.getUndoPresentationName()); redoitem.setText(edit.getRedoPresentationName());
}else{
undoitem.setEnabled(false);
redoitem.setEnabled(false);
undoitem.setText("Undo");
redoitem.setText("Redo");
}
}//end of updateMenu()
public void showDE(DocumentEvent de){
StringBuffer debuf=new StringBuffer(100);
debuf.append(de.getType());
debuf.append("Offset:");
debuf.append(de.getOffset());
debuf.append("Length:");
debuf.append(de.getLength());
Element Eroot=jta.getDocument().getDefaultRootElement(); DocumentEvent.ElementChange Echange=de.getChange(Eroot); if (Echange==null) {
debuf.append("(No Element Change)");
}else{
debuf.append("Element Change:index");
debuf.append("Echange.getIndex()");
}
debuf.append("\n");
message.append(debuf.toString());
}
public void changedUpdate(DocumentEvent de){
showDE(de);
}
public void insertUpdate(DocumentEvent de){
showDE(de);
}
public void removeUpdate(DocumentEvent de){
showDE(de);
}
public static void main(String[] args){
JFrame f=new JTextArea5() ;
f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0);
}
});
f.show();
}
}。