Swing中JScrollPane添加JPanel设置setPreferredSize问题

panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
Dimension ds = new Dimension(100, 100);
panel.setPreferredSize(ds);
jspane.setViewportView(panel);

上面的代码是在jspane的滚动视图组件中添加一个流式布局的JPanel。然后设置一个panel的prefSize首选值。

在java api中这样解释:

setPreferredSize
public void setPreferredSize(Dimension preferredSize)设置此组件的首选大小。如果 preferredSize为 null,则要求 UI 提供首选大小。

就是说如果不提供这个值,ui会进行计算并设置这个值,这里,会根据jspane的ui来设置值。(默认的JScrollPane组件是自动添加横竖滚动条的)

panel中添加组件,默认FlowLayout布局器会进行流式布局,这里定义是左对齐。如果没有设置prefSize值,则使用根据JScrollPane组件jspane的ui自动进行计算的首选大小prefSize。而JScrollPane组件默认是会进行滚动显示,所以,如果panel中添加的组件过多导致超出了panel的宽度,JScrollPane的ui会计算一个合适的prefSize值来提供给panel组件,此时,panel的流布局会一直在同一水平方向布局,而不会换行。如下图显示:


就算取消了JScrollPane的横向滚动条,panel也不会进行换行布局,此时获取panel的prefSize也会远远大于panel的默认长宽

java.awt.Dimension[width=6845,height=110]

Component中的preferredSize()方法

  1. public Dimension preferredSize() {  
  2.         /* Avoid grabbing the lock if a reasonable cached size value 
  3.          * is available. 
  4.          */  
  5.         Dimension dim = prefSize;//获取默认prefSize  
  6.         if (dim == null || !(isPreferredSizeSet() || isValid())) {  
  7.             synchronized (getTreeLock()) {  
  8.                 prefSize = (peer != null) ?  
  9.                     peer.getPreferredSize() :  
  10.                     getMinimumSize();  
  11.                 dim = prefSize;  
  12.             }  
  13.         }  
  14.         return new Dimension(dim);  
  15.     }

此时设置panel的prefSize值,JScrollPane就不会计算panel的大小,panel的组件如果超出panel的宽度,流布局就会自动转行。
不过,这样设置的效果是,JScrollPane的竖方向也不会计算panel的大小,一旦panel的组件过多,导致超出panel的高度,滚动条也不会显示,可以手动计算panel的组件数量布局,然后设置panel的prefSize。

  1. private void resize()  
  2. {  
  3.    int nums = panel.getComponentCount();  //组件数量
  4.    //100 添加的组件长和宽, 5是流布局FlowLayout的默认组件间隔  
  5.    int h = (nums / (panel.getWidth() / (100+5))) * (100 + 5);  
  6.    panel.setPreferredSize(new Dimension(100, h)); 
  7.    //手动设置panel的首选大小,如果不需要横向滚动,width的值可以设置和前面默认一样  
  8.    updateUI();  
  9. }



  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题描述: 在Linux下运行javaswing程序时,文输入法下输入时,光标不会随着输入移动,会停留在原位置。 问题分析: 这是Linux系统下文输入法的默认行为,由于输入法引擎和Java GUI的事件处理机制不同,在输入时会出现光标不跟随的现象。 解决方案: 可以通过在程序监听键盘事件,并手动更新光标位置来解决这个问题。下面是一个示例代码: ``` import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.im.InputContext; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class InputMethodCursor extends JFrame implements KeyListener { /** * */ private static final long serialVersionUID = 1L; JTextArea inputArea; JPanel panel; public InputMethodCursor() { setTitle("Input Method Cursor"); setSize(new Dimension(400, 400)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); inputArea = new JTextArea(); inputArea.setPreferredSize(new Dimension(300, 300)); inputArea.setWrapStyleWord(true); inputArea.setLineWrap(true); inputArea.addKeyListener(this); JScrollPane scrollPane = new JScrollPane(inputArea); panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.NORTHWEST; panel.add(scrollPane, gbc); getContentPane().setLayout(new BorderLayout()); getContentPane().add(panel, BorderLayout.CENTER); setVisible(true); } @Override public void keyPressed(KeyEvent e) { if (InputContext.getInstance().getLocale().equals("zh_CN")) { Point point = inputArea.getCaretPosition(); inputArea.setText(inputArea.getText() + e.getKeyChar()); inputArea.setCaretPosition(point.x + 1); } } @Override public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } public static void main(String[] args) { new InputMethodCursor(); } } ``` 在输入法为文时,监听键盘事件,获取当前光标位置并手动更新位置。 这样就可以在Linux系统上正常使用文输入法了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值