//TextBean.java package net.sxif.textpane; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.io.IOException; import java.io.InputStream; import java.io.Writer; import javax.swing.Icon; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.border.LineBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.HyperlinkListener; import javax.swing.text.Document; public class TextBean extends JPanel{ private static final long serialVersionUID = 1L; public MyJTextPane JTP=null; //自定义JTextPane public JPanel left=null; public JScrollPane Jright=null; //滚动的面板 public MyLabel label=null; //自定义标签 public MyLabel temp=null; public static int count=1; //行号计数器 public static int line=0; //换行个数 public My1DocumentListener mdl=null; public TextBean(int tw,int th) { Jright=new JScrollPane(); JTP=new MyJTextPane(); left=new JPanel(); left.setLayout(null); label=new MyLabel(Integer.toString(count)); label.setBounds(5,4,20,20); left.add(label); left.setPreferredSize(new Dimension(25,th)); setLayout(new BorderLayout()); Jright.setViewportView(JTP); Jright.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); Jright.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); mdl=new My1DocumentListener(); Jright.getVerticalScrollBar().addAdjustmentListener(new MyAdjustmentListener()); Jright.setPreferredSize(new Dimension(tw,th)); Jright.setBorder(null); add(left,BorderLayout.WEST);add(Jright,BorderLayout.CENTER); addTextDocumentListener(); this.addComponentListener(new MyComponentListener()); } //添加文档监听器 public void addTextDocumentListener() { JTP.getDocument().addDocumentListener(mdl); } //移除文档监听器 public void removeTextDocumentListener() { JTP.getDocument().removeDocumentListener(mdl); } //添加行号 public void addLabel(int num) { temp=label; label=new MyLabel(Integer.toString(num)); label.setUpLabel(temp); left.add(label); label.setBounds(5,5+(num-1)*18,20,20); if(label.getY()+label.getHeight()>left.getHeight()) { left.setBounds(left.getX(), left.getY(), left.getWidth(), left.getHeight()+18); } if(left.getHeight()>Jright.getHeight())left.setBounds(left.getX(), left.getY()-18, left.getWidth(), left.getHeight()); } //添加行号 public void addLabel() { addLabel(++count); } //移除行号 public void removeLabel() { if(label!=null&&count>1) { temp=label.getUpLabel(); left.remove(label); count--; left.repaint(); label=temp; } if(left.getHeight()>Jright.getHeight())left.setBounds(left.getX(), left.getY()+18, left.getWidth(), left.getHeight()-18); if(count==1)left.setBounds(0, 0, 25, left.getHeight()); } //组件大小调整事件监听器 class MyComponentListener implements ComponentListener { @Override public void componentHidden(ComponentEvent e) { // TODO Auto-generated method stub } @Override public void componentMoved(ComponentEvent e) { // TODO Auto-generated method stub } @Override public void componentResized(ComponentEvent e) { left.removeAll(); for(int i=0;i<count;i++) { addLabel(i+1); } left.repaint(); } @Override public void componentShown(ComponentEvent e) { // TODO Auto-generated method stub } } //文档监听器 class My1DocumentListener implements DocumentListener { @Override public void changedUpdate(DocumentEvent e) { } @Override public void insertUpdate(DocumentEvent e) { String s=JTP.getText(); int total=getLine(s); while(total>line){addLabel(++count);line++;} } @Override public void removeUpdate(DocumentEvent e) { String s=JTP.getText(); int total=getLine(s); while(total<line){removeLabel();line--;} } } //解析一段文本中的换行个数 public int getLine(String s) { int totalLine=0; for(int i=0;i<s.length();i++) { if("/n".equals(s.substring(i, i+1)))totalLine++; } return totalLine; } //滚动条值改变事件监听器 class MyAdjustmentListener implements AdjustmentListener { @Override public void adjustmentValueChanged(AdjustmentEvent e) { int value=Jright.getVerticalScrollBar().getValue(); if(left.getHeight()>Jright.getHeight())left.setBounds(left.getX(), -value, left.getWidth(), left.getHeight()); } } public void setEditable(boolean editable) { JTP.setEditable(editable); } public Document getDocument() { return JTP.getDocument(); } public void setContentType(String type) { JTP.setContentType(type); } public void setText(String s) { JTP.setText(s); } public void read(InputStream in, Object desc) throws IOException { JTP.read(in, desc); } public void write(Writer out) throws IOException { JTP.write(out); } public void insertIcon(Icon g) { JTP.insertIcon(g); } public void setPage(String page) throws IOException { JTP.setPage(page); } public void addHyperlinkListener(HyperlinkListener h) { JTP.addHyperlinkListener(h); } public String getText() { return JTP.getText(); } } //MyLabel.java package net.sxif.textpane; import java.awt.Color; import java.awt.Font; import javax.swing.JLabel; public class MyLabel extends JLabel{ private static final long serialVersionUID = 1L; //上一个标签的引用 private MyLabel up=null; public MyLabel(String name) { super(name); this.setHorizontalAlignment(RIGHT); this.setFont(new Font("黑体",Font.PLAIN,12)); this.setForeground(Color.GRAY); } public MyLabel() { super(); } //设置上一个标签类的引用 public void setUpLabel(MyLabel label) { up=label; } //返回上一个标签类对象 public MyLabel getUpLabel() { return up; } } //MyJTextPane.java package net.sxif.textpane; import java.awt.Dimension; import javax.swing.JTextPane; public class MyJTextPane extends JTextPane{ private static final long serialVersionUID = 1L; public MyJTextPane() { super(); } public boolean getScrollableTracksViewportWidth() { return false; } public void setSize(Dimension d) { d.width = 100000; super.setSize(d); } }