2014-01-24 23 views
1

我知道JViewport是一個獨生子容器,並且我不能將多個組件添加到一個jscrollpane。如何使一個JScrollPane連接到兩個組件?,解決方法

但我可以跟蹤scrollpane的位置,並根據它修改另一個組件的視圖嗎? 要顯示什麼即時試圖在這裏做的是一個形象:

http://i.imgur.com/X9GW3VO.png

這裏是我的代碼:

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,這樣我可以看到每行的數字,即使在達到面板底部之後?

如果你知道更好的方法來做到這一點,請讓我知道我對任何想法都是開放的。

我試圖把兩個組件放到一個面板中,然後把scrollpane放到它沒有工作的位置。之後,我甚至都看不到我面板中心的任何東西。不知道我做了什麼錯誤的芽沒有被視爲一個好辦法做到這一點。

+0

將兩個部件在一個面板,一個面板添加到滾動窗格。 –

回答

3

使用rowHeader視圖。

enter image description here

jsp.setRowHeaderView(textArea); 
+0

要試試這個,並返回我的結果 –

+0

這是瘋狂的2行代碼,一切正常!謝謝,當我能夠時,好的解決方案將會接受答案。 –

+1

幸運的是,java swing開發者做得很好。 :) –

相關問題