0

我创建了一个使用自定义的JList内部 a 。包含用 HTML 包装其内容的 a,因此文本会自动换行。不使用包装工作,但是当我使用时,文本没有被包装并且出现水平滚动条。JScrollPaneListCellRendererListCellRendererJlabelJScrollPaneJScrollPane

我的摘录ListCellRenderer

public class WorkableCellRenderer implements ListCellRenderer<Workable> {

    @Override
    public final Component getListCellRendererComponent(final JList<? extends Workable> list, final Workable value,
            final int index, final boolean isSelected, final boolean isFocused) {
        JPanel cell = new JPanel();
        cell.setLayout(new BoxLayout(cell, BoxLayout.Y_AXIS));

        // ...

        JPanel pnlDescription = new JPanel();
        cell.add(pnlDescription);
        pnlDescription.setLayout(new BorderLayout());

        JLabel lblDescription =
                new JLabel("<html><p style=\"margin: 0; padding: 0;\">" + value.getDescription() + "</p></html>");
        lblDescription.setFont(lblDescription.getFont().deriveFont(Font.PLAIN));
        pnlDescription.add(lblDescription, BorderLayout.CENTER);

        // ...

        return cell;
    }

}

将我的列表添加到的方法JFrame

private void addLoadedModulesPanel() {
    pnlLoadedModulesWrapper = new JPanel();
    pnlBottom.add(pnlLoadedModulesWrapper, BorderLayout.CENTER);
    pnlLoadedModulesWrapper.setLayout(new MigLayout("insets 0 5 5 5", "[grow]", "[grow]"));

    pnlLoadedModulesBox = new JPanel();
    pnlLoadedModulesWrapper.add(pnlLoadedModulesBox, "cell 0 0,grow");
    pnlLoadedModulesBox.setLayout(new MigLayout("insets 3", "[grow]", "[grow]"));
    pnlLoadedModulesBox.setBorder(BorderFactory.createTitledBorder("Geladene Module"));

    lstLoadedModules = new JList<Workable>(DefaultWorkableManager.getInstance());
    lstLoadedModules.setCellRenderer(new WorkableCellRenderer());

    final JScrollPane listScroller = new JScrollPane(lstLoadedModules);

    pnlLoadedModulesBox.add(listScroller, "cell 0 0,grow");
}

我认为问题在于它的视口,JScrollPane因为它比它JScrollPane本身大。如何调整视口宽度,使其始终与JScrollPane?

这是一个显示我的问题的 MCVE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.border.EmptyBorder;

public class TestFrame extends JFrame {

    private static final long serialVersionUID = -5281126214046039839L;

    public static void main(final String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    final TestFrame frame = new TestFrame();
                    frame.setVisible(true);
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public TestFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200, 500);
        getContentPane().setLayout(new BorderLayout());

        final JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(mainPanel);

        final DefaultListModel<String> lm = new DefaultListModel<>();
        final JList<String> list = new JList<>(lm);
        list.setCellRenderer(new MyListCellRenderer());

        final JScrollPane scrollPane = new JScrollPane(list);
        mainPanel.add(scrollPane);

        for (int i = 1; i < 21; i++) {
            lm.addElement(String.valueOf(i));
        }
    }

    private class MyListCellRenderer implements ListCellRenderer<String> {

        private final JPanel panel = new JPanel();
        private final JLabel label = new JLabel();

        public MyListCellRenderer() {
            panel.setLayout(new BorderLayout());
            panel.setBackground(new Color(16777215));
            panel.add(label);
        }

        @Override
        public Component getListCellRendererComponent(final JList<? extends String> list, final String val,
                final int index, final boolean isSelected, final boolean hasFocus) {
            label.setText("<html><p>Item number " + val
                    + " contains some very long text, that ideally should wrap.</p></html>");

            if (isSelected) {
                panel.setBackground(new Color(5323));
            } else {
                panel.setBackground(new Color(16777215));
            }

            return panel;
        }
    }

}
4

2 回答 2

2

一切都取决于...,然后JListinJScrollPane可以返回正确的getPreferredSize(或直接通过使用JList.setPrototypeCellValue)用于使用LayoutManager

  1. 什么是getPreferredSize回报的价值ListCellRenderer,这PreferredSize对于所有项目是否都相同

  2. 如何为JList.setLayoutOrientation()设置

  3. 是否有可见行的使用限制JList.setVisibleRowCount()

于 2014-04-30T08:40:19.953 回答
1

认为问题在于 JScrollPane 的视口,因为它比 JScrollPane 本身大。如何调整视口宽度以使其始终具有与 JScrollPane 相同的宽度?

您需要在面板上实现Scrollable接口以将面板的宽度限制为滚动窗格的宽度。

或者您可以使用可滚动面板,它提供了一些方法来控制这种行为。

于 2014-04-30T15:22:41.887 回答