Как часть приложения, которое я пишу, я изменяю размеры и перемещаю изображение поддона в JLabel
. Поскольку JLabel
находится в JLayeredPane
, я не использую менеджер макетов, и в результате каждый раз, когда меняю размер значка palletLabel, я использую setBounds()
, чтобы контролировать его размеры и местоположение на странице. Изображение того, как это выглядит ниже:
Код, который управляет тем, что происходит, когда размер поддона изменяется, вызывается каждый раз, когда изменяются размеры (указанные 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
, но это не дало эффекта.
Любые входные данные приветствуются,
Спасибо.