我学到最多的是布局,太厉害啦,这个GridBagLayout和GridBagConstraints加起来就是无敌啊。
GridBagLayout bag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(bag);
c.weightx = 1;
c.weighty = 1;
/* 按行网格布局 */
setCons(0, 0, 1, 1);
this.add(label[0], c);
setCons(1, 0, 3, 1);
this.add(text[0], c);
setCons(4, 0, 1, 1);
this.add(button[0], c);
类似这种布局,比那个setBounds强多了。不过这个东西有个拿捏不好的地方,就是你的实际大小和网格的分配要弄好,不然就挤成一坨了。
我学到次多就是JTextField的监听,它和别的组件的监听不一样。
用的时候只要
text[2].addKeyListener(new TextFieldKeyListener());
就行了。
class TextFieldKeyListener implements KeyListener {
public void keyTyped(KeyEvent e) {
Object o = e.getSource();
if (o instanceof JTextField) {
char keyCh = e.getKeyChar();
Pattern pat = Pattern.compile("[0-9]");
if (!pat.matcher(String.valueOf(keyCh)).matches()) {
if (keyCh != ' ') // 回车字符
e.setKeyChar('\0');
}
}
}
public void keyPressed(KeyEvent arg0) {
}
public void keyReleased(KeyEvent arg0) {
String temp = text[2].getText();
if (temp.length() != 0) {
blockSize = Integer.parseInt(text[2].getText()) *
1024;
doGiveMsg();
}
}
}
我学到的第三就是RandomAccessFile读,写文件,按字节。
一般就是
RandomAcceffFile in=new RandomAccessFile(srcFile);
RandomAcceffFile out=new RandomAccessFile(targetFile);
byte bytes[]=new byte[1024];
in.read(bytes);
out.write(bytes);
in.close();
out.close();
上面那个是手打的。。意思就是把srcFile中的1024个bytes读出来防止bytes中,再将bytes写到targetFile中。
实际操作可以参考下面的FileCut中的run()函数。一般都会有
in.seek();
進度條這種東西竟然java也有:
/* JProgressBar */
bar.setOrientation(JProgressBar.HORIZONTAL);
bar.setMinimum(0);
bar.setMaximum(100);
bar.setValue(0);
bar.setStringPainted(true);
bar.addChangeListener(this);
bar.setPreferredSize(new Dimension(300, 20));
bar.setBorderPainted(true);
bar.setBackground(Color.white);
用的時候如上即可,其中
setPerferredSize()方法 是設置大小,而不是setSize();
setBorderPainted(true);繪製邊框
setStringPainted(true) ; 顯示字符
setOrientation(JProgressBar.HORIZONTAL); 水平顯示
進度控制:
int progress=0;
bar.setValue(progress);
對於進度條的監聽,也不太一樣:
bar.addChangeListener(this);
java里面的List和Arrays.sort();都让我很惊奇,能够很方便的操作。这些以前我都不知道。。。
最後貼出全部代碼:
package ouyang;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class FileCutter {
public static void main(String args[]) {
CutterFrame frame = new CutterFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class CutterFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public CutterFrame() {
setTitle("File Cut and Merge");
setSize(500, 600);
JTabbedPane tab = new JTabbedPane();
CutPanel cut = new CutPanel();
MergePanel merge = new MergePanel();
tab.add(cut, "File cutter");
tab.add(merge, "File merger");
add(tab);
}
/* CutterFrame 中的子类CutPanel用来存放cut面板 */
class CutPanel extends JPanel implements ActionListener, ChangeListener {
/**
*
*/
private static final long serialVersionUID = 1L;
JLabel label[] = new JLabel[6];
ButtonGroup bg = new ButtonGroup();
JRadioButton radio[] = new JRadioButton[5];
JButton button[] = new JButton[3];
JProgressBar bar = new JProgressBar();
JTextField text[] = new JTextField[5];
File srcFile, targetFile;
int blockSize = (int) (1.44 * 1024 * 1024 + 0.5);
int number = 0;
boolean flag = false;
GridBagLayout bag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
private boolean srcFlag = false;
public CutPanel() {
drawCutPanel();
initCutPanel();
addListener();
}
public void setCons(int x, int y, int width, int height) {
c.gridx = x;
c.gridy = y;
c.gridwidth = width;
c.gridheight = height;
}
public void drawCutPanel() {
label[0] = new JLabel("File Name:");
label[1] = new JLabel("File Size:");
label[2] = new JLabel("Blocks Size:");
label[3] = new JLabel("KB");
label[4] = new JLabel("Number of blocks:");
label[5] = new JLabel("Target file:");
text[0] = new JTextField(20);
text[1] = new JTextField(20);
text[2] = new JTextField(5);
text[3] = new JTextField(5);
text[4] = new JTextField(20);
radio[0] = new JRadioButton("1.44MB");
radio[1] = new JRadioButton("1.2MB");
radio[2] = new JRadioButton("720KB");
radio[3] = new JRadioButton("360KB");
radio[4] = new JRadioButton("Self defined:");
button[0] = new JButton("...");
button[1] = new JButton("...");
button[2] = new JButton("Cut Start:");
/* 设置布局格式 */
setLayout(bag);
c.weightx = 1;
c.weighty = 1;
/* 按行网格布局 */
setCons(0, 0, 1, 1);
this.add(label[0], c);
setCons(1, 0, 3, 1);
this.add(text[0], c);
setCons(4, 0, 1, 1);
this.add(button[0], c);
setCons(0, 1, 1, 1);
this.add(label[1], c);
setCons(1, 1, 3, 1);
this.add(text[1], c);
setCons(4, 1, 1, 1);
this.add(button[1], c);
setCons(0, 2, 1, 1);
this.add(label[2], c);
setCons(1, 2, 1, 1);
this.add(radio[0], c);
setCons(2, 2, 1, 1);
this.add(radio[1], c);
setCons(1, 3, 1, 1);
this.add(radio[2], c);
setCons(2, 3, 1, 1);
this.add(radio[3], c);
setCons(1, 4, 1, 1);
this.add(radio[4], c);
setCons(2, 4, 1, 1);
this.add(text[2], c);
setCons(3, 4, 1, 1);
this.add(label[3], c);
setCons(0, 5, 1, 1);
this.add(label[4], c);
setCons(1, 5, 1, 1);
this.add(text[3], c);
setCons(0, 6, 1, 1);
this.add(label[5], c);
setCons(1, 6, 3, 1);
this.add(text[4], c);
setCons(4, 6, 3, 1);
this.add(button[1], c);
setCons(0, 7, 1, 1);
this.add(button[2], c);
setCons(1, 7, 5, 1);
this.add(bar, c);
}
public void initCutPanel() {
/* 面板小细节 */
for (int i = 0; i < 5; i++)
text[i].setEditable(false);
for (int i = 0; i < 5; i++)
bg.add(radio[i]);
/* JProgressBar */
bar.setOrientation(JProgressBar.HORIZONTAL);
bar.setMinimum(0);
bar.setMaximum(100);
bar.setValue(0);
bar.setStringPainted(true);
bar.addChangeListener(this);
bar.setPreferredSize(new Dimension(300, 20));
bar.setBorderPainted(true);
bar.setBackground(Color.white);
}
public void addListener() {
/* 监听器 */
for (int i = 0; i < 3; i++)
button[i].addActionListener(this);
for (int i = 0; i < 5; i++)
radio[i].addActionListener(this);
/* text[2]的监听不太一样 */
text[2].addKeyListener(new TextFieldKeyListener());
}
/* 子类TextFieldKeyListener是用来监听JTextField的 */
class TextFieldKeyListener implements KeyListener {
public void keyTyped(KeyEvent e) {
Object o = e.getSource();
if (o instanceof JTextField) {
char keyCh = e.getKeyChar();
Pattern pat = Pattern.compile("[0-9]");
if (!pat.matcher(String.valueOf(keyCh)).matches()) {
if (keyCh != ' ') // 回车字符
e.setKeyChar('\0');
}
}
}
public void keyPressed(KeyEvent arg0) {
}
public void keyReleased(KeyEvent arg0) {
String temp = text[2].getText();
if (temp.length() != 0) {
blockSize = Integer.parseInt(text[2].getText()) * 1024;
doGiveMsg();
}
}
}
public void doGiveMsg() {
if (srcFlag) {
int temp2 = (int) (srcFile.length());
number = (temp2 >= blockSize) ? (int) ((double) temp2
/ blockSize + 0.99) : 1;
text[3].setText(String.valueOf(number));
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button[0]) {
JFileChooser fc = new JFileChooser("d:\\");
int val = fc.showOpenDialog(null);
if (0 == val) {
srcFile = fc.getSelectedFile();
/* 为防止出错,targetFile默认路径设为同目录下 */
targetFile = srcFile.getParentFile();
text[0].setText(srcFile.getPath());
text[1].setText(String.valueOf((int) ((double) srcFile
.length() / 1024 + 0.5)) + " KB");
srcFlag = true;
}
} else if (e.getSource() == radio[0]) {
blockSize = (int) (1.44 * 1024 * 1024 + 0.5);
text[2].setEditable(false);
text[2].setText(null);
doGiveMsg();
} else if (e.getSource() == radio[1]) {
blockSize = (int) (1.2 * 1024 * 1024 + 0.5);
text[2].setEditable(false);
text[2].setText(null);
doGiveMsg();
} else if (e.getSource() == radio[2]) {
blockSize = 720 * 1024;
text[2].setEditable(false);
text[2].setText(null);
doGiveMsg();
} else if (e.getSource() == radio[3]) {
blockSize = 360 * 1024;
text[2].setEditable(false);
text[2].setText(null);
doGiveMsg();
} else if (e.getSource() == radio[4]) {
text[2].setEditable(true);
doGiveMsg();
} else if (e.getSource() == button[1]) {
JFileChooser fc = new JFileChooser("d:\\");
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int val = fc.showOpenDialog(null);
if (0 == val) {
targetFile = fc.getSelectedFile();
text[4].setText(targetFile.getPath());
}
} else if (e.getSource() == button[2]) {
FileCut cut = new FileCut();
cut.run();
}
}
/* CutPanel 中的子类FileCut用来处理cut面板 */
class FileCut extends Thread {
public void run() {
int temp = 0;
try {
RandomAccessFile in = new RandomAccessFile(srcFile, "r");
for (int i = 0; i < number - 1; i++) {
File outFile = new File(targetFile, srcFile.getName()
+ "_part_" + ((i < 10) ? ("0" + i) : i));
RandomAccessFile out = new RandomAccessFile(outFile,
"rw");
byte bytes[] = new byte[blockSize];
in.read(bytes);
out.write(bytes);
out.close();
temp += blockSize;
in.seek(temp);
int progress = 100 / number * (i + 1);
bar.setValue(progress);
}
File lastOutFile = new File(targetFile, srcFile.getName()
+ "_part_" + (number - 1));
RandomAccessFile outt = new RandomAccessFile(lastOutFile,
"rw");
byte bytes[] = new byte[(int) (srcFile.length() - temp)];
in.read(bytes);
outt.write(bytes);
bar.setValue(100);
in.close();
} catch (Exception e) {
System.out.println("File Exception!");
}
}
}
@Override
public void stateChanged(ChangeEvent e) {
// TODO Auto-generated method stub
}
}
/* CutterFrame 中的子类MergePanel用来存放merge面板 */
class MergePanel extends JPanel implements ActionListener, ChangeListener {
JLabel label[] = new JLabel[4];
JButton button[] = new JButton[4];
JProgressBar bar = new JProgressBar();
JTextField text[] = new JTextField[3];
JTextArea area;
List mergeFileList;
JScrollPane scroll;
GridBagLayout bag;
GridBagConstraints c;
File srcFile, targetFile;
int number = 0;
int blockSize = 0;
File[] fileList;
public MergePanel() {
drawMergePanel();
initMergePanel();
addListener();
}
public void setCons(int x, int y, int width, int height) {
c.gridheight = height;
c.gridx = x;
c.gridy = y;
c.gridwidth = width;
}
public void drawMergePanel() {
label[0] = new JLabel("File Name:");
label[1] = new JLabel("Files to be merge:");
label[2] = new JLabel("Number of files:");
label[3] = new JLabel("Targer file:");
button[0] = new JButton("...");
button[1] = new JButton("Remove");
button[2] = new JButton("Clear");
button[3] = new JButton("Start merging");
bar = new JProgressBar();
text[0] = new JTextField(20);
text[1] = new JTextField(10);
text[2] = new JTextField(20);
area = new JTextArea(10, 30);
scroll = new JScrollPane(area);
bag = new GridBagLayout();
c = new GridBagConstraints();
this.setLayout(bag);
c.weightx = 1;
c.weighty = 1;
setCons(0, 0, 1, 1);
this.add(label[0], c);
setCons(1, 0, 3, 1);
this.add(text[0], c);
setCons(4, 0, 1, 1);
this.add(button[0], c);
setCons(0, 1, 1, 1);
this.add(label[1], c);
setCons(1, 2, 5, 3);
this.add(scroll, c);
// setCons(1,2,5,3);
// this.add(area,c);
setCons(0, 7, 1, 1);
this.add(label[2], c);
setCons(1, 7, 1, 1);
this.add(text[1], c);
setCons(1, 8, 1, 1);
this.add(button[1], c);
setCons(2, 8, 1, 1);
this.add(button[2], c);
setCons(0, 9, 1, 1);
this.add(label[3], c);
setCons(1, 9, 3, 1);
this.add(text[2], c);
setCons(0, 10, 1, 1);
this.add(button[3], c);
setCons(1, 10, 4, 1);
this.add(bar, c);
}
public void initMergePanel() {
text[0].setEditable(false);
text[2].setEditable(false);
area.setEditable(false);
// 分别设置水平和垂直滚动条自动出现
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
mergeFileList = new ArrayList<String>();
/* JProgressBar */
bar.setOrientation(JProgressBar.HORIZONTAL);
bar.setMinimum(0);
bar.setMaximum(100);
bar.setValue(0);
bar.setStringPainted(true);
bar.addChangeListener(this);
bar.setPreferredSize(new Dimension(300, 20));
bar.setBorderPainted(true);
bar.setBackground(Color.white);
}
public void addListener() {
for (int i = 0; i < 4; i++)
button[i].addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button[0]) {
JFileChooser fc = new JFileChooser("d:\\");
fc.setMultiSelectionEnabled(true);
int val = fc.showOpenDialog(null);
if (0 == val) {
fileList = fc.getSelectedFiles();
text[0].setText(String.valueOf(fileList[0].getName()));
Arrays.sort(fileList);
for (int i = 0; i < fileList.length; i++) {
mergeFileList.add(fileList[i]);
}
doGiveMsg();
String a[] = fileList[0].getName().split("_");
String tFile = a[0];
targetFile = new File(
fileList[0].getParentFile().getPath(), tFile);
text[2].setText(tFile);
}
} else if (e.getSource() == button[1]) {
String temp = text[1].getText();
if (temp.equals("")) {
JOptionPane.showMessageDialog(null, "没有选中文件!");
} else {
int index = Integer.parseInt(text[1].getText());
mergeFileList.remove(index);
doGiveMsg();
}
} else if (e.getSource() == button[2]) {
if (area.getText().equals("")) {
JOptionPane.showMessageDialog(null, "没有文件!");
} else {
mergeFileList.clear();
doGiveMsg();
}
} else if (e.getSource() == button[3]) {
if (!area.getText().equals("")) {
FileMerge merge = new FileMerge();
merge.run();
} else {
JOptionPane.showMessageDialog(null, "没有可以合并的文件!");
}
}
}
public void doGiveMsg() {
String tempArea = "";
for (int i = 0; i < mergeFileList.size(); i++) {
tempArea += (i + 1) + " " + mergeFileList.get(i) + "\n";
}
area.setText(tempArea);
}
@Override
public void stateChanged(ChangeEvent arg0) {
// TODO Auto-generated method stub
}
/* MergePanel 中的子类FileMerge用来处理merge面板 */
class FileMerge extends Thread {
public void run() {
int temp = 0;
try {
RandomAccessFile out = new RandomAccessFile(targetFile,
"rw");
for (int i = 0; i < fileList.length; i++) {
System.out.println("Processing..." + i);
RandomAccessFile in = new RandomAccessFile(fileList[i],
"r");
int len = (int) fileList[i].length();
byte bytes[] = new byte[len];
in.read(bytes);
out.write(bytes);
in.close();
int progress = 100 / fileList.length * (i + 1);
bar.setValue(progress);
}
out.close();
bar.setValue(100);
} catch (Exception e) {
System.out.println("File Exception!");
}
}
}
}
}