在JscrollPane内部循环中添加标签

时间:2018-05-19 02:14:22

标签: java swing jscrollpane

我有一个循环,生成一些标题和描述,这些是字符串值,我制作标签包含这两个字符串,我想将这些添加到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 :(得分:1)

一个问题是您尝试将组件直接添加到JScrollPane,而JScrollPane不是组件应该去的地方。相反,这些组件属于视口的视图,即JScrollPane正在显示的组件。

建议:

  • 创建一个代表此视图的JPanel,并将其添加到JScrollPane的视口中。
  • 为此JPanel提供合适的布局,以便能够正确显示添加到其中的组件
  • 在上面的代码中,将您的组件添加到此JPanel,然后重新验证并重新绘制它,以便其布局管理器布局组件并正确绘制它们。
  • 或者更好,更清洁,将表格数据添加到JScrollPane所持有的JTable

例如,下面的代码将一对JLabel添加到innerPanel JPanel,一个使用BorderLayout将一个标签放在左边和另一个中心。 然后它将此innerPanel放入另一个JPanel,viewportViewPanel,它使用GridLayout将innerPanel放置在单列多行网格中。 viewportViewPanel通过将其传递到JScrollPane的构造函数中而放置在JScrollPane的视口中。请注意,我们从不在JScrollPane上调用.add(...)

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中的标题,并在JTextArea中显示所选JList项目的描述。像这样:

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

答案 1 :(得分:1)

我做了一些更正以使您的代码工作,并添加了注释来解释需要做什么:

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

代码可以进一步改进。我试图尽量减少变化,希望能让您更容易看到变化 不要犹豫,根据需要要求澄清。