Всем привет. Есть следующая задача: Есть компонент JList внутри которого содержится набор Item'ов, каждый item в себе содержит текст с переносом слов, т.е. текст размещается в нескольких строках (кол-во зарание не известно). Необходимо сделать так чтобы при изменении текста в item'е, если кол-во строк меняется то и высота item'а менялась. А также при изменении размеров окна было бы не плохо все размеры пересчитать. Вот пример кода что я имею на данный момент:
| Код | import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List;
public class CellRendererTest {
public static void main(String[] args) { final CellRendererTest test = new CellRendererTest();
SwingUtilities.invokeLater(new Runnable() { public void run() { test.createGui(); } }); }
public void createGui() { JFrame frame = new JFrame(); final MyListItem[] listItems = createBogusListItems(); final JList list = new JList(listItems); list.setCellRenderer(new MyListCellRenderer()); frame.getContentPane().add(new JScrollPane(list), BorderLayout.CENTER); final JButton push = new JButton("Push"); push.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for (MyListItem listItem : listItems) { listItem.description += " Test"; } list.repaint(); } }); frame.getContentPane().add(push, BorderLayout.SOUTH); frame.setSize(200, 400); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
private MyListItem[] createBogusListItems() { List<MyListItem> items = new ArrayList<MyListItem>();
items.add(new MyListItem("First item", "This is a nice short description.")); items.add(new MyListItem("Another one", "This is a longer description which might take up a couple of lines.")); items.add(new MyListItem("Next one", "This is a ridiculously long description which is total gibberish." + "Blah blah blabber jabber goo. Blither blather bonk. Oink boggle gaggle ker-plunk.")); items.add(new MyListItem("No Desc", null)); items.add(new MyListItem("Last one", "Boink!"));
return items.toArray(new MyListItem[items.size()]); }
static class MyListCellRenderer extends JPanel implements ListCellRenderer { private JLabel title; private JTextArea desc;
public MyListCellRenderer() { setLayout(new FlowLayout(FlowLayout.LEFT)); setBorder(BorderFactory.createEmptyBorder(6, 4, 6, 4)); setOpaque(true);
title = new JLabel(); title.setFont(new Font("Arial", Font.ITALIC | Font.BOLD, 11)); add(title);
desc = new JTextArea(); desc.setFont(new Font("Arial", Font.PLAIN, 9)); desc.setOpaque(false); desc.setWrapStyleWord(true); desc.setLineWrap(true); add(desc); doLayout(); }
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
MyListItem item = (MyListItem)value;
title.setText(item.title); if (item.description != null && item.description.length() > 0) { desc.setText(item.description); desc.setVisible(true); } else { desc.setVisible(false); }
// uncomment next line to to somewhat simulate the effect I want (hacked using the rows array) // desc.setRows(rows[index]);
if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } return this; }
}
static class MyListItem { String title; String description;
public MyListItem(String title, String description) { this.title = title; this.description = description; } } }
|
При нажатии на кнопку к тексту в каждом item'е добавляется слово, что приводит к изменению кол-ва строк и должно приводить к изменению высоты item'а. Так же интерестно почему при использовании BorderLayout в item'е получается неоправдано большая высота? Пример:
| Код | public MyListCellRenderer() { setLayout(new BorderLayout()); setBorder(BorderFactory.createEmptyBorder(6, 4, 6, 4)); setOpaque(true);
title = new JLabel(); title.setFont(new Font("Arial", Font.ITALIC | Font.BOLD, 11)); add(title, BorderLayout.NORTH);
desc = new JTextArea(); desc.setFont(new Font("Arial", Font.PLAIN, 9)); desc.setOpaque(false); desc.setWrapStyleWord(true); desc.setLineWrap(true); add(desc, BorderLayout.CENTER); doLayout(); }
|
Заранее благодарю всех кто откликнется. |