swing中的输入输出学习记录
近期看学习java中的swing程序设计,感觉基本上和Qt开发没有太大差异,主要差异在语法上,记录学习过程中的一个例子。
环境如下:
- jdk1.8;
- 编译器为IDEA。
知识点
使用FileWriter
和FileReader
两个方法实现文件的写入和读取,并结合swing开发窗体程序(对应《java从入门到精通(第5版)》15.4.2节的内容,程序如下图:
窗体为文本域JTextArea
,在文本域中写入内容,点击写入文件,可以保存一个txt文件,点击读取文件,可以将这个txt文件中的内容取出来显示在文本域中。
代码
书中有代码,但不太适合新手,我按自己的理解写了一下完整的代码,记录如下:
package Number;
import jdk.jfr.events.FileReadEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
public class MapText extends JFrame {
private JScrollPane scrollPane = new JScrollPane();
private static final long serialVersionUID = 1L;
private JPanel jContentPane;
private JTextField jTextField = new JTextField();
private JTextArea jTextArea = new JTextArea();
private JPanel controlPane;
private JButton openButton;
private JButton closeButton;
private JPanel getControlPane(){
controlPane = new JPanel();
FlowLayout flowLayout = new FlowLayout();
flowLayout.setVgap(1);
controlPane.setLayout(flowLayout);
controlPane.add(getOpenButton());
controlPane.add(getCloseButton());
return controlPane;
};
private JButton getOpenButton(){
openButton = new JButton("写入文件");
openButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
File file = new File("text.txt");
try {
FileWriter writer = new FileWriter(file);
String s = jTextArea.getText();
writer.write(s);
writer.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
});
return openButton;
};
private JButton getCloseButton(){
closeButton = new JButton("读取文件");
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
File file = new File("text.txt");
try {
FileReader reader = new FileReader(file);
char chars[] = new char[1024];
int len = reader.read(chars);
jTextArea.setText(new String(chars, 0, len));
reader.close();
} catch (FileNotFoundException fileNotFoundException) {
fileNotFoundException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
});
return closeButton;
};
private MapText(){
super();
setSize(400, 300);
setTitle("JFrame");
scrollPane.setViewportView(jTextArea);
setContentPane(getjContentPane());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
};
private JPanel getjContentPane(){
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(scrollPane, BorderLayout.CENTER);
jContentPane.add(getControlPane(), BorderLayout.SOUTH);
return jContentPane;
};
public static void main(String[] args) throws IOException {
MapText mapText = new MapText();
}
}
-
MapText
类继承自JFrame
父类,在类中定义了多个私有成员变量,都是swing的控件,主要如下:private JScrollPane scrollPane = new JScrollPane(); private static final long serialVersionUID = 1L; private JPanel jContentPane; private JTextField jTextField = new JTextField(); private JTextArea jTextArea = new JTextArea(); private JPanel controlPane; private JButton openButton; private JButton closeButton;
其中
JTextField
文本控件没有用到,但是我还是要写在这里,待会儿会解释。 -
设计面板功能
private JPanel getControlPane(){ controlPane = new JPanel(); FlowLayout flowLayout = new FlowLayout(); flowLayout.setVgap(1); controlPane.setLayout(flowLayout); controlPane.add(getOpenButton()); controlPane.add(getCloseButton()); return controlPane;
这个方法返回的是一个面板对象,这些面向对象的写法不太熟悉,但得适应。
这个方法设计了这个窗体的布局为流布局,并增加了两个按钮,这两个按钮就是这个窗体的主要功能。一般情况下,按钮都要添加监听,也就是Qt中的信号槽和槽函数,监听在按钮的两个方法中重写了。
-
写入文件按钮监听
private JButton getOpenButton(){ openButton = new JButton("写入文件"); openButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { File file = new File("text.txt"); try { FileWriter writer = new FileWriter(file); String s = jTextArea.getText(); writer.write(s); writer.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } }); return openButton;
同样是一个私有的方法,返回的是一个按钮对象,在这个方法中,新建了写入文件这个按钮,并为这个按钮重写了监听方法。
FileWriter writer = new FileWriter(file);
在写这行代码时,IDEA会提醒你抛出异常,按要求添加即可。这里有个知识点,覆盖和追加的问题,现在写入是覆盖写入,FileWriter writer = new FileWriter(file, true);
这种写法是追加。我这里改成了使用追加的方式。 -
读取文件按钮监听。与写入按钮类似,不再记录。
-
构造方法
private MapText(){ super(); setSize(400, 300); setTitle("JFrame"); scrollPane.setViewportView(jTextArea); setContentPane(getjContentPane()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); };
构造方法是核心,基本上所有的功能都可以在构造方法中写,这也是新手常见的写法,但是会很臃肿,所以熟练的人会写很多类似上面的成员方法,然后在构造方法中去调用。
我来逐行解释记录:
-
super();
继承JFrame父类; -
setSize(400, 300);
设置窗体大小; -
scrollPane.setViewportView(jTextArea);
Java中向滚动面板中添加文本域,一种是直接添加,一种是用setViewportView()方法(创建一个视口,并在括号内设置其视图),第一种一般在创建滚动面板的时候就把文本域添加进去了,这里用的是第二种; -
setContentPane(getjContentPane());
这里又有一个知识点,就是对JFrame窗体添加控件的两种方法:-
用
getContentPane()
方法获得JFrame的内容面板,再对其加入组件:frame.getContentPane().add(childComponent)
,本例中想要用这种方法,该如何写呢,如下:Container c = getContentPane(); c.add(getjContentPane());
-
建立一个Jpanel或JDesktopPane之类的中间容器,把组件添加到容器中,用setContentPane()方法把该容器置为JFrame的内容面板,也就是这里的写法。
-
-
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
设置窗体的默认关闭方法,也就是点×就是退出程序。 -
setVisible(true);
运行程序时使窗体可见。
-
-
构造面板容器
private JPanel getjContentPane(){ jContentPane = new JPanel(); jContentPane.setLayout(new BorderLayout()); jContentPane.add(scrollPane, BorderLayout.CENTER); jContentPane.add(getControlPane(), BorderLayout.SOUTH); return jContentPane; };
构造方法中调用了
getjContentPane()
方法,这里写的就是这个成员方法,它返回一个面板对象,并在构造方法中用setContentPane
方法将这个面板控件添加到容器中去。 -
主方法中实例化类。
至此完成这个小项目的全部介绍。
结果展示
看一下结果
swing中的输入输出学习记录
补充
前面提到,
其中
JTextField
文本控件没有用到
从代码上也可以看到,我用的是文本域,为什么不用JTextField,因为这是一个文本框控件,用它的话只有一行可以写,使用回车键无法换行,而且文本框会出现在面板的中部,而不是像文本域一样布满整个面板控件。
至此完成这个小项目的全部介绍。
记录到此结束,继续学习吧。