根据里面的JPanel调整JScrollPane

时间:2011-07-07 18:03:16

标签: java swing jscrollpane

我有一个扩展JPanel的类,它放在JScrollPane中。正如你从代码中看到的那样,我正在使用鼠标滚轮放大和缩小面板。这太好了。但是如何使ScrollPane相应地调整自己?我已经覆盖了JPanel的getPreferredSize(),认为它被JScrollPane用来调整它的大小。但是现在当我运行程序时,我可以放大缩小所有内容但滚动窗格不会出现。仅供参考,我有一个JFrame,我有JScrollPane。从JFrame中我创建了一个上面显示的SimPanel类的对象,并将其添加到JscrollPane中。

编辑: * 以下课程将汇编并运行并显示问题。 *

以下是JFrame类:

package gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;


import javax.swing.JFrame;
import javax.swing.JScrollBar;

public class MyJFrame extends JFrame{
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;  
    public MyJFrame() {
        initComponents();
    }
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jTextField1 = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jTextField2 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();        
        jPanel2 = new SimPanel(jScrollPane1.getViewportBorderBounds().getHeight(),jScrollPane1.getViewportBorderBounds().getWidth());
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();
        JScrollBar hScrollBar;
        JScrollBar vScrollBar;
        final SwingWorker worker = new SwingWorker() {
               public Object construct() {
                   for(;;){                                        
                       repaint();
                   }
               }               
            };

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("");

        jLabel2.setText("");

        jButton1.setText("START");

        jButton2.setText("USELESS");

        jButton1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                worker.start();             
                repaint();              
            }
        });
        jButton2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){        
                repaint();              
            }
        });
        hScrollBar=jScrollPane1.getHorizontalScrollBar();
        vScrollBar=jScrollPane1.getVerticalScrollBar();

        hScrollBar.addAdjustmentListener(new AdjustmentListener(){
            public void adjustmentValueChanged(AdjustmentEvent ae1){
                repaint();
            }
        });
        vScrollBar.addAdjustmentListener(new AdjustmentListener(){
            public void adjustmentValueChanged(AdjustmentEvent ae2){
                repaint();
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jTextField2)
                    .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addContainerGap(14, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton2))
                .addContainerGap(568, Short.MAX_VALUE))
        );

        jPanel2.setPreferredSize(new java.awt.Dimension(5000, 5000));

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 5000, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 5000, Short.MAX_VALUE)
        );

        jScrollPane1.setViewportView(jPanel2);

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 858, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 631, Short.MAX_VALUE)
        );

        pack();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MyJFrame().setVisible(true);
            }
        });
    } 
}

以下是SimPanel类:

package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Random;

import javax.swing.JPanel;

public class SimPanel extends JPanel implements MouseWheelListener{
    Dimension area;
    double height,width;
    double scale=0.5;
    private static Random rand=new Random();
    public SimPanel(double h, double w) {       
        height=h;
        width=w;
        addMouseWheelListener(this);
    }
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d;
        g2d=(Graphics2D)g.create();
        g2d.translate(width/2, height/2);
        g2d.scale(scale, scale);
        g2d.translate(-width/2, -height/2);
        g2d.setColor(Color.GREEN);
        g2d.drawLine(5000, 0, 5000, 5000);
        g2d.drawLine(0, 5000, 5000, 5000);
        g2d.drawLine(0, 0, 0, 5000);
        g2d.drawLine(0, 0, 5000, 0);
        area=new Dimension((int)width,(int)height);     
        for(int i=0;i<100;i++){
            g2d.fillRect(rand.nextInt(5000), rand.nextInt(5000), 100, 100);         
        }
        g2d.setColor(Color.RED);
        for(int i=0;i<100;i++){
            g2d.fillRect(rand.nextInt(5000), rand.nextInt(5000), 100, 100);
        }
        g2d.dispose();
    }
    /*@Override
    public Dimension getPreferredSize(){
        return new Dimension((int)(width*scale) , (int)(height*scale));
    }*/
    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        if(e.getWheelRotation()<0){
            scale=scale>=1.0?1.0:scale+0.05;
        }
        else if(e.getWheelRotation()>0){
            scale=scale<=0.1?0.1:scale-0.05;
        }
        repaint();
    }
}

你可以从这里获得摇摆工人班: http://java.sun.com/products/jfc/tsc/articles/threads/src/SwingWorker.java

2 个答案:

答案 0 :(得分:1)

您的面板需要实现Scrollable。我总是忘记在Scrollable中为每个方法设置的内容的确切细节,但我认为你希望getPreferredScrollableViewportSize返回你想要在任何给定时间看到的内容的维度

答案 1 :(得分:1)

您可以尝试添加:

revalidate();
repaint();

更改比例时。否则我不认为滚动窗格知道面板已经改变。

如果您需要更多帮助,请发布您的SSCCE。

编辑:

那不是SSCCE!菜单与滚轮问题有什么关系?按钮和文本字段与问题有什么关系?只发布与问题相关的代码,我们没有时间查看不必要的代码。

revalidate()代码在哪里我建议您添加?

为什么要注释掉getPreferredSize()方法?如果要根据需要显示滚动条,则需要更改首选大小。

您的代码的问题是首选大小没有意义。我测试时宽度为-3。所以你创建SimPanel的代码是错误的。我将值300,300作为SimPanel的参数进行了hdardoc。我也用过:

        if(e.getWheelRotation()<0){
//            scale=scale>=1.0?1.0:scale+0.05;
            scale += 0.05;
        }
        else if(e.getWheelRotation()>0){
//            scale=scale<=0.1?0.1:scale-0.05;
            scale -= -0.05;
        }

我的快速测试,它工作正常。