setPreferredSize изменился после факта, но GridBagLayout не обновляется

У меня есть JPanel (imagePanel), на котором отображается изображение. У меня есть imagePanel внутри другого JPanel (scrollPanel) с ограничениями по умолчанию GridBagLayout для его центрирования. scrollPanel - это область просмотра для JScrollPane. Мне нужно изменить размер imagePanel постфактум и по-прежнему держать его в центре. (Класс изображения - это то, что я сделал сам)

public class ImageView extends View {
private static final long serialVersionUID = -1745026846891845769L;

private JScrollPane scrollPane;
private JPanel scrollPanel;
public JPanel imagePanel;

public int zoom = 1;

public Image image;

public ImageView(Image image) {
    setLayout(new BorderLayout());
    setDoubleBuffered(true);

    this.image = image;

    imagePanel = new JPanel() {
        private static final long serialVersionUID = 2127374649591395224L;

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            ImageView.this.image.paintImage(g, 0, 0, zoom);
        }
    };
    imagePanel.setDoubleBuffered(true);

    scrollPanel = new JPanel(new GridBagLayout());
    scrollPanel.add(imagePanel);

    scrollPane = new JScrollPane(scrollPanel);
    add(scrollPane, BorderLayout.CENTER);
}

public void zoom(int zoom) {
    if(zoom < 1) 
        this.zoom = 1;
    else
        this.zoom = zoom;

    int imageWidth = image.WIDTH * this.zoom;
    int imageHeight = image.HEIGHT * this.zoom;

    imagePanel.setPreferredSize(new Dimension(imageWidth, imageHeight));
    //What do I do here???
}

РЕДАКТИРОВАТЬ: вот мой обновленный код для всех, у кого есть тот же вопрос

public class ImageView extends View {
private static final long serialVersionUID = -1745026846891845769L;

public class ImagePanel extends JPanel {
    private static final long serialVersionUID = 2127374649591395224L;

    public int zoom = 1;

    public void setZoom(int zoom) {
        if(zoom < 1) 
            this.zoom = 1;
        else
            this.zoom = zoom;
    }

    @Override
    public Dimension getPreferredSize() {
        int imageWidth = ImageView.this.image.WIDTH * this.zoom;
        int imageHeight = ImageView.this.image.HEIGHT * this.zoom;
        return new Dimension(imageWidth, imageHeight);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        ImageView.this.image.paintImage(g, 0, 0, zoom);
    }

}

private JScrollPane scrollPane;
private JPanel scrollPanel;
public ImagePanel imagePanel;

public Image image;

public ImageView(Image image) {
    setLayout(new BorderLayout());
    setDoubleBuffered(true);

    this.image = image;

    imagePanel = new ImagePanel();
    imagePanel.setDoubleBuffered(true);

    scrollPanel = new JPanel(new GridBagLayout());
    scrollPanel.add(imagePanel);

    scrollPane = new JScrollPane(scrollPanel);
    add(scrollPane, BorderLayout.CENTER);
}

public void zoom(int zoom) {
    imagePanel.setZoom(zoom);
    scrollPanel.revalidate();
    scrollPanel.repaint();
}

person 707090    schedule 30.11.2014    source источник


Ответы (2)


Не вызывайте setPreferredSize ().

Вы должны переопределить метод getPreferredSize() вашего класса, чтобы выполнить расчет размера. Таким образом, логика масштабирования должна быть определена в этом методе.

Затем в вызываемом методе zoom (..):

revalidate();
repaint();

Метод zoom() должен быть частью панели, которая рисует изображение, поскольку коэффициент масштабирования является свойством этой панели. Это приведет к вызову менеджера компоновки, и ваш новый предпочтительный размер будет использован в компоновке компонента.

Кроме того, вы должны переопределить метод paintComponent(...), а не метод paint (...) для рисования изображения.

person camickr    schedule 30.11.2014

По этой ссылке: http://www.coderanch.com/t/333435/GUI/java/Whats-exact-difference-paint-repaint вам может потребоваться вызвать проверку после вызова setPreferSize

person Zack Newsham    schedule 30.11.2014