《Java编程入门官方教程》第十六章练习答案
【练习16-1(SwingFC.java)】基于Swing的文件比较实用程序
虽然读者只学习了一点有关Swing的知识,但是已经可以使用这些知识来创建一个实用的小程序了。练习10-1中创建了一个基于控制台的文件比较实用程序,本练习将创建该程序的一个基于Swing的版本。你将会看到,为该程序提供基于Swing的用户界面能够显著改善程序的外观,使它易于使用。图16-6为该程序的输出。
由于Swing简化了基于GUI程序的创建,你会对创建该程序的简单程度感到惊奇。
package javaone.a.beginners.guide.chaptersixteen;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;
public class ChapterSixteenProgramOne implements ActionListener {
JTextField jtfFirst; // holds the first file name
JTextField jtfSecond; // holds the second file name
JButton jbtnComp; // button to compare the files
JLabel jlabFirst, jlabSecond; // display prompts
JLabel jlabResult; // display results and error messages
ChapterSixteenProgramOne(){
// Create a new JFrame container.
JFrame jfrm = new JFrame("Compare Files");
// Specify FlowLayout for the layout manager.
jfrm.setLayout(new FlowLayout());
// Give the frame an initial size.
jfrm.setSize(200, 190);
// Terminate the program when the user closes the application.
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create the text fields for the file names.
jtfFirst = new JTextField(14);
jtfSecond = new JTextField(14);
// Set the action commands for the text fields.
jtfFirst.setActionCommand("fileA");
jtfSecond.setActionCommand("fileB");
// Create the Compare button.
jbtnComp = new JButton("Compare");
// Add action listener for the Compare button.
jbtnComp.addActionListener(this);
// Create the labels.
jlabFirst = new JLabel("First file: ");
jlabSecond = new JLabel("Second file: ");
jlabResult = new JLabel("");
// Add the compontents to the content pane.
jfrm.add(jlabFirst);
jfrm.add(jtfFirst);
jfrm.add(jlabSecond);
jfrm.add(jtfSecond);
jfrm.add(jbtnComp);
jfrm.add(jlabResult);
// Display the frame.
jfrm.setVisible(true);
}
// Compare the files when the Compare button is pressed.
@Override
public void actionPerformed(ActionEvent ae) {
int i=0, j=0;
// First, confirm that both file names have
// been entered.
if(jtfFirst.getText().equals("")){
jlabFirst.setText("First file name missing.");
}
if(jtfSecond.getText().equals("")){
jlabSecond.setText("Second file name missing.");
}
// Compare files. Use try-with-resources to manage the files.
try(FileInputStream fOne = new FileInputStream(jtfFirst.getText());
FileInputStream fTwo = new FileInputStream(jtfSecond.getText())) {
// Check the contents of each file.
do{
i = fOne.read();
j = fTwo.read();
if(i != j){
break;
}
}while (i != -1 && j != -1);
if(i != j){
jlabResult.setText("Files are not the same.");
}else{
jlabResult.setText("Files compare equal.");
}
}catch (IOException exc){
jlabResult.setText("File Error");
}
}
public static void main(String[] args) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ChapterSixteenProgramOne();
}
});
}
}
16.11 自测题
1. 一般而言,AWT组件是重量级的,而Swing组件是________。
答案:轻量级。
2. Swing组件的外观和行为可以修改吗?如果可以,是哪一种功能提供的支持?
答案:可以,Swing的可插入式外观支持该操作。
3. 应用程序最常用的顶级容器是什么?
答案:JFrame。
4. 顶级容器有多个窗格,哪一个窗格用来添加组件?
答案:内容窗格。
5. 说明如何创建一个包含消息"Select an entry from the list"的标签?
答案:JLabel("Select an entry from the list");
6. 与GUI组件的所有交互都必须发生在哪个线程之上?
答案:事件分派线程。
7. 与JButton关联的默认动作命令是什么?如何修改该动作命令?
答案:默认的动作命令字符串是按钮中显示的文本,可以通过调用setActionCommand()方法修改。
8. 单击按钮时生成什么事件?
答案: ActionEvent。
9. 如何创建一个包含32列的文本域?
答案:JTextField(32);
10. JTextField有动作命令集吗?如果有,它是如何起作用的?
答案:可以,通过调用setActionCommand()。
11. 哪种Swing组件可以创建复选框,选中和取消选中复选框时将发生哪一种事件?
答案:JCheckBox创建复选框。ItemEvent事件在选中或取消选中复选框时生成。
12. JList显示一个条目列表,用户可以从中进行选择,这种说法是否正确?
答案:正确。
13. 用户在JList中选择或取消选择条目时将生成什么事件?
答案:ListSelectionEvent。
14. 什么方法用来设置JList的选择模式?什么方法获得第一个选中的条目的索引?
答案:setSelectionMode()设置选择模式。getSelectionIndex()获取第一个选中条目的索引。
15. 为练习15-1中开发的文件比较器添加一个复选框,包含以下文本:Show position of mismatch(显示未匹配的位置)。当复选框选中时,让程序显示文件中遇到的第一处未匹配的位置。
package javaone.a.beginners.guide.chaptersixteen;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;
/*
Try This 16-1
A Swing-based file comparsion utility.
This version has a check box that causes the
location of the first mismatch to be shown.
*/
public class ChapterSixteenExerciseFifteen implements ActionListener {
JTextField jtfFirst; // holds the first file name
JTextField jtfSecond; // holds the second file name
JButton jbtnComp; // button to compare the files
JLabel jlabFirst, jlabSecond; // display prompts
JLabel jlabResult; // display results and error messages
JCheckBox jcbLoc; // check to display location of mismatch
ChapterSixteenExerciseFifteen(){
// Create a new JFrame container.
JFrame jfrm = new JFrame("Compare Files");
// Specify FlowLayout for the layout manager.
jfrm.setLayout(new FlowLayout());
// Give the frame an initial size.
jfrm.setSize(200, 220);
// Terminate the program when the user closes the application.
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create the text fields for the file names.
jtfFirst = new JTextField(14);
jtfSecond = new JTextField(14);
// Set the action commands for the text fields.
jtfFirst.setActionCommand("fileA");
jtfSecond.setActionCommand("fileB");
// Create the Compare button.
jbtnComp = new JButton("Compare");
// Add action listener for the Compare button.
jbtnComp.addActionListener(this);
// Create the labels.
jlabFirst = new JLabel("First file: ");
jlabSecond = new JLabel("Second file: ");
jlabResult = new JLabel("");
// Create check box.
jcbLoc = new JCheckBox("Show position of mismatch");
// Add the compontents to the content pane.
jfrm.add(jlabFirst);
jfrm.add(jtfFirst);
jfrm.add(jlabSecond);
jfrm.add(jtfSecond);
jfrm.add(jcbLoc);
jfrm.add(jbtnComp);
jfrm.add(jlabResult);
// Display the frame.
jfrm.setVisible(true);
}
// Compare the files when the Compare button is pressed.
@Override
public void actionPerformed(ActionEvent e) {
int i=0, j=0;
int count = 0;
// First, confirm that both file names have
// been entered.
if(jtfFirst.getText().equals("")){
jlabFirst.setText("First file name missing.");
}
if(jtfSecond.getText().equals("")){
jlabSecond.setText("Second file name missing.");
}
// Compare files. Use try-with-resources to manage the files.
try(FileInputStream fOne = new FileInputStream(jtfFirst.getText());
FileInputStream fTwo = new FileInputStream(jtfSecond.getText())) {
// Check the contents of each file.
do{
i = fOne.read();
j = fTwo.read();
if(i != j){
break;
}
count++;
}while (i != -1 && j != -1);
if(i != j){
if(jcbLoc.isSelected()){
jlabResult.setText("Files differ at location " + count);
}else{
jlabResult.setText("Files are not the same.");
}
}else{
jlabResult.setText("Files compare equal.");
}
}catch (IOException exc){
jlabResult.setText("File Error");
}
}
public static void main(String[] args) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ChapterSixteenExerciseFifteen();
}
});
}
}
16. 修改ListDemo程序,使其允许在列表中选中多个条目。
package javaone.a.beginners.guide.chaptersixteen;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
// Demonstarte multiple selection in a JList.
public class ChapterSixteenExerciseSixteen implements ListSelectionListener {
JList<String> jlst;
JLabel jlab;
JScrollPane jscrlp;
// Create an array of names.
String names[]= { "Sherry", "Jon", "Rachel",
"Saaha", "Josselyn", "Randy",
"Tom", "Mary", "Ken",
"Andrew", "Matt", "Todd"
};
ChapterSixteenExerciseSixteen(){
// Create a new JFrame container.
JFrame jfrm = new JFrame("JList Demo");
// Specify a flow layout.
jfrm.setLayout(new FlowLayout());
// Given the frame an initial size.
jfrm.setSize(200, 160);
// Terminate the program when the user closes the application.
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create a JList.
jlst = new JList<String>(names);
// By removing following line, multiple selection (which
// is the default behavior of a JList) will be used.
// jlst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// Add list to a scroll pane.
jscrlp = new JScrollPane(jlst);
// Set the preferred size of the scroll pane.
jscrlp.setPreferredSize(new Dimension(120, 90));
// Make a label that displays the selection.
jlab = new JLabel("Please choose a name");
// Add list selection handler.
jlst.addListSelectionListener(this);
// Add the list and label to the content pane.
jfrm.add(jscrlp);
jfrm.add(jlab);
// Display the frame.
jfrm.setVisible(true);
}
// Handle list selection events.
@Override
public void valueChanged(ListSelectionEvent le) {
// Get the indices of the changed item.
int indices[] = jlst.getSelectedIndices();
// Display the selection, if one or more items
// were selected.
if(indices.length != 0){
String who = "";
// Contruct a string of the names:
for(int i: indices){
who += names[i] + " ";
}
jlab.setText("Current selection: " + who);
}else{ // Otherwise, reprompt.
jlab.setText("Please choose a name");
}
}
public static void main(String[] args) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ChapterSixteenExerciseSixteen();
}
});
}
}