java实现极简单的 TXT小说阅读器(第三版)

第三版在第二版的基础上增加了

保存 以及另存为的选项。

并且完善了简单的菜单栏。

SaveAndSaveAs类:

public class SaveAndSaveAs {	
	public SaveAndSaveAs(JTextArea textArea,String filePath){
		BufferedWriter bw = null;
        try {
            OutputStream os = new FileOutputStream(filePath);
            bw = new BufferedWriter(new OutputStreamWriter(os));
            for (String value : textArea.getText().split("\n")) {
                bw.write(value);
                bw.newLine();//换行
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
	}
}


WordStyleSet类:

public class WordStyleSet {
	public static void StyleSet(JTextArea jtextarea,String wordName,int wordStyle,int wordSize){
		Font font = new Font(wordName,wordStyle,wordSize);
		jtextarea.setFont(font);
	}	
}


Display_txt类:

public class Display_txt extends JFrame {
	
	JFrame jframe = new JFrame();
	JTextArea content,wordSizeSetArea,wordStyleSetArea,wordNameSetArea;
	JMenuBar menubar = new JMenuBar();
	JMenu menu_file = new JMenu("文件");
	JMenu menu_about = new JMenu("关于");
	JMenuItem menuItem_open = new JMenuItem("打开");
	JMenuItem menuItem_save = new JMenuItem("保存");
	JMenuItem menuItem_saveAs = new JMenuItem("另存为");
	JMenuItem menuItem_exit = new JMenuItem("退出");
	JMenuItem menuItem_about = new JMenuItem("软件说明");
	
	boolean flag = true;
	String str_filePath = null;
	
	
	public Display_txt(){
		//文字输入框(文字显示窗口)
		content = new JTextArea(10,50);
		content.setAutoscrolls(true);
		JScrollPane contentScroll = new JScrollPane(content);
		content.setBorder(BorderFactory.createBevelBorder(1));
		JPanel upper = new JPanel(new BorderLayout());
		upper.add(contentScroll);
		//字体大小设置窗口
		wordSizeSetArea = new JTextArea(1,3);
		wordSizeSetArea.setBorder(BorderFactory.createBevelBorder(1));
		wordSizeSetArea.setText("12");
		//字体样式设置窗口(加粗等)
		wordStyleSetArea = new JTextArea(1,3);
		wordStyleSetArea.setBorder(BorderFactory.createBevelBorder(1));
		wordStyleSetArea.setText("0");
		//字体名字设置窗口(宋体等)
		wordNameSetArea = new JTextArea(1,3);
		wordNameSetArea.setBorder(BorderFactory.createBevelBorder(1));
		wordNameSetArea.setText("宋体");
		//(菜单栏)文件——打开
		menuItem_open.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					JFileChooser jfc = new JFileChooser();
					if(jfc.showOpenDialog(jframe)==JFileChooser.APPROVE_OPTION ){
						str_filePath = jfc.getSelectedFile().getAbsolutePath();
						BufferedReader bufferedReader = new BufferedReader(new FileReader(str_filePath));
						String str_line;
						while((str_line=bufferedReader.readLine())!=null){
							if(flag){
								content.setText(str_line);
								flag = false;
							}
							else{
								content.setText(content.getText()+"\n"+str_line);
							}
						}
						bufferedReader.close();
					}
				}catch(FileNotFoundException e1){
					e1.printStackTrace();
				}catch(IOException e2){
					e2.printStackTrace();
				}
			}
		});
		//按钮
		JButton wordSizeSet = new JButton("设置字体大小");
		wordSizeSet.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					WordStyleSet.StyleSet(content,wordNameSetArea.getText(),Integer.parseInt(wordStyleSetArea.getText()),Integer.parseInt(wordSizeSetArea.getText()));
				}catch(Exception e0){
					e0.printStackTrace();				
				}
			}
		});
		//按钮
		JButton wordStyleSet = new JButton("设置字体样式");
		wordStyleSet.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					WordStyleSet.StyleSet(content,wordNameSetArea.getText(),Integer.parseInt(wordStyleSetArea.getText()),Integer.parseInt(wordSizeSetArea.getText()));
				}catch(Exception e0){
					e0.printStackTrace();				
				}
			}
		});
		//按钮
		JButton wordNameSet = new JButton("设置字体名字");
		wordNameSet.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					WordStyleSet.StyleSet(content,wordNameSetArea.getText(),Integer.parseInt(wordStyleSetArea.getText()),Integer.parseInt(wordSizeSetArea.getText()));
				}catch(Exception e0){
					e0.printStackTrace();				
				}
			}
		});
		//(菜单栏)文件——另存为
		menuItem_saveAs.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				JFileChooser jfc = new JFileChooser();
				if(jfc.showSaveDialog(jframe)==JFileChooser.APPROVE_OPTION )
					new SaveAndSaveAs(content,jfc.getSelectedFile().getPath());
			}
		});
		//(菜单栏)文件——保存
		menuItem_save.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				new SaveAndSaveAs(content,str_filePath);
			}
		});
		//(菜单栏)文件——退出
		menuItem_exit.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.exit(0);
			}	
		});
		//(菜单栏)关于——软件说明
		menuItem_about.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				JOptionPane.showMessageDialog(jframe, "版本1.0    作者:snnile","软件说明", JOptionPane.INFORMATION_MESSAGE); 
			}
		});
				
		menu_file.add(menuItem_open);
		menu_file.add(menuItem_save);
		menu_file.add(menuItem_saveAs);
		menu_file.add(menuItem_exit);
		menubar.add(menu_file);
		menu_about.add(menuItem_about);
		menubar.add(menu_about);
		JPanel buttonp = new JPanel();
		buttonp.add(wordSizeSet);
		buttonp.add(wordSizeSetArea);
		buttonp.add(wordStyleSet);
		buttonp.add(wordStyleSetArea);
		buttonp.add(wordNameSet);
		buttonp.add(wordNameSetArea);
		JPanel all = new JPanel(new GridLayout(1,1));
		all.add(upper);
		jframe.add(menubar,BorderLayout.NORTH);
		jframe.add(buttonp,BorderLayout.SOUTH);
		jframe.add(all,BorderLayout.CENTER);
		jframe.pack();
		Toolkit tool = Toolkit.getDefaultToolkit();
		Dimension screen = tool.getScreenSize();
		jframe.setLocation(screen.width/2-jframe.getWidth()/2,screen.height/2-jframe.getHeight()/2);
		jframe.setTitle("TXT小说阅读器");
		jframe.setVisible(true);
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public static void main(String args[]){
		Display_txt display_demo = new Display_txt();
	}

}

