java - 为什么在更改文本框中的内容时不会更改滚动条的大小?
问题描述
英语不是我的母语,如果有语法错误,请原谅。这是一个文本编辑器程序。
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;
}
}
从上图中可以看出,改变 textArea 的内容并不会改变滚动条的大小。我们如何使滚动条随着 scrollableTextArea 内内容的变化而调整?如何修复错误?
提前致谢。
解决方案
推荐阅读
- python - 如何访问在 `with` 语句中创建的变量
- typescript - 打字稿中所有对象文字类型的子类型?
- reactjs - 传递给子组件的道具未定义,但 console.log 显示道具的值
- gradle - 使用 Gradle 和 JavaFX 创建一个使用自定义 JVM 参数的可运行 jar
- oop - ByRef 或 ByVal 用于传递参数,当参数是对象时。伪代码
- javascript - 使用Javascript计算文本宽度而不进行四舍五入
- excel - 格式功能已更改且无法工作
- node.js - 带有 express 和 nodejs 的空正文
- scala - 在 Spark 应用程序中使用 log4j 时如何忽略导入的库日志
- python - 如何根据 Python Dataframe 中不同行中 2 个变量的变化添加二进制状态变量?