Я пытался распечатать размер кнопки (после ее создания, а также после добавления). Это всегда дает мне 0 и, следовательно, ArgumentException (width (0) и height (0) должны быть ненулевыми).
да, это было бы по многим причинам
- контейнер не проверен
- , даже если подтверждено, их размер не является гарантией, пока его возвращаемое значение
getTopLevelAncestor()
не отображается! (ведь в этом случае ваш TestResize
объект)
- установка границы в null делает половину того, чтобы ваша кнопка достигла размера 0,0, так как первый надежный вызов для размера - это предпочтительный размер, и когда он не содержит содержимого и даже вставок (вставки границ) пользовательский интерфейс даст ему 0,0, так как он полностью пуст!
так что концепция была неправильной с самого начала, и даже если вы не сделали границу нулевой, размер будет равен вставкам границы (и для всех границ API, которые жесткие !!! даже для равнины " привет "с размером шрифта 5 !!!).
так что ваша лучшая ставка в такой ситуации (но не вашей, как я уже говорил) - это позвонить
back.getPreferredSize()
для того, чтобы это работало (в вашей ситуации), вы должны сделать начальный размер изображения самим, а затем при установке значка на кнопку пользовательский интерфейс придаст ему дополнительный размер.
Также я хочу динамически изменять размер шрифта до размера кнопки
@ Эндрю Томпсон указал на замечательные примеры в этом ответе, который он написал, и @trashgod хорошие примеры, все они потрясающие !! +1 за это.
<ч />
Редактировать
После этого спросите у кнопок его размер, а затем добавьте значок с таким же размером?
Вы должны понимать, что при использовании менеджеров компоновки каждый размер вещи относительно ее родителя !!
для вашего примера
кнопка со значком -> панель уровня (с панелью содержимого) -> корневая панель JLayeredPane
объект -> корневая панель сама -> наконец, рамка !!
размер каждой вещи изменяется в зависимости от родительского размера, но если в случае родительского размера 0,0, не ожидайте, что подкомпонент получит больше, чем это !!
и просто помните, что GridBagLayout
- самый сложный из всех макетов, и он может вести себя странным образом.
и использование
component.getWidth();
//and
component.getHeight();
- получить реальный размер «НА ЭКРАНЕ», возврат которого может быть даже не связан с getSize()
или другими (максимум, минимум).
так что лучший способ получить значок такого же размера, как вы должны сделать
ComponentListener
Значок того же размера
это плохая идея, потому что, если у L & F есть вставки по умолчанию для кнопки, вы дадите ей больше, чем нужно !!
и с ComponentListener
вы получите анимацию изменения размера !!
вот реорганизованная версия вашего класса,
ComponentAdapter
является реализацией интерфейса ComponentListener
, который реализует каждый метод пустым способом, я использую его, поэтому мне не нужно реализовывать все остальные методы тоже.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import mdlaf.utils.MaterialImages;
public class TestResize extends JFrame {
private Container cp;
private JPanel levelPane;
private GridBagConstraints gbc = new GridBagConstraints();
public TestResize() {
super();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 200;
int frameHeight = 200;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
setTitle("temp");
setResizable(false);
cp = getContentPane();
cp.setLayout(new BorderLayout());
createLevelMenu();
GridBagLayout gbl = (GridBagLayout) levelPane.getLayout();
gbc = gbl.getConstraints(back);
gbc.fill = GridBagConstraints.BOTH;
levelPane.remove(back);
levelPane.add(back, gbc);
back.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
//here you can add an image relative to the new size !!
if (back.getIcon() == null) {
fixIcon();
} else if (back.getIcon().getIconHeight() != back.getHeight() - heightPadding || back.getIcon().getIconWidth() != back.getWidth() - widthPadding) {
fixIcon();
}
}
});
setVisible(true);
} // end of public temp
private int widthPadding;
private int heightPadding;
private void fixIcon() {
Image img = (new ImageIcon(MaterialImages.BACK_ARROW)).getImage().getScaledInstance(back.getWidth() - widthPadding, back.getHeight() - heightPadding, Image.SCALE_SMOOTH);
back.setIcon(new ImageIcon(img));
}
public static void main(String[] args) {
new TestResize();
} // end of main
JButton back;
public void createLevelMenu() {
if (levelPane == null) {
levelPane = new JPanel(new GridBagLayout());
gbc.fill = GridBagConstraints.NONE;
back = new JButton();
back.setOpaque(false);
back.setBackground(null);
back.setBorder(null);
addObject(0, 0, 1, 1, GridBagConstraints.FIRST_LINE_START, back);
JPanel menu = new JPanel(new BorderLayout());
menu.setBackground(Color.RED);
JLabel l = new JLabel("Demo");
l.setFont(l.getFont().deriveFont(30)); //Font Size as big as Possible (adjust
l.setHorizontalAlignment(SwingConstants.CENTER);
l.setVerticalAlignment(SwingConstants.CENTER);
menu.add(l, BorderLayout.CENTER);
gbc.fill = GridBagConstraints.BOTH;
addObject(2, 2, 1, 4, GridBagConstraints.CENTER, menu);
JButton info = new JButton("Info");
addObject(3, 3, 1.25f, 1.25f, GridBagConstraints.LAST_LINE_END, info);
cp.add(levelPane, BorderLayout.CENTER);
}
}
public void addObject(int gridX, int gridY, double weightX, double weightY, int anchor, JComponent comp) {
gbc.gridx = gridX;
gbc.gridy = gridY;
gbc.weightx = weightX;
gbc.weighty = weightY;
gbc.anchor = anchor;
levelPane.add(comp, gbc);
}
}
widthPadding
и heightPadding
- это общее количество вставок L & F для кнопок, я не могу вам помочь с этим, вы должны сделать это самостоятельно, это зависит от L & F.
но для взлома вы можете изменить метод componentResized
на этот (я не рекомендую это)
public void componentResized(ComponentEvent e) {
//here you can add an image relative to the new size !!
if (back.getIcon() == null) {
back.removeComponentListener(this);
fixIcon();
}
Я уже видел этот пример, но нахожу его немного сложным, поэтому я подумал, что, возможно, есть лучшее (более простое) решение.
к сожалению, я так не думаю, но ответ @AndrewThompson, кажется, легко выучить, я бы изучил, что если я захочу начать читать о GlyphVector
, это аккуратно и просто, и приятное кодирование.