Engli sh не мой родной язык, извините, если есть грамматические ошибки. Это программа для текстового редактора.
Класс Rule используется в качестве заголовка строки для ScrollableTextArea. ScrollableTextArea расширяет JTextArea и реализует Scrollable, он также реализуетMouseMotionListener, так что пользователь может прокручивать (перемещать ручку), нажимая на дорожку.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
/**
*Classes required
*Rule.java
*ScrollableTextArea
* @author Dev Parzival
*/
public class Note extends JPanel{
static int NUMBER_PANEL_WIDTH=50;
private ScrollableTextArea scrollableTextArea;
private Rule rowView;
private JScrollPane scroll;
public Note(Dimension size,File file) {
rowView=new Rule(SwingConstants.VERTICAL,getIncrement());
scrollableTextArea=new ScrollableTextArea(rowView.getIncrement());
boolean flag=fetchData(scrollableTextArea, file);
rowView.setPreferredHeight(scrollableTextArea.getHeight());
if(!flag)
return;
scroll=new JScrollPane(scrollableTextArea);
scroll.setPreferredSize(size);
scroll.setRowHeaderView(rowView);
scroll.setViewportBorder(BorderFactory.createLineBorder(Color.black));
add(scroll);
setSize(size);
setVisible(true);
}
private boolean fetchData(JTextArea text,File file){
FileReader scan;
BufferedReader br;
try{
scan=new FileReader(file);
String msg="";
br=new BufferedReader(scan);
try{
while(true){
String data=br.readLine();
if(data==null)
break;
msg+=data+"\n";
}
text.setText(msg);
}
catch(IOException ex){
JOptionPane.showMessageDialog(this,"Error Occured while reading "+file.getAbsolutePath()+".","Error",JOptionPane.INFORMATION_MESSAGE);
}
}
catch(FileNotFoundException ex){
JOptionPane.showMessageDialog(this,"Cannot found this path : "+file.getAbsoluteFile(),"Error",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
/*Here the unit is the height of the text inside the textArea*/
public int getIncrement(){
JTextArea ta=new JTextArea();
return ta.getFontMetrics(ta.getFont()).getHeight();
}
public static void createAndShowGUI(){
JFrame frame = new JFrame("ScrollDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
//Create and set up the content pane.
JComponent newContentPane = new Note(frame.getSize(),new File("C:\\Users\\DevParzival\\Documents\\pro.txt"));
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
//frame.pack();
frame.setVisible(true);
}
public static void main(String $[]){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}
class Rule extends JComponent {
public static int INCH;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int SIZE = 35;
public int orientation;
private int increment;
private int units;
public Rule(int o,int height) {
orientation = o;
INCH=height;
setIncrementAndUnits();
}
private void setIncrementAndUnits() {
increment = units=INCH;
}
public int getIncrement() {
return increment;
}
public void setPreferredHeight(int ph) {
setPreferredSize(new Dimension(SIZE, ph));
}
public void setPreferredWidth(int pw) {
setPreferredSize(new Dimension(pw, SIZE));
}
protected void paintComponent(Graphics g) {
Rectangle drawHere = g.getClipBounds();
System.out.println(drawHere);
// Fill clipping area with dirty brown/orange.
g.setColor(new Color(230, 163, 4));
g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
// Do the ruler labels in a small font that's black.
g.setFont(new Font("SansSerif", Font.PLAIN, 10));
g.setColor(Color.black);
// Some vars we need.
int end = 0;
int start = 0;
int tickLength = 0;
String text = null;
// Use clipping bounds to calculate first and last tick locations.
if (orientation == HORIZONTAL) {
start = (drawHere.x / increment) * increment;
end = (((drawHere.x + drawHere.width) / increment) + 1)
* increment;
} else {
start = (drawHere.y / increment) * increment;
end = (((drawHere.y + drawHere.height) / increment) + 1)
* increment;
}
// Make a special case of 0 to display the number
// within the rule and draw a units label.
// if (start == 0) {
// text = Integer.toString(0);
// tickLength = 10;
// if (orientation == HORIZONTAL) {
// g.drawLine(0, SIZE-1, 0, SIZE-tickLength-1);
// g.drawString(text, 2, 21);
// } else {
// g.drawLine(SIZE-1, 0, SIZE-tickLength-1, 0);
// g.drawString(text, 9, 10);
// }
// text = null;
// start = increment;
// }
// ticks and labels
for (int i = start; i < end; i += increment) {
if (i % units == 0) {
tickLength = 10;
text = Integer.toString(i/units);
} else {
tickLength = 7;
text = null;
}
if (tickLength != 0) {
if (orientation == HORIZONTAL) {
g.drawLine(i, SIZE-1, i, SIZE-tickLength-1);
if (text != null)
g.drawString(text, i-3, 21);
} else {
g.drawLine(SIZE-1, i, SIZE-tickLength-1, i);
if (text != null)
g.drawString(text, 9, i+3+increment/2);
}
}
}
}
}
class ScrollableTextArea extends JTextArea implements Scrollable,MouseMotionListener {
private int maxUnitIncrement = 1;
public ScrollableTextArea(int m) {
maxUnitIncrement = m;
//Let the user scroll by dragging to outside the window.
setAutoscrolls(true); //enable synthetic drag events
addMouseMotionListener(this); //handle mouse drags
}
//Methods required by the MouseMotionListener interface:
public void mouseMoved(MouseEvent e) { }
public void mouseDragged(MouseEvent e) {
//The user is dragging us, so scroll!
Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
scrollRectToVisible(r);
}
public Dimension getPreferredSize() {
return new Dimension(500,500);
}
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation,
int direction) {
//Get the current position.
int currentPosition = 0;
if (orientation == SwingConstants.HORIZONTAL) {
currentPosition = visibleRect.x;
} else {
currentPosition = visibleRect.y;
}
//Return the number of pixels between currentPosition
//and the nearest tick mark in the indicated direction.
if (direction < 0) {
int newPosition = currentPosition -
(currentPosition / maxUnitIncrement)
* maxUnitIncrement;
return (newPosition == 0) ? maxUnitIncrement : newPosition;
} else {
return ((currentPosition / maxUnitIncrement) + 1)
* maxUnitIncrement
- currentPosition;
}
}
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation,
int direction) {
if (orientation == SwingConstants.HORIZONTAL) {
return visibleRect.width - maxUnitIncrement;
} else {
return visibleRect.height - maxUnitIncrement;
}
}
public boolean getScrollableTracksViewportWidth() {
return false;
}
public boolean getScrollableTracksViewportHeight() {
return false;
}
public void setMaxUnitIncrement(int pixels) {
maxUnitIncrement = pixels;
}
}

Из приведенного выше pi c видно, что изменение содержимого textArea не приводит к изменению размера полос прокрутки. Как можно настроить полосу прокрутки при изменении содержимого внутри scrollableTextArea? Как исправить ошибку?
Заранее спасибо.