2013-01-11 5 views
1

Situation: J'ai un JScrollPane « scrollpane » contenant un JPanel « mainPanel » qui contient plusieurs JPanel de « Les itemPanels » un dessous de l'autre (informations lues à partir d'une base de données et objets créés en conséquence). L'utilisateur peut insérer de nouvelles entrées entre les existantes. Dans ce cas, la nouvelle entrée est ajoutée à la base de données et tous les composants ("itemPanels") sont générés à nouveau et ajoutés à un nouveau "mainPanel". A la fin, le nouveau "mainPanel" est réglé sur le scrollPane avec setViewPortView.Éviter le défilement automatique vers le bas après avoir appelé setViewportView dans un JScrollPane

Vector<JPanel> itemPanels = generateMyPanelsFromDB(); 
JPanel mainPanel = new JPanel(new GridBagLayout()); 
//.. layout stuff 
for(JPanel itemPanel: itemPanels) mainPanel.add(itemPanel,<gridbagconstraintsvar>); 
scrollPane.setViewportView(mainPanel); 

Ce qui se passe, c'est que les nouveaux composants sont ajoutés correctement et le scrollpane défile automatiquement jusqu'à la fin.

Comment puis-je éviter, que le scrollpane défile jusqu'à la fin (= reste où il était avant). Ce que je essayé: Entourez l'action ci-dessus:

int currentPos = scrollPane.getVerticalScrollBar().getValue(); 
//.. to the setViewPortView stuff 
scrollPane.getVerticalScrollBar().setValue(value); 

cela ne fait rien (le scrollpane défile toujours à la fin et rien de plus arrive). Je ne réussi à rescroll en arrière avec l'imbrication invokeLater suivante, mais cela ne peut pas être la bonne façon et n'empêche pas non plus le défilement vers le bas, puis sauvegarder (= l'œil blesse)

final int value = scrollPane.getVerticalScrollBar().getValue(); 
    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      scrollPane.setViewportView(mainPanel); 
      Thread t = new Thread() { 
       public void run() { 
        try { 
         Thread.sleep(1); 
        } 
        catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        javax.swing.SwingUtilities.invokeLater(new Runnable() { 
          public void run() { 
           scrollPane.getVerticalScrollBar().setValue(value); 
          } 
         }); 
       } 
      }; 
      t.start(); 
     } 
    }); 

Ajouté 2012 -01 à 14:

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

private JScrollPane commandScrollPane; 

public DebugImportCommandEditPanel() { 
    this.setLayout(new BorderLayout()); 
    this.commandScrollPane = new JScrollPane(this.getMainPanel()); 
    this.add(this.commandScrollPane, BorderLayout.CENTER); 
} 

private JPanel getMainPanel() { 
    Vector<InnerPanel> innerPanels = new Vector<InnerPanel>(); 
    for(int i=0;i<12;i++) innerPanels.add(new InnerPanel((i+1)+ ".")); 

    JPanel mainPanel = new JPanel(new GridBagLayout()); 
    GridBagConstraints c = new GridBagConstraints(); 
    c.gridx=0;c.gridy=0;c.weightx=1;c.weighty=1;c.fill = GridBagConstraints.BOTH; 
    for(InnerPanel panel: innerPanels) { 
     mainPanel.add(panel,c); 
     c.gridy++; 
    } 
    return mainPanel; 
} 

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

    protected InnerPanel(String number) { 
     this.setLayout(new BorderLayout()); 
     this.setBorder(BorderFactory.createTitledBorder("Inner Panel No. "+number)); 
     JTextPane textPane = new JTextPane(); 
     textPane.setText("Lorem ipsum dolor sit amet consectetuer tellus sociis sapien porttitor "+ 
         "Suspendisse. Mattis morbi eu In non ante convallis\n "+ 
         "tempus risus venenatis urna. Sed ipsum et parturient volutpat\n "+ 
         "adipiscing dolor quis adipiscing Donec odio.\n "+ 
         "Neque adipiscing pretium lacus Phasellus neque a vel sed wisi alique\n"+ 
         "t. Condimentum Sed pretium libero vitae facilisi pretium sit consequat a "+ 
         "tincidunt. Pharetra ac Aliquam."); 
     this.add(textPane,BorderLayout.CENTER); 
    } 
} 

}

+4

afair, le comportement par défaut à _not_ défile vers le bas - donc quelque chose dans votre code le fait dévier de la valeur par défaut. Pour le retracer, s'il vous plaît montrer un SSCCE a le comportement que vous décrivez. – kleopatra

+3

d'accord avec un commentaire, pour une meilleure aide plus tôt un post [SSCCE] (http://sscce.org/), court, runnable. compilable, à peu près 'JFrame', avec le principal' JPanel' (avec le 'n' JPanels' == hardcode 'PreferredSize' vide imbriqué vide), – mKorbel

+0

Id a fait un SSCCE (ne sais pas ce que cela représente, mais je suppose que vous parlez à propos d'un programme exemple simplifié pour prouver l'effet) et je peux confirmer que, avec cela, il n'y a pas de défilement automatique à la fin. Je vais devoir y regarder de plus près et je reviendrai avec les outcomming. Merci pour l'instant! – Hotkey

Répondre

1

en voyant votre edit: il pourrait être le JTextPane imbriquée - de façon inattendue (pour moi, au moins :-), il semble même comportement affect the overall scrolling sinon l'enfant direct de la fenêtre.

La solution est de configurer la stratégie de caret pour ne pas mettre à jour sur la définition du texte:

JTextPane tp = new JTextPane(); 
DefaultCaret caret = (DefaultCaret) tp.getCaret(); 
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); 
textPane.setText("Lorem ipsum dolor sit amet consectetuer tellus sociis sapien porttitor "+ 
    .... 

Notez que vous devez définir la stratégie avant la définition du texte.

+0

Merci beaucoup! Cela a fait l'affaire! – Hotkey

Questions connexes