2015-02-23 3 views
0

У меня есть ScrollPane с JPanel в моей программе Java, которая получает много добавленного текста. Мне нужно, чтобы ScrollPane прокручивалась до самого нижнего уровня после каждого добавления. Моя проблема со следующим кодом заключается в том, что он прокручивает «почти» до нижней, но не полностью. Любые идеи относительно того, что я делаю неправильно?Java JScrollPane прокручивает вниз ... почти

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

public class Sample extends JFrame{ 
    JTextField input = new JTextField(); 
    JPanel log = new JPanel(); 
    JScrollPane scrollPane = new JScrollPane(log); 
    JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); 

    public Sample(){ 

     input.setBorder(new TitledBorder("Message")); 
     input.setToolTipText("Type a message here."); 

     log.setBorder(new TitledBorder("Log")); 
     log.setLayout(new BoxLayout(log, BoxLayout.Y_AXIS)); 
     log.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 

     // Add the panels to the frame 
     setLayout(new BorderLayout(10, 10)); 
     add(input, BorderLayout.NORTH); 
     add(scrollPane, BorderLayout.CENTER); 

     setTitle("Chat Window"); 
     setSize(400, 300); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setVisible(true); 

     // Register Key listener 
     input.addKeyListener(new KeyAdapter() { 
      @Override 
      public void keyReleased(KeyEvent e) { 
       if (e.getKeyCode() == KeyEvent.VK_ENTER) { 
        log.add(new ServerBubble(input.getText())); 
        log.add(Box.createRigidArea(new Dimension(0, 10))); 
        input.setText(null); 
        scrollPane.revalidate(); 
        scrollBar.setValue(scrollBar.getMaximum()); 
       } 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     JFrame frame = new Exercise33_9Server(); 

    } 

    private class ServerBubble extends JLabel{ 

     private final Color LIGHT_GREEN = new Color(204, 255, 229); 
     private final Color DARK_GREEN = new Color(0, 102, 51); 
     String message; 

     public ServerBubble(String label){ 
      message = processText(label); 
      setOpaque(true); 
      setForeground(DARK_GREEN); 
      setBackground(LIGHT_GREEN); 
      setHorizontalAlignment(LEFT); 
      setBorder(new LineBorder(DARK_GREEN, 3, true)); 
      setText(label); 
      setBorder(BorderFactory.createCompoundBorder(getBorder(), BorderFactory.createEmptyBorder(5, 5, 5, 5))); 
     } 

     private String processText(String message){ 
      message = "<HTML>" + message; 
      return message; 
     } 
    } 
} 
+0

1- Использовать API привязки ключей над 'KeyListener'; 2- 'revalidate' view (' log'), прежде чем пытаться перейти к концу панели прокрутки. – MadProgrammer

+0

Я должен использовать keyListener, поскольку это часть целей школьных заданий. –

+0

Тогда ваша школа ПУТЬ позади ... – MadProgrammer

ответ

0

В принципе, возможно, вы пытаетесь обновить область просмотра до того, как иерархия компонентов успела обновиться. Иногда ты просто ждал.

В этом примере в основном используется SwingUtilities.invokeLater, чтобы отправить запрос на очередь событий о том, что некоторая часть работы будет выполнена «в ближайшее время в ближайшем будущем». Это позволяет текущие ожидающие обновления времени для обработки ...

if (e.getKeyCode() == KeyEvent.VK_ENTER) { 

    log.add(new ServerBubble(input.getText())); 
    log.add(Box.createRigidArea(new Dimension(0, 10))); 
    input.setText(null); 
    log.revalidate(); 

    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      Dimension vpSize = scrollPane.getViewport().getExtentSize(); 
      Dimension logSize = log.getSize(); 

      int height = logSize.height - vpSize.height; 
      scrollPane.getViewport().setViewPosition(new Point(0, height)); 
     } 
    }); 
} 

В это время, я хватаю текущий размер вида и сравнить его с текущим размером бревенчатого панели, то я использую разные для вычисления смещения y от нижней части панели, которая позволила бы видеть последний элемент ...

+0

Да !!! это решило проблему. Я вытаскивал свои волосы, пытаясь заставить это работать. Благодарю вас. –

Смежные вопросы