2017-01-13 15 views
0

Это класс, в котором запускается программа.JScrollPane не работает, viewport представляет собой панели для укладки

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(); 

} 
} 

Это панели, которые добавляются в контейнер.

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); 

    } 
} 

Этот класс упражнений используется для извлечения информации для 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; 
    } 

} 

Это изображение укладки ExerciseList, которое я получаю.

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

Любая помощь приветствуется! Спасибо

+2

Для лучшей помощи рано пожалуйста, оставить в силе [mcve], который демонстрирует проблему. Вероятно, связано с сочетанием менеджера макетов (https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) и 'setBounds()'. Однако для вашего графического интерфейса вы можете попробовать использовать ['JTable'] (https://docs.oracle.com/javase/7/docs/api/javax/swing/JTable.html) – Frakcool

+0

Хорошо, спасибо! Я предпочитаю оставаться с этим графическим интерфейсом. Итак, где проблема может возникнуть как из менеджера компоновки, так и для setbounds()? –

+0

Проблема в том, что вы не можете и не должны этого делать. Пусть макеты и компоненты имеют предпочтительные размеры, устанавливают их фактический размер, иначе GUI отображается смешными способами, как вы видите. –

ответ

3

Вот проблема: вы используете макеты null, макет, который JScrollPanes не оборудован, и этого следует избегать в качестве общего правила. Избавиться от этого:

// setLayout(null); 

и ваши проблемы уходят. Почему это проблема? Как менеджер компоновки контейнера, так и его компоненты помогают определить предпочтительный размер контейнера и его компонентов. Если используются пустые макеты, то этого не происходит, и поэтому вид viewport (JPanel, хранящийся JScrollPane) не будет расширяться, как и при добавлении дополнительных компонентов.

В то время как пустые макеты и setBounds() могут показаться Swing новичками, как самый простой и лучший способ создания сложных графических интерфейсов, чем больше Swing GUI вы создадите более серьезные трудности, с которыми вы столкнетесь при их использовании. Они не будут изменять размеры ваших компонентов при изменении размера графического интерфейса, они являются королевской ведьмой для улучшения или поддержки, они полностью не выполняются при размещении в scrollpanes, они выглядят ужасно ужасно при просмотре на всех платформах или разрешениях экрана, отличных от исходного ,

Изучите руководство по планированию.

Затем используйте их.

Например:

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

Ничего себе, спасибо за информацию. Я буду принимать это во внимание, поскольку я делаю больше GUI. Большое спасибо! –

+0

@ gary.l: например, скомпилируйте и запустите указанный выше код. Это требует, чтобы ваш класс упражнений работал. –

+0

Очень впечатляет, большое вам спасибо на воздушной подушке! –