Processing Java - 如何使滑块与文件内容成比例
Processing Java - how to make slider proportional to contents of file
我已将 Processing
的示例 Scrollbar/Slider
class 修改为垂直方向,并使滑块从顶部而不是中间开始。滑块长度与滚动条的比率是最大行数文本区域可以容纳的行数与最大行数的比率文件。滚动条在移动文本方面工作得很好,但这是一个小问题:
打开比较大的文件时,滚动条走得太远,当滚动条到尽头时,应该到文档的末尾。然而,滚动条走得更远,有额外的空行。文本框的定位可能是错的,因为我从我正在制作的文本编辑器中转移了代码。
我测试的文件是 554 行长度。
这是主文件:
Scrollbar bar;
String content = "";
float scrollbarRatio;
String absolutePath;
int line;
void setup()
{
// Background and size
background(0);
size(int(displayWidth * 4/5), int(displayHeight * 4/5));
// Resizable Window
if (frame != null) {
frame.setResizable(true);
}
// Scrollbar
bar = new Scrollbar(width-12, 55, 24, height - 79, 1);
// Input
selectInput("Select a file to process:", "openFile");
}
// Create set of line numbers given starting number and number of lines
void createLineNumbers(int startingNumber, int numberOfLines)
{
textAlign(LEFT);
String lineText = "";
textLeading(22);
for (int i = startingNumber; i <= startingNumber + numberOfLines; i++)
{
lineText += (str(i) + "\n");
}
text(lineText, width/5 + 12.5, 75);
textAlign(CENTER);
}
void draw()
{
String[] adjustedLines = content.split("\n");
int maxLines = floor((height - 80) / 22);
if (adjustedLines.length > maxLines)
{
scrollbarRatio = ((float) maxLines) / ((float) adjustedLines.length);
}
// Text Box
fill(80);
rect(width/5, 55, width*4/5, height-55);
textAlign(LEFT);
textLeading(22);
fill(225);
String[] contentLines = content.split("\n");
String display = "";
int lineDifference = bar.getLineDifference();
if (adjustedLines.length > maxLines)
{
for (int i = lineDifference; i < maxLines + lineDifference; i++)
{
if (i < adjustedLines.length)
{
display += adjustedLines[i];
display += "\n";
}
}
} else
{
display = content;
}
text(display, width/5+55, 75);
fill(240);
if (maxLines < adjustedLines.length)
{
createLineNumbers(lineDifference, lineDifference + maxLines);
} else if (maxLines >= adjustedLines.length)
{
createLineNumbers(1, adjustedLines.length);
}
bar.resizeScrollbar(width-12, 55, 24, height - 79);
bar.update(scrollbarRatio);
bar.display(scrollbarRatio);
}
// File - Open
void openFile(File selection)
{
if (selection != null)
{
try
{
// Read content of file
absolutePath = selection.getAbsolutePath();
String lines[] = loadStrings(absolutePath);
// Reset content and line numbers
content = "";
line = 0;
for (int i = 0; i < lines.length; i++) {
String lineContent = lines[i] + "\n";
content += lineContent;
line++;
}
}
catch (Exception exc)
{
println(exc.getMessage());
}
}
}
这里是 滚动条 class:
class Scrollbar
{
float swidth, sheight; // width and height of bar
float xpos, ypos; // x and y position of bar
float spos, newspos; // x position of slider
float sposMin, sposMax; // max and min values of slider
int loose; // how loose/heavy
boolean over; // is the mouse over the slider?
boolean locked; // is the mouse clicked over the slider
int lineDifference;
Scrollbar (int xp, int yp, int sw, int sh, int l) {
swidth = sw;
sheight = sh;
xpos = xp-swidth/2;
ypos = yp;
spos = ypos;
newspos = spos;
sposMin = ypos;
sposMax = ypos + sheight;
loose = l;
}
void resizeScrollbar(int xp, int yp, int sw, int sh)
{
xpos = xp - swidth/2;
ypos = yp;
swidth = sw;
sheight = sh;
}
void update(float ratio) {
if (over()) {
over = true;
} else {
over = false;
}
if (mousePressed && over) {
locked = true;
}
if (!mousePressed) {
locked = false;
}
if (locked) {
sposMax = ypos + sheight;
newspos = constrain(mouseY-swidth/2, sposMin, sposMax - sheight * ratio);
lineDifference = ceil((newspos - 55)/22 * (1/ratio));
if (abs(newspos - spos) > 1) {
spos = spos + (newspos-spos)/loose;
}
}
}
float constrain(float val, float minv, float maxv) {
return min(max(val, minv), maxv);
}
boolean over() {
if (mouseX > xpos && mouseX < xpos+swidth &&
mouseY > ypos && mouseY < ypos+sheight) {
return true;
} else {
return false;
}
}
void display(float ratio) {
fill(220);
rect(xpos, ypos, swidth, sheight);
if (over || locked) {
fill(80);
} else {
fill(190);
}
// Removes whitespace between slider and beginning of scrollbar
if (spos != 55 && floor(spos) == 55)
{
spos = 55;
}
// Removes whitespace between slider and end of scrollbar
if ((spos + sheight * ratio) != (sheight + ypos) && ceil(spos + sheight * ratio) == (sheight + ypos))
{
spos = sheight + ypos - (sheight * ratio);
}
rect(xpos, spos, swidth, sheight * ratio);
}
int getLineDifference()
{
return lineDifference;
}
}
首先检索滚动到页面底部时与开头的行差异,然后将其添加到可能出现的最大行数中存储在区域,减去文档的长度,我得到了必须从比率的分母中减去的额外数量
我已将 Processing
的示例 Scrollbar/Slider
class 修改为垂直方向,并使滑块从顶部而不是中间开始。滑块长度与滚动条的比率是最大行数文本区域可以容纳的行数与最大行数的比率文件。滚动条在移动文本方面工作得很好,但这是一个小问题:
打开比较大的文件时,滚动条走得太远,当滚动条到尽头时,应该到文档的末尾。然而,滚动条走得更远,有额外的空行。文本框的定位可能是错的,因为我从我正在制作的文本编辑器中转移了代码。
我测试的文件是 554 行长度。
这是主文件:
Scrollbar bar;
String content = "";
float scrollbarRatio;
String absolutePath;
int line;
void setup()
{
// Background and size
background(0);
size(int(displayWidth * 4/5), int(displayHeight * 4/5));
// Resizable Window
if (frame != null) {
frame.setResizable(true);
}
// Scrollbar
bar = new Scrollbar(width-12, 55, 24, height - 79, 1);
// Input
selectInput("Select a file to process:", "openFile");
}
// Create set of line numbers given starting number and number of lines
void createLineNumbers(int startingNumber, int numberOfLines)
{
textAlign(LEFT);
String lineText = "";
textLeading(22);
for (int i = startingNumber; i <= startingNumber + numberOfLines; i++)
{
lineText += (str(i) + "\n");
}
text(lineText, width/5 + 12.5, 75);
textAlign(CENTER);
}
void draw()
{
String[] adjustedLines = content.split("\n");
int maxLines = floor((height - 80) / 22);
if (adjustedLines.length > maxLines)
{
scrollbarRatio = ((float) maxLines) / ((float) adjustedLines.length);
}
// Text Box
fill(80);
rect(width/5, 55, width*4/5, height-55);
textAlign(LEFT);
textLeading(22);
fill(225);
String[] contentLines = content.split("\n");
String display = "";
int lineDifference = bar.getLineDifference();
if (adjustedLines.length > maxLines)
{
for (int i = lineDifference; i < maxLines + lineDifference; i++)
{
if (i < adjustedLines.length)
{
display += adjustedLines[i];
display += "\n";
}
}
} else
{
display = content;
}
text(display, width/5+55, 75);
fill(240);
if (maxLines < adjustedLines.length)
{
createLineNumbers(lineDifference, lineDifference + maxLines);
} else if (maxLines >= adjustedLines.length)
{
createLineNumbers(1, adjustedLines.length);
}
bar.resizeScrollbar(width-12, 55, 24, height - 79);
bar.update(scrollbarRatio);
bar.display(scrollbarRatio);
}
// File - Open
void openFile(File selection)
{
if (selection != null)
{
try
{
// Read content of file
absolutePath = selection.getAbsolutePath();
String lines[] = loadStrings(absolutePath);
// Reset content and line numbers
content = "";
line = 0;
for (int i = 0; i < lines.length; i++) {
String lineContent = lines[i] + "\n";
content += lineContent;
line++;
}
}
catch (Exception exc)
{
println(exc.getMessage());
}
}
}
这里是 滚动条 class:
class Scrollbar
{
float swidth, sheight; // width and height of bar
float xpos, ypos; // x and y position of bar
float spos, newspos; // x position of slider
float sposMin, sposMax; // max and min values of slider
int loose; // how loose/heavy
boolean over; // is the mouse over the slider?
boolean locked; // is the mouse clicked over the slider
int lineDifference;
Scrollbar (int xp, int yp, int sw, int sh, int l) {
swidth = sw;
sheight = sh;
xpos = xp-swidth/2;
ypos = yp;
spos = ypos;
newspos = spos;
sposMin = ypos;
sposMax = ypos + sheight;
loose = l;
}
void resizeScrollbar(int xp, int yp, int sw, int sh)
{
xpos = xp - swidth/2;
ypos = yp;
swidth = sw;
sheight = sh;
}
void update(float ratio) {
if (over()) {
over = true;
} else {
over = false;
}
if (mousePressed && over) {
locked = true;
}
if (!mousePressed) {
locked = false;
}
if (locked) {
sposMax = ypos + sheight;
newspos = constrain(mouseY-swidth/2, sposMin, sposMax - sheight * ratio);
lineDifference = ceil((newspos - 55)/22 * (1/ratio));
if (abs(newspos - spos) > 1) {
spos = spos + (newspos-spos)/loose;
}
}
}
float constrain(float val, float minv, float maxv) {
return min(max(val, minv), maxv);
}
boolean over() {
if (mouseX > xpos && mouseX < xpos+swidth &&
mouseY > ypos && mouseY < ypos+sheight) {
return true;
} else {
return false;
}
}
void display(float ratio) {
fill(220);
rect(xpos, ypos, swidth, sheight);
if (over || locked) {
fill(80);
} else {
fill(190);
}
// Removes whitespace between slider and beginning of scrollbar
if (spos != 55 && floor(spos) == 55)
{
spos = 55;
}
// Removes whitespace between slider and end of scrollbar
if ((spos + sheight * ratio) != (sheight + ypos) && ceil(spos + sheight * ratio) == (sheight + ypos))
{
spos = sheight + ypos - (sheight * ratio);
}
rect(xpos, spos, swidth, sheight * ratio);
}
int getLineDifference()
{
return lineDifference;
}
}
首先检索滚动到页面底部时与开头的行差异,然后将其添加到可能出现的最大行数中存储在区域,减去文档的长度,我得到了必须从比率的分母中减去的额外数量