我对JList的大小有点问题:
有一个带有三个JList的JFrame(每个JList都在JScrollPane中)。你可以点击一个项目添加到列表中。程序启动后,所有JList都有相同的宽度。但在填充任何列表后,他的宽度都会减少,创建的空间也会平等地添加到空列表中。
我想停止调整大小。我希望下面的代码能更好地描述我的问题。
package test;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class Test extends JFrame {
public Test() {
GroupLayout layout = new GroupLayout(this.getContentPane());
this.setLayout(layout);
JList listA = new JList(new DefaultListModel<String>());
JList listB = new JList(new DefaultListModel<String>());
JList listC = new JList(new DefaultListModel<String>());
MouseListener listener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
((DefaultListModel) ((JList) e.getSource()).getModel()).addElement("some text");
revalidate();
}
};
listA.addMouseListener(listener);
JScrollPane paneA = new JScrollPane(listA);
listB.addMouseListener(listener);
JScrollPane paneB = new JScrollPane(listB);
listC.addMouseListener(listener);
JScrollPane paneC = new JScrollPane(listC);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(paneA).addComponent(paneB).addComponent(paneC));
layout.setVerticalGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(paneA).addComponent(paneB).addComponent(paneC)));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Test test = new Test();
test.setVisible(true);
}
});
}
}
要使组件大小不变,需要使用addComponent(Component component, int min, int pref, int max)
。所以用这个替换你的代码
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(paneA, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
.addComponent(paneB, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
.addComponent(paneC, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE));
而不是这个
layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(paneA).addComponent(paneB).addComponent(paneC));
这里我使用了GroupLayout
的性质和恒定宽度的200
使其稳定。
JList
s的大小可能已调整,因为所呈现的值的大小小于首次创建时的大小。然后由布局管理器对它们进行重新布局,以满足这些新要求。
JScrollPane
、JViewport
、JList
和JList
的ListCellRenderer
之间正在进行大量复杂的工作,您不想参与其中。
相反,您希望向JList
提供关于您希望它们的大小的"提示"。
例如。。。
您可以使用JList#setPrototypeCellValue
向JList
提供有关将来将添加到列表中的值的最大大小的信息。当您有大量的值要添加时,这尤其方便,因为JList
不需要检查每一个值来确定每一行的高度和容纳这些值所需的宽度。
缺点是,您需要知道任何值可能添加的最大宽度。。。
或者,您可以使用LayoutManager
,它可以让您更好地控制组件的定位和更改方式,例如GridBagLayout
甚至MigLayout
您还应该查看JavaSwing中是否应该避免使用set(Preferred|Maximum|Minimum)Size方法?
这里有一种解决问题的方法。
JScrollPane paneA = new JScrollPane(listA);
paneA.setPreferredSize(new Dimension(paneA.getPreferredSize().height, 300));
listB.addMouseListener(listener);
JScrollPane paneB = new JScrollPane(listB);
paneB.setPreferredSize(new Dimension(paneB.getPreferredSize().height, 300));
listC.addMouseListener(listener);
JScrollPane paneC = new JScrollPane(listC);
paneC.setPreferredSize(new Dimension(paneC.getPreferredSize().height, 300));
我不熟悉GroupLayout管理器。以下文档可能提供了一种进一步控制布局的方法。http://docs.oracle.com/javase/tutorial/uiswing/layout/group.html(请参阅组件大小和可调整性)