Почему я должен вызывать setBounds дважды, чтобы он работал - PullRequest
0 голосов
/ 06 марта 2019

Как часть приложения, которое я пишу, я изменяю размеры и перемещаю изображение поддона в JLabel. Поскольку JLabel находится в JLayeredPane, я не использую менеджер макетов, и в результате каждый раз, когда меняю размер значка palletLabel, я использую setBounds(), чтобы контролировать его размеры и местоположение на странице. Изображение того, как это выглядит ниже:

enter image description here

Код, который управляет тем, что происходит, когда размер поддона изменяется, вызывается каждый раз, когда изменяются размеры (указанные JSpinners, которые можно увидеть слева). Размер palletLabel ниже:

private void resizePalletImage(int[] size)
{
    Dimension dim = calculatePalletImageSize(size[1], size[0]);
    palletImage = ResizeImage.scaleImageByAbsoluteValues(originalPalletImage, dim);
    ImageIcon icon = new ImageIcon(palletImage);
    palletLabel.setIcon(icon);
    layerPanelHeight = layerCenterPanel.getHeight();
    //Have to set this twice, as the length hasn't "updated" by the time the first setBounds is called. Weird.
    palletLabel.setBounds(0, layerPanelHeight - palletLabel.getHeight(), icon.getIconWidth(), icon.getIconHeight());
    palletLabel.setBounds(0, layerPanelHeight - palletLabel.getHeight(), icon.getIconWidth(), icon.getIconHeight());
}
  • originalPalletImage - копия исходного изображения с высоким разрешением, которая используется для предотвращения размытия после большого размера изображения.
  • ResizeImage.scaleImageByAbsoluteValues - статический метод, используемый для изменения размера изображения. Он просто вызывает Image.getScaledInstance после нескольких вычислений.
  • layerCenterPanel - это JLayeredPane, на котором сидит panelLabel.

Как видно, я звоню setBounds() дважды в конце. Первоначально он был вызван только один раз, и он изменил размер palletLabel, но он не использовал значения, которые были только что установлены ранее в методе, а скорее предыдущие значения, и изображение поддона плавало там, где оно не должно (как использовалось предыдущее значение для palletLabel.getHeight()). Другими словами, метод работал как задумано, но всегда был на одну итерацию позади. Я решил это, просто дважды позвонив setBounds(), и теперь он работает точно так, как задумано. Мне просто интересно, почему это необходимо, я попытался поместить setBounds() в invokeLater, но это не дало эффекта.

Любые входные данные приветствуются, Спасибо.

...