我知道 JViewport 是一个单子容器,而且我不能将多个组件添加到一个 jscrollpane。
但是我可以跟踪滚动窗格的位置并根据它修改另一个组件的视图吗?为了展示我在这里尝试做的是一张图片:
这是我的代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.border.MatteBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
public class XMLSettingsPage extends JPanel {
private int lines;
private LinePanel linePanel;
private JPanel southButtP;
private JButton saveBtn = new JButton("Save");
private JButton resetBtn = new JButton("Reset");
private JScrollPane jsp;
private JTextArea textArea;
private JPanel panel;
public XMLSettingsPage() {
setBackground(Color.BLACK);
setLayout(new BorderLayout());
panel = new JPanel();
add(panel, BorderLayout.CENTER);
panel.setLayout(new BorderLayout(0, 0));
linePanel = new LinePanel();
panel.add(linePanel, BorderLayout.WEST);
linePanel.setForeground(Color.GRAY);
linePanel.setFont(new Font("Tahoma", Font.PLAIN, 13));
linePanel.setBackground(SystemColor.inactiveCaptionBorder);
textArea = new JTextArea();
textArea.setCaretColor(Color.BLACK);
textArea.setFont(new Font("Tahoma", Font.PLAIN, 13));
textArea.setForeground(Color.BLACK);
textArea.setBackground(UIManager.getColor("menu"));
textArea.addKeyListener(new LinePanel() {
@Override
public void keyPressed(KeyEvent e) {
linePanel.setLine(getLines());
}
});
textArea.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
southButtP.setVisible(false);
}
@Override
public void focusGained(FocusEvent e) {
southButtP.setVisible(true);
}
});
LinePainter painter = new LinePainter(textArea);
painter.setColor(Color.WHITE);
jsp = new JScrollPane(textArea);
panel.add(jsp, BorderLayout.CENTER);
jsp.setBackground(Color.BLACK);
jsp.setBorder(null);
southButtP = new JPanel();
add(southButtP, BorderLayout.SOUTH);
southButtP.setBorder(new MatteBorder(1, 0, 0, 0, (Color) Color.WHITE));
southButtP.add(resetBtn);
southButtP.add(saveBtn);
southButtP.setBackground(SystemColor.scrollbar);
southButtP.setVisible(false);
resetBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
reset();
}
});
resetBtn.setBackground(resetBtn.getParent().getBackground());
saveBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
save();
}
});
saveBtn.setBackground(resetBtn.getParent().getBackground());
}
private int getLines() {
int totalCharacters = textArea.getText().length();
int lineCount = (totalCharacters == 0) ? 1 : 0;
try {
int offset = totalCharacters;
while (offset > 0) {
offset = Utilities.getRowStart(textArea, offset) - 1;
lineCount++;
}
} catch (BadLocationException e) {
e.printStackTrace();
}
return lineCount;
}
private void reset() {
textArea.setText(getXMLSettingsData());
}
private void save() {
// write to xml file settings.
}
private String getXMLSettingsData() {
return null;
}
public static void setXMLSettingsData() {
// sets xml data on change
}
}
// Line Panel.
class LinePanel extends JTextArea implements KeyListener {
private int lineNumber = 1;
private StringBuilder sb;
final private String END_STRING = " \n";
public LinePanel() {
sb = new StringBuilder();
setBackground(Color.BLACK);
setFont(new Font("Tahoma", Font.PLAIN, 13));
setEditable(false);
}
public void printNumbers(String s) {
setText(s);
}
private void numberFactory(int l) {
sb.delete(0, sb.length());
for (int i = 0, a = 1; i < l; i++, a++) {
sb.append(" " + a + END_STRING);
}
printNumbers(sb.toString());
}
public void setLine(int line) {
if (lineNumber != line) {
lineNumber = line;
numberFactory(line);
} else {
}
}
public int getLine() {
return lineNumber;
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
当我到达窗口底部时,我看不到另一个行号,原因很明显(它不是自动向下滚动也不是手动向下滚动)。
有什么方法可以将我的 JScrollPane 连接到东 JTextArea,这样即使在我到达面板底部后我也可以看到每行的数字?
如果您知道任何更好的方法来做到这一点,请让我知道我对任何想法持开放态度。
我试图将两个组件放入一个面板中,然后将滚动面板放到它上面,但它不起作用。在那之后我什至看不到面板中心的任何东西。不知道我做错了什么,芽并没有被视为这样做的好方法。