У меня есть следующий сценарий - у меня есть панель, которая содержит компонент (в данном случае метку) внутри другой панели - все определяется с помощью MigLayout
.
Когда размер панели изменяется, я хочу настроитьразмер шрифта JLabel
таким образом, чтобы соответствовать всей области.
Я обрезал код до минимума
public class TestClass {
private JPanel panel;
private JLabel displayLabel;
private TestClass() {
panel = new JPanel(new MigLayout(new LC().fill().gridGap("0", "0").insetsAll("0").hideMode(3)));
displayLabel = new JLabel("some text goes here");
displayLabel.setFont(new Font("Dialog", Font.BOLD, 9));
panel.add(displayLabel, new CC().grow().push());
panel.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
scale(displayLabel);
}
});
}
private void scale(JLabel component) {
Integer lastWidth = (Integer) component.getClientProperty("width");
Integer lastHeight = (Integer) component.getClientProperty("height");
if (lastWidth != null && lastHeight != null && lastWidth == component.getWidth() && lastHeight == component.getHeight()) {
return;
}
component.putClientProperty("width", component.getWidth());
component.putClientProperty("height", component.getHeight());
int minFontSize = 9;
Font oldFont = component.getFont();
float size = oldFont.getSize();
Font newFont = oldFont.deriveFont(size);
FontMetrics fm = component.getFontMetrics(newFont);
int availWidth = component.getWidth() - 2;
int availHeight = component.getHeight() - 2;
boolean found = false;
boolean increased = false;
boolean decreased = false;
while (!found) {
int stringWidth = fm.stringWidth(component.getText());
int stringHeight = fm.getHeight();
if (!decreased && stringWidth < availWidth && stringHeight < availHeight) {
size++;
increased = true;
} else if (stringWidth > availWidth || stringHeight > availHeight) {
size--;
decreased = true;
} else {
found = true;
}
if (increased && decreased) {
found = true;
}
newFont = oldFont.deriveFont(size);
fm = component.getFontMetrics(newFont);
}
if (size < minFontSize) {
size = minFontSize;
newFont = oldFont.deriveFont(size);
}
component.setFont(newFont);
}
public JPanel getPanel() {
return panel;
}
public static void main(String[] args) {
JFrame frame = new JFrame("");
JPanel pnl = new JPanel(new MigLayout(new LC().fill()));
pnl.add(new TestClass().getPanel(), new CC().grow().push());
frame.add(pnl, BorderLayout.CENTER);
frame.setSize(1024, 700);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Когда я изменяю размер кадра, перетаскиваяправый край, чтобы увеличить его - он работает просто отлично, однако, когда я пытаюсь уменьшить его размер, перетаскивая его влево от правого края, приложение вяло и результат не сразу отражается в графическом интерфейсе.Пожалуйста, запустите его, чтобы понять, что я имею в виду.
У вас есть идеи, как я могу улучшить этот код, чтобы он работал гладко?
Обновление : я добавил некоторые записи в журнал и заметил, что при увеличении ширины он работает нормально, но при уменьшении ширины панели я вижу, что вызывается метод componentResized ()во много раз больше, чем при увеличении.
Причиной проблемы, по-видимому, является MigLayout в сочетании с grow ().Я заменил все макеты с BorderLayout и, кажется, работает нормально.
Однако в моем случае я не могу этого сделать, поскольку мне нужно, чтобы моя панель увеличивалась в макете.