2017-01-13 1 views
0

Il s'agit de la classe dans laquelle le programme est exécuté.JScrollPane ne fonctionne pas, viewport empile les panneaux

import java.awt.Color; 
import java.awt.GridLayout; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class runClass { 

public static void main(String[] args) { 

    JFrame frame = new JFrame(); 
    frame.setSize(1366, 768); 
    frame.setVisible(true); 

    JPanel backgroundPanel = new JPanel(); 
    backgroundPanel.setBounds(0, 0, 1366, 768); 
    backgroundPanel.setBackground(Color.PINK); 
    frame.getContentPane().add(backgroundPanel); 

    JPanel panel = new JPanel(); 
    panel.setLayout(new GridLayout(0,1,10,10)); 

    JScrollPane scrollPane = new JScrollPane(); 
    scrollPane.setBounds(228, 5, 453, 426); 
    scrollPane.setViewportView(panel); 
    scrollPane.setVisible(true); 
    backgroundPanel.setLayout(null); 
    backgroundPanel.add(scrollPane); 

    for (int x = 0; x < 15; x++){ 
     panel.add(new ExerciseList(new Exercise("hello"))); 
    } 

    panel.revalidate(); 
    panel.repaint(); 

} 
} 

Ce sont les panneaux qui sont ajoutés dans le conteneur.

import java.awt.Color; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import java.awt.Font; 

public class ExerciseList extends JPanel{ 

    private Exercise exercise; 

    public ExerciseList(Exercise e){ 

     this.exercise = e; 

     setLayout(null); 
     setVisible(true); 
     setBackground(Color.LIGHT_GRAY); 

     JLabel lblName = new JLabel(exercise.getName()); 
     lblName.setFont(new Font("Tahoma", Font.PLAIN, 18)); 
     lblName.setBounds(229, 11, 209, 22); 
     add(lblName); 

    } 
} 

Ceci est la classe d'exercices utilisée pour extraire des informations pour ExerciseList.

public class Exercise { 

    private String name; 

    public Exercise(String name) { 
     super(); 
     this.name = name; 

    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

} 

Ceci est une image de l'empilage de ExerciseList que je reçois.

As you can see, the ExerciseList panels are overlapping, rather than the JScrollPane allowing me to scroll

Toute aide est appréciée! Merci

+2

Pour une meilleure aide plus tôt s'il vous plaît poster un valide [mcve] qui démontre la question. Probablement lié au mélange d'un [Gestionnaire de mise en page] (https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) et 'setBounds()'. Cependant, pour votre interface graphique, vous pouvez essayer d'utiliser un ['JTable'] (https://docs.oracle.com/javase/7/docs/api/javax/swing/JTable.html) – Frakcool

+0

Ok merci! Je préfère rester avec cette mise en page GUI. Alors, où le problème peut provenir à la fois du gestionnaire de mise en page et setbounds()? –

+0

Le problème est que vous ne pouvez pas et ne devriez pas faire cela. Laissez les dispositions et les tailles préférées des composants définir leur taille réelle, sinon l'interface graphique est affichée de manière amusante comme vous le voyez. –

Répondre

3

Voici le problème: vous utilisez les dispositions null, une mise en page que JScrollPanes n'est pas équipé pour traiter et qui devrait être évitée en règle générale. Débarrassez-vous de ceci:

// setLayout(null); 

et vos problèmes disparaissent. Pourquoi c'est un problème? Le gestionnaire de disposition d'un conteneur et ses composants aident à déterminer la taille préférée du conteneur et de ses composants. Si des dispositions nulles sont utilisées, cela ne se produit pas et la vue de la fenêtre d'affichage (le JPanel détenu par JScrollPane) ne se développera pas comme elle le devrait lorsque d'autres composants sont ajoutés. Alors que les mises à zéro et les setBounds() peuvent sembler aux débutants Swing comme le moyen le plus facile et le meilleur de créer des interfaces graphiques complexes, plus vous créez les plus grandes difficultés que vous rencontrerez lors de leur utilisation. Ils ne redimensionnent pas vos composants lorsque l'IHM redimensionne, ils sont une sorcière royale à améliorer ou à maintenir, ils échouent complètement lorsqu'ils sont placés dans des scrollpanes, ils ont l'air horrible quand on les regarde sur toutes les plateformes ou résolutions d'écran différentes de l'original .

Apprenez les gestionnaires de disposition.

Ensuite, utilisez-les.

Par exemple:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class ExerciseDemo extends JPanel { 
    private static final int PREF_W = 500; 
    private static final int PREF_H = 450; 
    protected static final int MAX_COUNTER = 30; 
    private JPanel exerciseHolder = new JPanel(new GridLayout(0, 1)); 

    public ExerciseDemo() { 
     JPanel wrapperPanel = new JPanel(new BorderLayout()); 
     wrapperPanel.add(exerciseHolder, BorderLayout.PAGE_START); 
     JScrollPane scrollPane = new JScrollPane(wrapperPanel); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

     setLayout(new BorderLayout()); 
     add(scrollPane); 

     new Timer(300, new ActionListener() { 
      int counter = 0; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       counter++; 
       exerciseHolder.add(new ExerciseList2(new Exercise("John Smith " + counter))); 
       exerciseHolder.revalidate(); 
       exerciseHolder.repaint(); 
       if (counter > MAX_COUNTER) { 
        ((Timer) e.getSource()).stop(); 
       } 
      } 
     }).start(); 

    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private static void createAndShowGui() { 
     ExerciseDemo mainPanel = new ExerciseDemo(); 

     JFrame frame = new JFrame("ExerciseDemo"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

@SuppressWarnings("serial") 
class ExerciseList2 extends JPanel { 
    private static final Font NAME_FONT = new Font("Tahoma", Font.PLAIN, 18); 
    private Exercise exercise; 

    public ExerciseList2(Exercise exercise) { 
     this.exercise = exercise; 

     JLabel lblName = new JLabel(exercise.getName()); 
     lblName.setFont(NAME_FONT); 

     setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); 
     setLayout(new BorderLayout(15, 0)); 
     add(new JCheckBox("Check Box"), BorderLayout.LINE_START); 
     add(lblName, BorderLayout.CENTER); 
     add(new JButton("Button"), BorderLayout.LINE_END); 
    }  

    public Exercise getExercise() { 
     return exercise; 
    } 

} 
+0

Wow, merci pour l'information. Je vais prendre cela en compte car je fais plus de GUI. Merci beaucoup! –

+0

@ gary.l: par exemple, compilez et exécutez le code ci-dessus. Il nécessite votre classe d'exercice pour travailler. –

+0

Très impressionnant, merci beaucoup Hovercraft !! –