Java 如何使一个JScrollPane连接到两个组件?解决方法

Java 如何使一个JScrollPane连接到两个组件?解决方法,java,swing,jscrollpane,jtextarea,rowheader,Java,Swing,Jscrollpane,Jtextarea,Rowheader,我知道JViewport是一个子容器,而且我不能将多个组件添加到一个jscrollpane中 但我可以跟踪滚动窗格的位置并根据它修改另一个组件的视图吗? 下面是一张图片,显示我想做什么: 这是我的密码: import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.SystemColor; import java.awt.event.ActionEvent; import j

我知道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) {
    }

}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.SystemColor;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.FocusEvent;
导入java.awt.event.FocusListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入javax.swing.JButton;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTextArea;
导入javax.swing.UIManager;
导入javax.swing.border.MatteBorder;
导入javax.swing.text.BadLocationException;
导入javax.swing.text.Utilities;
公共类XMLSettingsPage扩展了JPanel{
专用int线;
专用线板线板;
私人JPanel southButtP;
私有JButton saveBtn=新JButton(“Save”);
私有JButton resetBtn=新JButton(“重置”);
私有JScrollPane jsp;
私人JTEXTEXTAREA textArea;
私人JPanel小组;
公共XMLSettingsPage(){
挫折背景(颜色:黑色);
setLayout(新的BorderLayout());
panel=新的JPanel();
添加(面板、边框布局、中心);
panel.setLayout(新的BorderLayout(0,0));
linePanel=新的linePanel();
panel.add(linePanel,BorderLayout.WEST);
linePanel.setForeground(颜色:灰色);
linePanel.setFont(新字体(“Tahoma”,Font.PLAIN,13));
linePanel.setBackground(SystemColor.inactiveCaptionBorder);
textArea=新的JTextArea();
textArea.setCaretColor(颜色:黑色);
setFont(新字体(“Tahoma”,Font.PLAIN,13));
textArea.setForeground(颜色为黑色);
textArea.setBackground(UIManager.getColor(“菜单”);
textArea.addKeyListener(新的LinePanel(){
@凌驾
按下公共无效键(按键事件e){
linePanel.setLine(getLines());
}
});
addFocusListener(新FocusListener(){
@凌驾
公共无效焦点丢失(焦点事件e){
southButtP.setVisible(假);
}
@凌驾
获得公共无效焦点(焦点事件e){
southButtP.setVisible(真);
}
});
LinePainter=新的LinePainter(textArea);
painter.setColor(Color.WHITE);
jsp=新的JScrollPane(textArea);
添加(jsp,BorderLayout.CENTER);
setBackground(Color.BLACK);
jsp.setboorder(null);
southButtP=newjpanel();
添加(southButtP,BorderLayout.SOUTH);
southButtP.setboorder(新的MatteBorder(1,0,0,0,(彩色)Color.WHITE));
southButtP.add(resetBtn);
southButtP.add(saveBtn);
southButtP.setBackground(SystemColor.scrollbar);
southButtP.setVisible(假);
resetBtn.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
重置();
}
});
resetBtn.setBackground(resetBtn.getParent().getBackground());
saveBtn.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
save();
}
});
saveBtn.setBackground(resetBtn.getParent().getBackground());
}
私有int getLines(){
int totalCharacters=textArea.getText().length();
int lineCount=(totalCharacters==0)?1:0;
试一试{
整数偏移量=总字符数;
而(偏移量>0){
offset=Utilities.getRowStart(textArea,offset)-1;
lineCount++;
}
}捕获(错误位置异常e){
e、 printStackTrace();
}
返回行计数;
}
私有无效重置(){
setText(getXMLSettingsData());
}
私有void save(){
//写入xml文件设置。
}
私有字符串getXMLSettingsData(){
返回null;
}
公共静态无效设置xmlsettingsdata(){
//设置更改时的xml数据
}
}
//线路板。
类LinePanel扩展JTextArea实现KeyListener{
专用整数行号=1;
私家侦探;
最终私有字符串END_String=“\n”;
公共线路面板(){
sb=新的StringBuilder();
挫折背景(颜色:黑色);
setFont(新字体(“Tahoma”,Font.PLAIN,13));
可编辑设置(假);
}
公共无效打印编号(字符串s){
setText(s);
}
私有void numberFactory(int l){
sb.删除(0,sb.length());
对于(int i=0,a=1;i
当我到达窗口底部时,我看不到其他行号,原因很明显(它既不是自动向下滚动,也不是手动向下滚动)

有没有办法将我的JScrollPane连接到east JTextArea,这样即使我到达面板底部,我也能看到每行的编号?

如果你知道更好的方法,请告诉我我愿意接受任何想法

我试着把两个组件放在一个面板上,然后把scrollpane放在上面,但都没用。我甚至看不到一个面板
jsp.setRowHeaderView(textArea);