我可以使用按键组合在 JScrollPane 内的 JTextArea 中向上或向下滚动吗?
Can I use a keypress combination to scroll up or down in a JTextArea inside a JScrollPane?
如果文本区域有焦点,当然 PgUp 和 PgDn 键可以正常工作,但我希望滚动它使用键绑定向上或向下,将焦点留在原处,而不是将其移动到文本区域并返回。
所以我将 VK_PAGEDOWN 和 CTRL_DOWN_MASK 映射到菜单项,希望当用户按下 Ctrl+PgDn 时 程序会将文本区域滚动 20 行。
但是当 txaOutput.getLineCount()
returns 文本区域中的行数时,我找不到将插入符号 line 设置为该数字减去的方法20. txaOutput.setCaretPosition(int i)
将插入符号设置为字节数 i
。
我所做的是伪造的,但它确实滚动(Page Up 除了 - scrollBytes
之外是相同的):
PageDown = new KeyBoundMenuItem("PAGEDOWN", VK_PAGE_DOWN, CTRL_DOWN_MASK)
{
@Override
public void action(ActionEvent e) {
scrollBytes = 20 * totalBytesInTextArea / txaOutput.getLineCount();
try{
txaOutput.setCaretPosition(txaOutput.getCaretPosition() + scrollBytes);
}catch(Exception ex){}
}
};
有没有办法将插入符设置为 JScrollPane
中的 JTextArea
中的特定行号?
编辑
文本区域包含每行 3 到 11 个字母的单词。
编辑 2
这是 action
而不是 actionPerformed
的原因:
import java.awt.event.ActionEvent;
import javax.swing.*;
import static javax.swing.KeyStroke.getKeyStroke;
public abstract class KeyBoundMenuItem extends JMenuItem{
public abstract void action(ActionEvent e);
public KeyBoundMenuItem(String actionMapKey, int key, int mask)
{
Action myAction = new AbstractAction()
{
@Override public void actionPerformed(ActionEvent e)
{
action(e);
}
};
setAction(myAction);
getInputMap(WHEN_IN_FOCUSED_WINDOW)
.put(getKeyStroke(key, mask),actionMapKey);
getActionMap().put( actionMapKey, myAction);
}
}
编辑 3
可以用这个代替 KeyBoundMenuItem
:
public static void shortcut(JMenuItem item, int mnem, int mods, int key)
{
item.setMnemonic(mnem);
item.setAccelerator(getKeyStroke(key,mods));
}
但是已经为类似的 class KeyBoundButton
编写了代码。当天晚些时候轻松更改。
编辑 4
以下是需要向上或向下滚动的文本类型:
Is there a way to set the caret to a particular line number
查看 Text Utilities class。方法如:
getLineAtCaret()
和
gotoStartOfLine(...)
应该允许你做你想做的事。那就是向下滚动你可以这样做:
int currentLine = RXTextUtilities.getLineAtCaret(textArea);
RXTextUtilities.gotoStartOfLine(textArea, currentLine + 10);
感谢@camickr,这是有效的(PAGEUP 的代码是相同的,除了 -
而不是 +
:
PageDown = new KeyBoundMenuItem("PAGEDOWN", VK_PAGE_DOWN, CTRL_DOWN_MASK)
{
@Override
public void action(ActionEvent e)
{
int currentLine = RXTextUtilities.getLineAtCaret(txaOutput);
RXTextUtilities.gotoStartOfLine(
txaOutput,
currentLine + RXTextUtilities.maxLinesVisibleInWindow(txaOutput));
}
};
我可能应该修改此代码以反映他的有效批评,即我不必制作 abstract class
来完成键绑定,但它并没有坏。 (我可能有一天会抽出时间...)
我什至想出了(通过研究他的 Text Utilities)如何在不使用常量的情况下滚动 window(28,参见评论):
public static int maxLinesVisibleInWindow(JTextComponent component)
{
Container container = getAncestorOfClass(JViewport.class, component);
if (container == null) return 0;
JViewport viewport = (JViewport)container;
int extentHeight = viewport.getExtentSize().height;
FontMetrics fm = component.getFontMetrics(component.getFont());
int characterHeight = fm.getHeight();
return (int)extentHeight/characterHeight - 1;
}
如果文本区域有焦点,当然 PgUp 和 PgDn 键可以正常工作,但我希望滚动它使用键绑定向上或向下,将焦点留在原处,而不是将其移动到文本区域并返回。
所以我将 VK_PAGEDOWN 和 CTRL_DOWN_MASK 映射到菜单项,希望当用户按下 Ctrl+PgDn 时 程序会将文本区域滚动 20 行。
但是当 txaOutput.getLineCount()
returns 文本区域中的行数时,我找不到将插入符号 line 设置为该数字减去的方法20. txaOutput.setCaretPosition(int i)
将插入符号设置为字节数 i
。
我所做的是伪造的,但它确实滚动(Page Up 除了 - scrollBytes
之外是相同的):
PageDown = new KeyBoundMenuItem("PAGEDOWN", VK_PAGE_DOWN, CTRL_DOWN_MASK)
{
@Override
public void action(ActionEvent e) {
scrollBytes = 20 * totalBytesInTextArea / txaOutput.getLineCount();
try{
txaOutput.setCaretPosition(txaOutput.getCaretPosition() + scrollBytes);
}catch(Exception ex){}
}
};
有没有办法将插入符设置为 JScrollPane
中的 JTextArea
中的特定行号?
编辑
文本区域包含每行 3 到 11 个字母的单词。
编辑 2
这是 action
而不是 actionPerformed
的原因:
import java.awt.event.ActionEvent;
import javax.swing.*;
import static javax.swing.KeyStroke.getKeyStroke;
public abstract class KeyBoundMenuItem extends JMenuItem{
public abstract void action(ActionEvent e);
public KeyBoundMenuItem(String actionMapKey, int key, int mask)
{
Action myAction = new AbstractAction()
{
@Override public void actionPerformed(ActionEvent e)
{
action(e);
}
};
setAction(myAction);
getInputMap(WHEN_IN_FOCUSED_WINDOW)
.put(getKeyStroke(key, mask),actionMapKey);
getActionMap().put( actionMapKey, myAction);
}
}
编辑 3
可以用这个代替 KeyBoundMenuItem
:
public static void shortcut(JMenuItem item, int mnem, int mods, int key)
{
item.setMnemonic(mnem);
item.setAccelerator(getKeyStroke(key,mods));
}
但是已经为类似的 class KeyBoundButton
编写了代码。当天晚些时候轻松更改。
编辑 4
以下是需要向上或向下滚动的文本类型:
Is there a way to set the caret to a particular line number
查看 Text Utilities class。方法如:
getLineAtCaret()
和gotoStartOfLine(...)
应该允许你做你想做的事。那就是向下滚动你可以这样做:
int currentLine = RXTextUtilities.getLineAtCaret(textArea);
RXTextUtilities.gotoStartOfLine(textArea, currentLine + 10);
感谢@camickr,这是有效的(PAGEUP 的代码是相同的,除了 -
而不是 +
:
PageDown = new KeyBoundMenuItem("PAGEDOWN", VK_PAGE_DOWN, CTRL_DOWN_MASK)
{
@Override
public void action(ActionEvent e)
{
int currentLine = RXTextUtilities.getLineAtCaret(txaOutput);
RXTextUtilities.gotoStartOfLine(
txaOutput,
currentLine + RXTextUtilities.maxLinesVisibleInWindow(txaOutput));
}
};
我可能应该修改此代码以反映他的有效批评,即我不必制作 abstract class
来完成键绑定,但它并没有坏。 (我可能有一天会抽出时间...)
我什至想出了(通过研究他的 Text Utilities)如何在不使用常量的情况下滚动 window(28,参见评论):
public static int maxLinesVisibleInWindow(JTextComponent component)
{
Container container = getAncestorOfClass(JViewport.class, component);
if (container == null) return 0;
JViewport viewport = (JViewport)container;
int extentHeight = viewport.getExtentSize().height;
FontMetrics fm = component.getFontMetrics(component.getFont());
int characterHeight = fm.getHeight();
return (int)extentHeight/characterHeight - 1;
}