【问题标题】:setPreferredSize changed after the fact but GridBagLayout not updatingsetPreferredSize 事后发生了变化,但 GridBagLayout 没有更新
【发布时间】:2014-11-30 23:38:35
【问题描述】:

我有一个显示图像的 JPanel (imagePanel)。我在另一个 JPanel (scrollPanel) 中有 imagePanel,并带有 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();
}

【问题讨论】:

标签: java swing resize layout-manager gridbaglayout


【解决方案1】:

不要调用 setPreferredSize()。

你应该重写你的类的getPreferredSize() 方法来进行大小计算。所以基本上缩放逻辑应该在那个方法中定义。

然后在你调用的 zoom(..) 方法中:

revalidate();
repaint();

zoom() 方法应该是绘制图像的面板的一部分,因为缩放系数是该面板的一个属性。这将导致布局管理器被调用,并且您的新首选尺寸将用于组件的布局。

此外,您应该重写 paintComponent(...) 方法,而不是绘制图像的 paint(...) 方法。

【讨论】:

    【解决方案2】:

    根据此链接:http://www.coderanch.com/t/333435/GUI/java/Whats-exact-difference-paint-repaint 调用 setPreferedSize 后可能需要调用 validate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 2021-09-20
      • 2019-09-23
      • 2021-11-14
      相关资源
      最近更新 更多