Настройка JScrollPane в соответствии с JPanel внутри него - PullRequest
1 голос
/ 07 июля 2011

У меня есть класс, который расширяет JPanel, и он находится внутри JScrollPane.Как видно из кода, я увеличиваю и уменьшаю масштаб панели с помощью колесика мыши. Пока все хорошо.Но как заставить ScrollPane настроить себя соответственно?Я переопределил getPreferredSize () для JPanel, думая, что он используется JScrollPane для настройки его размера. Но теперь, когда я запускаю программу, я могу делать масштабирование, уменьшая все, но область прокрутки не появляется.Просто для информации, у меня есть JFrame, в котором у меня есть JScrollPane.Из JFrame я создаю объект класса SimPanel, показанный выше, и добавляю его в JscrollPane.

EDIT: * Следующие вместе собранные классы будут компилироваться, выполняться и показыватьсяпроблема. *

Ниже приведен класс 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 ]

1 голос
/ 08 июля 2011

Вы можете попробовать добавить:

revalidate();
repaint();

Когда вы меняете масштаб. В противном случае я не думаю, что панель прокрутки знает, что панель изменилась.

Если вам нужна дополнительная помощь, опубликуйте свой SSCCE.

Edit:

Это НЕ SSCCE! Какое отношение меню имеет к проблеме с колесом прокрутки? Какое отношение к проблеме имеют кнопки и текстовое поле? Только почтовый индекс, соответствующий проблеме, у нас нет времени, чтобы посмотреть ненужный код.

Где код revalidate (), который я предложил добавить?

Почему вы закомментировали метод getPreferredSize ()? Вам нужно изменить предпочтительный размер, если вы хотите, чтобы полосы прокрутки отображались по мере необходимости.

Проблема с вашим кодом в том, что предпочтительный размер не имеет смысла. Ширина была -3, когда я проверял это. Так что ваш код для создания SimPanel неверен. Я hdardocde значения 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;
        }

для моего быстрого теста, и он работал нормально.

1 голос
/ 07 июля 2011

На вашей панели должен быть реализован Scrollable.Я всегда забываю точные детали того, что нужно установить для каждого метода в Scrollable, но я думаю, что вы хотите, чтобы getPreferredScrollableViewportSize возвращал измерение того, что вы хотите видеть в любой момент времени

...