2016-11-07 2 views
0

У меня есть JPanel внутри JScrollPane внутри GridBagLayout , не прокрутке должным образом. Что должно произойти, так это то, что каждый раз, когда нажата кнопка xxx xxx, в области прокрутки добавляется новая строка. Что на самом деле происходит, так это то, что если xxx нажата, скажем, 10 раз, появляются только первые семь строк, а остальные не могут быть прокручены. Может ли кто-нибудь предложить изменения к исходному коду ниже, что приведет к правильной прокрутке ? Я потратил несколько часов на это без успеха, пробовал стратегии всего через Интернет.JPanel внутри от JScrollPane внутри GridBagLayout не прокручивать правильно

Примечания:

  1. Текст разделен на paintComponent, потому что drawString делает не справиться с конца-строки символов.
  2. JPanel внутри JScrollPane внутри GridBagLayout конфигурация является необходимой частью гораздо более крупного программного обеспечения с той же проблемой, поэтому я сохранил его здесь.

Спасибо.

import java.util.*; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class question { 

    public static void main(String[] args) { 
     new DrawingGUI(); 
    } 

    private static class ScrollingPane extends JPanel { 
     private static final long serialVersionUID = 1L; 

     String text; 

     public ScrollingPane() { 
      setPreferredSize(new Dimension(300, 100)); 
      text = ""; 
     } 

     public void SetText(String text_x) {text = text + System.lineSeparator() + text_x;} 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      FontMetrics fm = g.getFontMetrics(); 

      int y = -fm.getHeight(); 
      for (String text : text.split("\n")) 
       g.drawString(text, 0, y += fm.getHeight()); 
     } 
    } 

    static class DrawingGUI extends JFrame implements ActionListener { 
     private static final long serialVersionUID = 1L; 

     JPanel jp; 
     JScrollPane js; 
     ScrollingPane sp; 

     int LineNum; 

     DrawingGUI() { 
      LineNum = 0; 
      JFrame frame = new JFrame("xxx"); 
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

      addComponentsToPane(frame.getContentPane()); 

      frame.setSize(800,800); 
      frame.setVisible(true); 
     } 

     public void addComponentsToPane(Container pane) { 
      pane.setLayout(new GridBagLayout()); 
      GridBagConstraints c = new GridBagConstraints(); 

      JButton button = new JButton("xxx"); 
      button.setActionCommand("add_text"); 
      button.addActionListener(this); 
      c.gridx = 0; 
      c.gridy = 0; 
      pane.add(button, c); 

      jp = new JPanel(); 
      c.gridx = 0; 
      c.gridy = 1; 
      c.ipadx = 600; 
      c.ipady = 450; 
      pane.add(jp, c); 

      sp = new ScrollingPane(); 

      js = new JScrollPane(sp); 
      js.getViewport().setPreferredSize(new Dimension(300,100)); 
      c.gridx = 0; 
      c.gridy = 2; 
      c.ipady = 50; 
      pane.add(js, c); 
     } 

     public void actionPerformed(ActionEvent e) { 
      if ("add_text".equals(e.getActionCommand())) { 
       LineNum++; 
       sp.SetText("LineNum = " + LineNum); 
       sp.revalidate(); 
       sp.repaint(); 
      } 
     } 
    } 

} 
+0

Пожалуйста, см редактировать ответить. –

+0

............... привет? –

+0

Спасибо. ScrollingPane2 был тем, что мне нужно. –

ответ

1

Вы короткое замыкание способности вашего ScrollingPane JPanel от правильной калибровки себя с этой линией:

setPreferredSize(new Dimension(300, 100)); 

Это зафиксирует размер ScrollingPane JPanel. Я вижу, что у вас есть несколько возможных решений:

  1. Трудные: переопределить GetPreferredSize() для ScrollingPane JPanel, и рассчитать соответствующий предпочтительный размер в зависимости от размера текста он держит и тянет с использованием FontMetrics.
  2. Проще: не добавляйте текст так, как вы делаете, но вместо этого используйте ScrollingPane с помощью GridLayout (0, 1) (один столбец, переменное количество строк) и добавьте JLabels в ScrollingPane, когда требуется новый текст для быть добавлен. Затем наберите revalidate() и repaint().
  3. Простенький: Не используйте ScrollingPane JPanel, а скорее JTextArea, что выглядит как JPanel и не может быть отредактирован. Добавьте это в JScrollPane и снова, не ограничивайте его размер.
  4. Самый простой. Просто используйте JList, так как это функциональность, которую вы используете здесь.

К примеру, любой из них будет работать, и будет выглядеть примерно так:

private static class ScrollingPane2 extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private JTextArea textArea = new JTextArea(6, 20); 

    public ScrollingPane2() { 
     setLayout(new BorderLayout()); 
     add(textArea, BorderLayout.CENTER); 
     textArea.setEditable(false); 
     textArea.setFocusable(false); 
     textArea.setBackground(null); 
    } 

    public void SetText(String text_x) { 
     textArea.append(text_x + "\n"); 
    } 
} 

private static class ScrollingPane3 extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private DefaultListModel<String> listModel = new DefaultListModel<>(); 
    private JList<String> jList = new JList<>(listModel); 

    public ScrollingPane3() { 
     setLayout(new BorderLayout()); 
     add(jList, BorderLayout.CENTER); 
     jList.setBackground(null); 
    } 

    public void SetText(String text_x) { 
     listModel.addElement(text_x); 
    } 
} 
Смежные вопросы