Добавить метки внутри JscrollPane внутри цикла - PullRequest
0 голосов
/ 19 мая 2018

У меня есть цикл, который генерирует некоторые заголовки и описания, которые являются строковыми значениями, и я сделал Labels, чтобы содержать эти две строки, я хочу добавить их к JScrollPane, но по какой-то причине мой код не работает, яЯ не получаю никаких ошибок, элемент не добавляется на панель прокрутки, вот мой код:

package testa;

import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class test extends JFrame {

    JLabel[] titles;
    JLabel[] descriptions;
    JPanel[] panels;
    JScrollPane jScrollPane1 = new JScrollPane();
    JPanel bigPanel = new JPanel();

    public test() {
        this.setLocationRelativeTo(null);
        this.setSize(1000, 500);
        this.jScrollPane1.setSize(1000, 500);

        this.getContentPane().add(this.jScrollPane1);

        this.setVisible(true);
        requetezQuery();
    }

    public void requetezQuery() {
        int resultsList = 10;
        this.titles = new JLabel[resultsList];
        this.descriptions = new JLabel[resultsList];
        this.panels = new JPanel[resultsList];
        for (int i = 0; i < resultsList; i++) {

            String title = "Test Title " + i;
            String resume = "Test Resume " + i;

            this.titles[i] = new JLabel();
            this.descriptions[i] = new JLabel();
            this.panels[i] = new JPanel();
            this.panels[i].setLayout(new FlowLayout());
            this.titles[i].setText(title);
            this.descriptions[i].setText(resume);
            this.titles[i].setForeground(Color.red);
            this.descriptions[i].setForeground(Color.red);
            this.panels[i].add(this.titles[i]);
            this.panels[i].add(this.descriptions[i]);
            this.bigPanel.add(panels[i]);
        }
        this.jScrollPane1.add(this.bigPanel);
    }

    public static void main(String args[]) {
        test a = new test();
    }
}

Я пытался System.out.println заголовки и переменные возобновления и его работа, поэтому проблема не вне из них.

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Я внес некоторые исправления, чтобы заставить вас работать с кодом, и добавил комментарии, объясняющие, что нужно сделать:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout; 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Test extends JFrame{ //see https://www.javatpoint.com/java-naming-conventions

    private JLabel[] titles;
    private JLabel[] descriptions;
    private JPanel [] panels;
    private JScrollPane jScrollPane1;
    private JPanel bigPanel;
    private final static int NUM_OF_RESULTS =10;

    public Test() {

        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //this.setSize(1000,500);             no need to set size. use preferred sizes
        //jScrollPane1.setSize(1000, 500);    and layouts. see following comments

        bigPanel = new JPanel();
        //set layout to
        GridLayout layout = new GridLayout(NUM_OF_RESULTS, 0);
        bigPanel.setLayout(layout);
        jScrollPane1 = new JScrollPane(bigPanel);
        getContentPane().add(jScrollPane1);

        requetezQuery();
        pack(); //see https://stackoverflow.com/questions/22982295/what-does-pack-do
        setVisible(true); //set visible typically comes last
    }
    public void requetezQuery(){

        titles = new JLabel[NUM_OF_RESULTS];
        descriptions = new JLabel[NUM_OF_RESULTS];
        panels = new JPanel[NUM_OF_RESULTS];

        for(int i = 0; i<NUM_OF_RESULTS; i++){

            String title="Test Title "+i;
            String resume="Test Resume "+i;

            titles[i]= new JLabel();
            descriptions[i]= new JLabel();
            panels[i]= new JPanel();
            panels[i].setPreferredSize(new Dimension(250, 50));
            panels[i].setLayout(new FlowLayout()); //FlowLayout is default for JPanel
            titles[i].setText(title);
            descriptions[i].setText(resume);
            titles[i].setForeground(Color.red);
            descriptions[i].setForeground(Color.red);
            panels[i].add(titles[i]);
            panels[i].add(descriptions[i]);
            bigPanel.add(panels[i],i, 0);
        }
    }

    public static void main(String args[]){
        new Test();
    }
}

Код можно еще улучшить.Я пытался свести к минимуму изменения, надеясь, что вам будет легче их увидеть.Не стесняйтесь обращаться за разъяснениями по мере необходимости.

0 голосов
/ 19 мая 2018

Одной из проблем является то, что вы пытаетесь добавить компоненты непосредственно в 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());
    }
}
...