我学到最多的是布局,太厉害啦,这个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强多了。不过这个东西有个拿捏不好的地方,就是你的实际大小和网格的分配要弄好,不然就挤成一坨了。
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读,写文件,按字节。
实际操作可以参考下面的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!"); } } } } }