图一:



图二:


图三:


图四:


图五:



  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package cn.huang.my_txtreader; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.text.DecimalFormat; import java.util.Vector; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; public class BookPageFactory { //把字体绘制到界面上 private File book_file = null; private MappedByteBuffer m_mbBuf = null;//MappedByteBuffer 将文件直接映射到内存 private int m_mbBufLen = 0; private int m_mbBufBegin = 0; private int m_mbBufEnd = 0; private String m_strCharsetName = "gbk";//文本格式 private Bitmap m_book_bg = null;//文本图像 private int mWidth; private int mHeight; private Vector<String> m_lines = new Vector<String>(); //用于一行一行显示 private int m_fontSize = 24; private int m_textColor = Color.BLACK;//字体颜色 private int m_backColor = 0xffff9e85; // 背景颜色 private int marginWidth = 15; // 左右与边缘的距离 private int marginHeight = 20; // 上下与边缘的距离 private int mLineCount; // 每页可以显示的行数 private float mVisibleHeight; // 绘制内容的宽 private float mVisibleWidth; // 绘制内容的宽 private boolean m_isfirstPage,m_islastPage; // private int m_nLineSpaceing = 5; private Paint mPaint; //设置阅读界面,包括字体,显示多少行 public BookPageFactory(int w, int h) { // TODO Auto-generated constructor stub mWidth = w; mHeight = h;//获得宽和高 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setTextAlign(Align.LEFT);//设置文本对齐方式 mPaint.setTextSize(m_fontSize);//设置字体大小 mPaint.setColor(m_textColor);//设置颜色 mVisibleWidth = mWidth - marginWidth * 2; mVisibleHeight = mHeight - marginHeight * 2;//绘制的内容宽和高 mLineCount = (int) (mVisibleHeight / m_fontSize); // 可显示的行数 } //获得文件,并映射到内存 public void openbook(String strFilePath) throws IOException { book_file = new File(strFilePath); long lLen = book_file.length();//文本长度 m_mbBufLen = (int) lLen;//缓存的长度 m_mbBuf = new RandomAccessFile(book_file, "r").getChannel().map( FileChannel.MapMode.READ_ONLY, 0, lLen); //RandomAccessFile是用来访问那些保存数据记录的文件的 } //读一段 protected byte[] readParagraphBack(int nFromPos) { int nEnd = nFromPos;//字符缓存开始的位置 int i; byte b0, b1; if (m_strCharsetName.equals("UTF-16LE")) { i = nEnd - 2;//? while (i > 0) { b0 = m_mbBuf.get(i); b1 = m_mbBuf.get(i + 1); if (b0 == 0x0a && b1 == 0x00 && i != nEnd - 2) { i += 2; break; } i--; } } else if (m_strCharsetName.equals("UTF-16BE")) { i = nEnd - 2; while (i > 0) { b0 = m_mbBuf.get(i);//返回指定索引 b1 = m_mbBuf.get(i + 1); if (b0 == 0x00 && b1 == 0x0a && i != nEnd - 2) { i += 2; break; }//过段时 i--; } } else { i = nEnd - 1;//? while (i > 0) { b0 = m_mbBuf.get(i); if (b0 == 0x0a && i != nEnd - 1) { i++; break; }//过段时 i--; } } if (i < 0) i = 0; //i是过段的索引位置 int nParaSize = nEnd - i; int j; byte[] buf = new byte[nParaSize]; for (j = 0; j < nParaSize; j++) { buf[j] = m_mbBuf.get(i + j); } return buf; } // 读取上一段落 protected byte[] readParagraphForward(int nFromPos) { int nStart = nFromPos;//字符缓存开始的位置 int i = nStart; byte b0, b1; // 根据编码格式判断换行 if (m_strCharsetName.equals("UTF-16LE")) { while (i < m_mbBufLen - 1) { b0 = m_mbBuf.get(i++); b1 = m_mbBuf.get(i++); if (b0 == 0x0a && b1 == 0x00) { break; } } } else if (m_strCharsetName.equals("UTF-16BE")) { while (i < m_mbBufLen - 1) { b0 = m_mbBuf.get(i++); b1 = m_mbBuf.get(i++); if (b0 == 0x00 && b1 == 0x0a) { break; } } } else { while (i < m_mbBufLen) { b0 = m_mbBuf.get(i++); if (b0 == 0x0a) { break; } } } //这使i在换行的索引位置 int nParaSize = i - nStart; byte[] buf = new byte[nParaSize]; for (i = 0; i < nParaSize; i++) { buf[i] = m_mbBuf.get(nFromPos + i); }//把读到的段输入字节流中 return buf; } protected Vector<String> pageDown() { String strParagraph = ""; Vector<String> lines = new Vector<String>(); while (lines.size() < mLineCount && m_mbBufEnd < m_mbBufLen) { //不能大于给定的最多行数 byte[] paraBuf = readParagraphForward(m_mbBufEnd); // 读取一个段落 m_mbBufEnd += paraBuf.length; //减去读到的长度,作为下一个结束的地步 try { strParagraph = new String(paraBuf, m_strCharsetName); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } String strReturn = ""; if (strParagraph.indexOf("\r\n") != -1) { //"\r\n"在字符串中则,下同 strReturn = "\r\n"; strParagraph = strParagraph.replaceAll("\r\n", ""); } else if (strParagraph.indexOf("\n") != -1) { strReturn = "\n"; strParagraph = strParagraph.replaceAll("\n", ""); } if (strParagraph.length() == 0) { lines.add(strParagraph); } while (strParagraph.length() > 0) { int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); //返回刚好要超过规定长度mVisibleWidth的值 lines.add(strParagraph.substring(0, nSize)); strParagraph = strParagraph.substring(nSize); if (lines.size() >= mLineCount) {//超过规定的行数 break; } } if (strParagraph.length() != 0) { try { m_mbBufEnd -= (strParagraph + strReturn) .getBytes(m_strCharsetName).length; //即返回字符串在GBK、UTF-8和ISO8859-1编码下的byte数组表示 //目的在于把m_mbBufEnd改成指向下一行 } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return lines; } //设置文本显示 //预防文本超过界面规定的范围 protected void pageUp() { if (m_mbBufBegin < 0) m_mbBufBegin = 0; Vector<String> lines = new Vector<String>(); String strParagraph = ""; while (lines.size() < mLineCount && m_mbBufBegin > 0) { //不能大于给定的最多行数 Vector<String> paraLines = new Vector<String>(); byte[] paraBuf = readParagraphBack(m_mbBufBegin); //读到一段 //从头开始读 m_mbBufBegin -= paraBuf.length; //减去读到的长度,作为下一个开始要读的标志 try { strParagraph = new String(paraBuf, m_strCharsetName); //第一个参数读到的字符串,第二个参数是文本格式 } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } strParagraph = strParagraph.replaceAll("\r\n", ""); //用第二个参数的字符串替换第一个 strParagraph = strParagraph.replaceAll("\n", ""); //替换掉任何过行的记录 if (strParagraph.length() == 0) {//为空,没有字符串时 paraLines.add(strParagraph); } while (strParagraph.length() > 0) { int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); //测量第一个字符串,与第三个参数即宽度相比 paraLines.add(strParagraph.substring(0, nSize)); //获得0到nSize的字符串 strParagraph = strParagraph.substring(nSize); //字符串变成从nSize开始 }//在于把字符串变成不会超过规定长度mVisibleWidth的字符串 lines.addAll(0, paraLines);//加入所有Vector字符串列 } while (lines.size() > mLineCount) {//超过规定行数时 try { m_mbBufBegin += lines.get(0).getBytes(m_strCharsetName).length; //.get()表示返回指定位置的元素 //String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组 //即返回字符串在GBK、UTF-8和ISO8859-1编码下的byte数组表示 //目的在于把m_mbBufBegin改成指向下一行 lines.remove(0); //删除指定位置的元素 } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } m_mbBufEnd = m_mbBufBegin; return; } protected void prePage() throws IOException { if (m_mbBufBegin <= 0) { m_mbBufBegin = 0; m_isfirstPage=true; return; }else m_isfirstPage=false; m_lines.clear(); //删除所有元素 pageUp(); m_lines = pageDown(); //把收集到的文本放到m_lines中 } public void nextPage() throws IOException { if (m_mbBufEnd >= m_mbBufLen) { m_islastPage=true; return; }else m_islastPage=false; m_lines.clear(); m_mbBufBegin = m_mbBufEnd; m_lines = pageDown(); } public void onDraw(Canvas c) { if (m_lines.size() == 0) m_lines = pageDown(); //现在m_lines的格式是按照 //界面阅读规定的,即有多宽的,有多行 if (m_lines.size() > 0) { if (m_book_bg == null) c.drawColor(m_backColor);//设置背景颜色 else c.drawBitmap(m_book_bg, 0, 0, null); int y = marginHeight; for (String strLine : m_lines) { y += m_fontSize; c.drawText(strLine, marginWidth, y, mPaint); //给界面的每一行绘制 } } float fPercent = (float) (m_mbBufBegin * 1.0 / m_mbBufLen); DecimalFormat df = new DecimalFormat("#0.0");//用于格式化十进制数字 //即按照参数的格式输出 String strPercent = df.format(fPercent * 100) + "%"; int nPercentWidth = (int) mPaint.measureText("999.9%") + 1; //返回字符串的宽度 c.drawText(strPercent, mWidth - nPercentWidth, mHeight - 5, mPaint); } //绘制图像 public void setBgBitmap(Bitmap BG) { m_book_bg = BG; } //返回第一页 public boolean isfirstPage() { return m_isfirstPage; } //返回最后一页 public boolean islastPage() { return m_islastPage; } }
Java小说阅读器的设计和代码较为复杂,需要涉及到图形界面、文件读取和解析、数据存储等多个方面。下面是一个简单的示例,供参考: 设计: 1. 主界面:包括小说列表、搜索框、分类、收藏等功能。 2. 阅读界面:显示小说内容、目录、翻页等功能。 3. 设置界面:包括字体、字号、背景颜色等设置。 代码: 1. 主界面实现: ```java public class MainFrame extends JFrame { private JPanel contentPane; private JTextField searchField; private JComboBox<String> categoryComboBox; private JList<String> novelList; private JButton collectButton; public MainFrame() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 800, 600); setTitle("小说阅读器"); contentPane = new JPanel(); setContentPane(contentPane); contentPane.setLayout(null); searchField = new JTextField(); searchField.setBounds(10, 10, 200, 30); contentPane.add(searchField); categoryComboBox = new JComboBox<String>(); categoryComboBox.setBounds(220, 10, 100, 30); contentPane.add(categoryComboBox); novelList = new JList<String>(); novelList.setBounds(10, 50, 310, 500); contentPane.add(novelList); collectButton = new JButton("收藏"); collectButton.setBounds(330, 10, 80, 30); contentPane.add(collectButton); } } ``` 2. 阅读界面实现: ```java public class ReaderFrame extends JFrame { private JPanel contentPane; private JTextArea contentArea; private JList<String> chapterList; private JButton previousButton; private JButton nextButton; public ReaderFrame() { setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setBounds(100, 100, 800, 600); setTitle("小说阅读器"); contentPane = new JPanel(); setContentPane(contentPane); contentPane.setLayout(null); contentArea = new JTextArea(); contentArea.setBounds(10, 50, 770, 500); contentPane.add(contentArea); chapterList = new JList<String>(); chapterList.setBounds(10, 50, 150, 500); contentPane.add(chapterList); previousButton = new JButton("上一页"); previousButton.setBounds(10, 10, 80, 30); contentPane.add(previousButton); nextButton = new JButton("下一页"); nextButton.setBounds(100, 10, 80, 30); contentPane.add(nextButton); } } ``` 3. 设置界面实现: ```java public class SettingFrame extends JFrame { private JPanel contentPane; private JComboBox<String> fontComboBox; private JComboBox<Integer> fontSizeComboBox; private JComboBox<String> colorComboBox; private JButton confirmButton; private JButton cancelButton; public SettingFrame() { setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setBounds(100, 100, 400, 300); setTitle("设置"); contentPane = new JPanel(); setContentPane(contentPane); contentPane.setLayout(null); fontComboBox = new JComboBox<String>(); fontComboBox.setBounds(10, 10, 100, 30); contentPane.add(fontComboBox); fontSizeComboBox = new JComboBox<Integer>(); fontSizeComboBox.setBounds(120, 10, 60, 30); contentPane.add(fontSizeComboBox); colorComboBox = new JComboBox<String>(); colorComboBox.setBounds(190, 10, 100, 30); contentPane.add(colorComboBox); confirmButton = new JButton("确定"); confirmButton.setBounds(100, 220, 80, 30); contentPane.add(confirmButton); cancelButton = new JButton("取消"); cancelButton.setBounds(200, 220, 80, 30); contentPane.add(cancelButton); } } ``` 以上代码只是一个简单的示例,实现的功能较为简单,需要根据实际需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值