一、文本输入
文本域(JTextField)和文本区(JTextArea)组件用于获取文本输入。JTextField只能接收单行文本输入而JTextArea可以接收多行文本输入。
JTextField和JTextArea都继承于JTextComponent类。可以通过调用setText(String t),getText()方法设置或获取文本组件中的内容。
可以通过setEditable(boolean b)方法设置文本组件内容是否可编辑。
文本域:
文本域添加到窗口中的办法与按钮基本一致,添加到面板或者其它容器中,再添加到窗口。
JPanel jpanel = new JPanel();
JTextField jtf = new JTextField("Default",20);//创建一个初始内容为Default,显示20列大小的文本域。
jpanel.add(jtf);
上述的20列是指该文本域可以显示的字符是20个,但可以输入更多,输入更多的时候文本域会滚动,然后显示后面的20个字符。
这里的列数只是给AWT一个首选的大小,当布局管理器调整组件大小时,显示的字符也是变动的。
如果需要在运行时重新设置列数,则可以调用setColumns方法设置。在调用了setColumns方法后还需要调用包含这个文本域的容器的revalidate方法。
jtf.setColumns(30);
jpanel.revalidate();
在调用了revalidate方法后,布局管理器会重新计算容器内组件大小,并进行重新布局。该方法是JComponent类。
如果想重新计算一个JFrame中的所有组件,需要调用validate()方法,因为JFrame并未扩展JComponent类。
标签与标签组件:
标签(JLabel)是容纳文本的组件,没有任何修饰,也不响应用户输入。使用标签标识组件。例如使用标签标识文本域。
JLabel的构造器允许指定初始文本和图标,也可以选择内容的排列方式。可以使用SWingConstants接口中的常量来指定排列方式。
JLabel label = new JLabel("Minutes",SwingConstants.RIGHT);
setText和setIcon方法可以设置标签的显示内容和图标。标签放入与其它组件一样。
二、文本域变化跟踪
所有文本组件的模型都有Document接口描述,其既包括无格式的文本,也包括格式化的文本。
当文本的内容发生改变时,可以要求文档给予通告而非文本组件。这就需要文档监听器(DocumentListener)。
jtf.getDocument().addDocumentListener(listener);
文档监听器接口DocumentListener中有三个方法
void changedUpdate(DocumentEvent e); //文本域不会调用该方法
void insertUpdate(DocumentEvent e); //当文本域添加字符时调用
void removeUpdate(DocumentEvent e); //当文本域删除字符时调用
接口DocumentListener没有对应的适配器类,因此对于文档监听接口必须实现这三个方法。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.math.*;
import java.awt.geom.*;
import javax.swing.event.*;
public class ClockTextTest01
{
public static void main(String[] args)
{
ClockFrame calcFrame = new ClockFrame();
calcFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calcFrame.setVisible(true);
}
}
class ClockFrame extends JFrame
{
public ClockFrame()
{
setTitle("Clock");
//创建存储文本组件的面板
JPanel clockText = new JPanel();
//创建文档监听器
DocumentListener docClockListener = new DocumentClockListener();
//创建标签和文本域
JLabel labelHour = new JLabel("Hour");
hourText = new JTextField("12",3);
JLabel labelMinute = new JLabel("Minute");
minuteText = new JTextField("00",3);
//文本域添加文档监听器
hourText.getDocument().addDocumentListener(docClockListener);
minuteText.getDocument().addDocumentListener(docClockListener);
//将标签和文本域添加到面板
clockText.add(labelHour);
clockText.add(hourText);
clockText.add(labelMinute);
clockText.add(minuteText);
//将面板添加到窗口下方
add(clockText,BorderLayout.SOUTH);
clkPanel=new ClockPanel();
add(clkPanel,BorderLayout.CENTER);
pack();
}
//文档监听器
class DocumentClockListener implements DocumentListener
{
public void insertUpdate(DocumentEvent e)
{
setClock();
}
public void removeUpdate(DocumentEvent e)
{
setClock();
}
public void changedUpdate(DocumentEvent e)
{
//nothing
}
}
public void setClock()
{
try
{
int hours = Integer.parseInt(hourText.getText().trim());
int minutes = Integer.parseInt(minuteText.getText().trim());
clkPanel.setTime(hours,minutes);
}
catch(NumberFormatException e)
{
//e.printStackTrace();
int hours=12;
int minutes=0;
clkPanel.setTime(hours,minutes);
}
}
private JTextField hourText;
private JTextField minuteText;
private ClockPanel clkPanel;
}
class ClockPanel extends JPanel
{
public ClockPanel()
{
setPreferredSize(new Dimension(2*radius+1,2*radius+1));
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D grap2D = (Graphics2D)g;
Ellipse2D circle = new Ellipse2D.Double(0,0,2*radius,2*radius);
grap2D.draw(circle);
double hourAngle = Math.toRadians(360*minutes/(12*60));
double minuAngle = Math.toRadians(360*minutes/60);
drawLine(grap2D,hourAngle,hourHand);
drawLine(grap2D,minuAngle,minuHand);
}
public void drawLine(Graphics2D g,double angle,double handlength)
{
Point2D endP = new Point2D.Double(
radius+handlength*Math.sin(angle),
radius-handlength*Math.cos(angle)
);
Point2D startP = new Point2D.Double(radius,radius);
g.draw(new Line2D.Double(startP,endP));
}
public void setTime(int hours,int minutes)
{
this.minutes=hours*60+minutes;
repaint();
}
private double minutes=0;
private static final int radius=100;
private static final double hourHand=radius*0.6;
private static final double minuHand=radius*0.8;
}
运行结果: