Java MigLayout限制JScrollPane上JList的滚动
我有一个GUI,它由一个面板上的多个JList组件组成,该面板位于JScrollPane上。滚动窗格可以一次滚动所有列表。但是,当我在包含列表的面板上使用MigLayout时,我无法滚动通过前1819个列表元素。限制似乎与列表的高度有关,而不是与元素的数量有关。如果我使用较大的元素大小,我可以滚动较少的元素。我目前正在使用MigLayout 4.2 下面是一个显示这种行为的简化示例Java MigLayout限制JScrollPane上JList的滚动,java,swing,jscrollpane,jlist,miglayout,Java,Swing,Jscrollpane,Jlist,Miglayout,我有一个GUI,它由一个面板上的多个JList组件组成,该面板位于JScrollPane上。滚动窗格可以一次滚动所有列表。但是,当我在包含列表的面板上使用MigLayout时,我无法滚动通过前1819个列表元素。限制似乎与列表的高度有关,而不是与元素的数量有关。如果我使用较大的元素大小,我可以滚动较少的元素。我目前正在使用MigLayout 4.2 下面是一个显示这种行为的简化示例 import net.miginfocom.swing.MigLayout; import javax.swin
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
public final class MigLayoutListTest {
public static void main(final String... args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final String[] listData = new String[5000];
for (int i = 0; i < 5000; i++) {
listData[i] = "Index " + i;
}
final JPanel panel = new JPanel(new MigLayout());
panel.add(new JList(listData));
final JFrame frame = new JFrame();
frame.setContentPane(new JScrollPane(panel));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(600, 400));
frame.pack();
frame.setVisible(true);
}
});
}
}
import net.miginfocom.swing.migloayout;
导入javax.swing.*;
导入java.awt.*;
公共最终类MigLayoutListTest{
公共静态void main(最终字符串…参数){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
最终字符串[]listData=新字符串[5000];
对于(int i=0;i<5000;i++){
listData[i]=“索引”+i;
}
最终JPanel面板=新的JPanel(新的MigLayout());
panel.add(新JList(listData));
最终JFrame=新JFrame();
frame.setContentPane(新的JScrollPane(面板));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(新尺寸(600400));
frame.pack();
frame.setVisible(true);
}
});
}
}
如果我删除JPanel并将JList直接放在JScrollPane上,那么滚动就可以正常工作,但是我不能使用这种解决方法,因为我需要在同一个JScrollPane上有多个列表。如果我对JPanel使用MigLayout以外的任何布局,那么滚动就可以正常工作
这是MigLayout的缺陷还是限制?是否有一些配置选项需要应用于MigLayout以使其正常工作?我认为您的方法很笨拙。相反,在自己的JScrollPane中使用JLists并同步滚动:
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class ScrollingDemo implements Runnable
{
public static void main(String args[])
{
SwingUtilities.invokeLater(new ScrollingDemo());
}
public void run()
{
JScrollPane sp1 = new JScrollPane(getJList(1));
sp1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JScrollPane sp2 = new JScrollPane(getJList(3));
sp2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JScrollBar sBar1 = sp1.getVerticalScrollBar();
JScrollBar sBar2 = sp2.getVerticalScrollBar();
// synchronize:
sBar2.setModel(sBar1.getModel());
JPanel p = new JPanel(new GridLayout(1,2));
p.add(sp1);
p.add(sp2);
JFrame frame = new JFrame("Synch Scrolling");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public JList getJList(int factor)
{
Vector<String> items = new Vector<String>();
for(int i = 0; i < 5000; i++)
{
items.add(Integer.toString((i+1)*factor));
}
JList list = new JList(items);
list.setPrototypeCellValue("XXXXXXXXXX");
list.setVisibleRowCount(10);
return list;
}
}
这是一个巧妙的技巧,在本例中效果很好,不幸的是,我使用的列表有不同数量的元素,我必须将GUI限制为一个滚动条。我认为这是MigLayout 4.2中的一个bug,并在多台机器上进行了测试,得到了相同的结果。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ScrollingDemo2 implements Runnable
{
public static void main(String args[])
{
SwingUtilities.invokeLater(new ScrollingDemo2());
}
public void run()
{
JScrollPane sp1 = new JScrollPane(getJList(100));
sp1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
JScrollPane sp2 = new JScrollPane(getJList(200));
sp2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// synchronize:
sp2.getVerticalScrollBar().addAdjustmentListener(new Synchronizer(sp1, sp2));
JPanel p = new JPanel(new GridLayout(1,0));
p.add(sp1);
p.add(sp2);
JFrame frame = new JFrame("Synch Scrolling 2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public JList getJList(int count)
{
Vector<String> items = new Vector<String>();
for(int i = 0; i < count; i++)
{
items.add(Integer.toString(i+1));
}
JList list = new JList(items);
list.setPrototypeCellValue("XXXXXXXXXX");
list.setVisibleRowCount(10);
return list;
}
class Synchronizer implements AdjustmentListener
{
JScrollPane sp1, sp2;
public Synchronizer(JScrollPane sp1, JScrollPane sp2)
{
this.sp1 = sp1;
this.sp2 = sp2;
}
public void adjustmentValueChanged(AdjustmentEvent e)
{
if (! e.getValueIsAdjusting())
{
return;
}
JScrollBar vert1 = sp1.getVerticalScrollBar();
JScrollBar vert2 = sp2.getVerticalScrollBar();
int range1 = vert1.getMaximum() - vert1.getMinimum() -
vert1.getModel().getExtent();
int range2 = vert2.getMaximum() - vert2.getMinimum() -
vert2.getModel().getExtent();
float percent2 = (float) (vert2.getValue()) / range2;
int newVal1 = (int) (percent2 * range1);
vert1.setValue(newVal1);
}
}
}