Одной из проблем является то, что вы пытаетесь добавить компоненты непосредственно в JScrollPane, а это не то место, куда эти компоненты должны идти.Вместо этого эти компоненты принадлежат в представлении области просмотра, компоненте, который отображает JScrollPane.
Предложения:
- создайте JPanel, который представляет это представление, и добавьте его в область просмотра JScrollPane.
- Дайте этому JPanel приличный макет, чтобы он мог правильно отображать компоненты, добавленные к нему
- В приведенном выше коде добавьте свои компоненты к этому JPanel, затем повторно проверьте и перекрасьте его так, чтобыего менеджеры по расположению размечают компоненты и рисуют их правильно.
- Или, возможно, еще лучше и чище, добавьте ваши табличные данные в JTable, который хранится в JScrollPane
Например,код ниже добавляет пару JLabels к внутренней панели JPanel, которая использует BorderLayout для размещения одной метки слева, а другой - в центре.Затем он помещает эту innerPanel в другую JPanel, viewportViewPanel, которая использует GridLayout для размещения innerPanel в сетке из нескольких строк, состоящей из одного столбца.ViewportViewPanel помещается в область просмотра JScrollPane, передавая его в конструктор JScrollPane.Обратите внимание, что мы никогда не вызываем .add(...)
на JScrollPane:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class MyTest extends JPanel {
private static final int COUNT = 400;
private JPanel viewportViewPanel = new JPanel();
private JScrollPane scrollPane = new JScrollPane(viewportViewPanel);
public MyTest() {
setPreferredSize(new Dimension(800, 500));
viewportViewPanel.setLayout(new GridLayout(0, 1));
for (int i = 0; i < COUNT; i++) {
String text = "abcd efgh ijkl mnop qrst uvwx";
text = String.format("%s %s %s", text, text, text);
JPanel innerPanel = new JPanel();
innerPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
innerPanel.setLayout(new BorderLayout());
innerPanel.add(new JLabel("Test Title:"), BorderLayout.LINE_START);
innerPanel.add(new JLabel(text, SwingConstants.CENTER));
viewportViewPanel.add(innerPanel);
}
setLayout(new BorderLayout());
add(scrollPane);
}
private static void createAndShowGui() {
MyTest mainPanel = new MyTest();
JFrame frame = new JFrame("MyTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Еще лучше, если вы хотите показать заголовок и описание, рассмотрите возможность показа только заголовков в JList,и показывает описание выбранного элемента JList в JTextArea.Примерно так:
import java.awt.BorderLayout;
import javax.swing.*;
@SuppressWarnings("serial")
public class ShowTitleDescriptions extends JPanel {
private static final int COUNT = 500;
// nonsense text as a demo filler
private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur "
+ "adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore "
+ "magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco "
+ "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor "
+ "in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
+ "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa "
+ "qui officia deserunt mollit anim id est laborum.";
private DefaultListModel<TitleDescription> listModel = new DefaultListModel<>();
private JList<TitleDescription> titlesList = new JList<>(listModel);
private JTextArea descriptionArea = new JTextArea(20, 60);
public ShowTitleDescriptions() {
titlesList.setVisibleRowCount(20);
JScrollPane titleScroll = new JScrollPane(titlesList);
descriptionArea.setLineWrap(true);
descriptionArea.setWrapStyleWord(true);
descriptionArea.setEditable(false);
JScrollPane descriptionScroll = new JScrollPane(descriptionArea);
for (int i = 0; i < COUNT; i++) {
String title = "Title " + i;
StringBuilder descriptionSb = new StringBuilder();
// fill description with random text
for (int j = 0; j < 40; j++) {
descriptionSb.append(title + "\n");
descriptionSb.append(LOREM_IPSUM + " ");
descriptionSb.append(LOREM_IPSUM + " ");
descriptionSb.append(LOREM_IPSUM);
descriptionSb.append("\n\n");
}
TitleDescription titleDescr = new TitleDescription(title, descriptionSb.toString());
listModel.addElement(titleDescr);
}
titlesList.addListSelectionListener(l -> {
TitleDescription selection = titlesList.getSelectedValue();
descriptionArea.setText(selection.getDescription());
});
titlesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
titlesList.setSelectedIndex(0);
setLayout(new BorderLayout());
add(descriptionScroll);
add(titleScroll, BorderLayout.LINE_END);
}
// class to hold title and description together
private static class TitleDescription {
private String title;
private String description;
public TitleDescription(String title, String description) {
this.title = title;
this.description = description;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
// JList uses this to decide what to display
@Override
public String toString() {
return title;
}
}
private static void createAndShowGui() {
ShowTitleDescriptions mainPanel = new ShowTitleDescriptions();
JFrame frame = new JFrame("ShowTitleDescriptions");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}