开发者

Adjusting JScrollPane according to the JPanel inside it

I have a class which extends JPanel,and it is placed inside a JScrollPane. As you can see from the code that I am zooming in and out of the panel using the mouse wheel.so far so good. But how to make the ScrollPane adjust itself accordingly? I have overridden the getPreferredSize() of the JPanel thinking that it is used by JScrollPane to adjust its size.But now when I run the program, I can do the zoom in zoom out everything but the scrollpane doesn't appear. Just for information, I have a JFrame in which I have the JScrollPane. From the JFrame I create an object of the SimPanel class shown above, and add it into the JscrollPane.

EDIT: *The following classes put together will compile and run and show the problem.*

The following is the JFrame class:

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()
开发者_Go百科                .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);
            }
        });
    } 
}

And the following is the SimPanel class:

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();
    }
}

you can get the swing worker class from here: http://java.sun.com/products/jfc/tsc/articles/threads/src/SwingWorker.java


Your panel needs to implement Scrollable. I always forget the exact details of what to set for each method in Scrollable but I think you want getPreferredScrollableViewportSize to return the dimension of what you want visible at any given time


You can try adding:

revalidate();
repaint();

When you change the scale. Otherwise I don't think the scrollpane knows that the panel has changed.

If you need more help post your SSCCE.

Edit:

That is NOT a SSCCE! What do the menus have to do with the scroll wheel problem? What do the buttons and text field have to do with the problem? Only post code relevant to the problem, we don't have time to look at unecessary code.

Where is the revalidate() code I suggested that you add?

Why did you comment out the getPreferredSize() method? You need the preferred size to change if you want scrollbars to appear as required.

The problem with your code is the the preferred size makes no sense. The width was -3 when I tested it. So your code to create the SimPanel is wrong. I hdardocde the values 300, 300 as parameters for the SimPanel. I also used:

        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;
        }

for my quick test and it worked fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