2011-07-07 42 views
1

我有一个扩展JPanel的类,它放在JScrollPane中。从代码中可以看到,我使用鼠标滚轮放大和缩小面板,效果非常好。但是如何让ScrollPane相应地调整自己?我重写了JPanel的getPreferredSize(),它认为它被JScrollPane用来调整它的大小。但是现在当我运行该程序时,我可以缩放所有内容,但不显示滚动窗格。仅供参考,我有一个JFrame,其中包含JScrollPane。从JFrame创建上面显示的SimPanel类的对象,并将其添加到JscrollPane中。根据其中的JPanel调整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

+1

请提供[sscce](http://sscce.org/)。 – trashgod

+0

@trashgod我按问题进行了更新,提供了一个简短的,自包含的示例,它显示了问题。它将编译并运行。 – aps

+0

您不需要'javax.swing.SwingUtilities.SwingWorker'。 – trashgod

回答

1

您的面板需要实现Scrollable。我总是忘了什么就在滚动每种方法设置的具体细节,但我想你想getPreferredScrollableViewportSize在任何给定时间内返回的,你想看到什么样的尺寸

1

你可以尝试添加:

revalidate(); 
repaint(); 

当你改变比例。否则,我不认为该scrollpane知道该面板已更改。

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

编辑:

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

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

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

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

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

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

+0

我已更新了问题以提供一个简短的自我包含显示问题的例子,它会编译并运行。 – aps

+0

@aps,请参阅编辑。 – camickr

+0

实际上我减少了很多代码,但仍然保留了一些不必要的代码。对不起。我曾使用过revalidate();但它似乎没有任何区别。无论如何,我会再次尝试与您的上述建议。你在getPreferredSize()中使用了什么? – aps