当前,我正在尝试添加一个与按钮一样大的图标(已添加到GridBagLayout
中)。我想将图标缩放为按钮的大小,但是我的按钮显示为0。
我尝试打印出按钮的大小(在创建按钮之后以及添加按钮之后)。它总是给我0,因此ArgumentException
(宽度(0)和高度(0)必须不为零)。
我还想动态调整字体大小,使其与按钮一样大(尚无实现,但由于按钮未给出其大小,因此它也无法正常工作)。
有人有使用LayoutManager
动态调整大小的解决方案吗?也许有一种方法可以获取像元大小,然后将图像缩放到像元大小?
这是我的测试代码:
import javax.swing.*;
import java.awt.*;
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();
setVisible(true);
} // end of public temp
public static void main(String[] args) {
new TestResize();
} // end of main
public void createLevelMenu(){
if (levelPane == null){
levelPane = new JPanel(new GridBagLayout());
gbc.fill = GridBagConstraints.NONE;
JButton back = new JButton();
back.setOpaque(false);
back.setBackground(null);
back.setBorder(null);
addObject(0,0,1,1,GridBagConstraints.FIRST_LINE_START,back);
Image img = (new ImageIcon("Content/Graphics/UI/returnIcon.png")).getImage().getScaledInstance(back.getWidth(),back.getHeight(),Image.SCALE_SMOOTH);
back.setIcon(new ImageIcon(img));
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);
}
}
答案 0 :(得分:0)
我尝试打印出按钮的大小(在创建按钮之后以及添加按钮之后)。它总是给我0,因此出现ArgumentException(宽度(0)和高度(0)必须不为零)。
是的,这有很多原因
getTopLevelAncestor()
也不可显示,则不能保证其大小! (在本例中为TestResize
对象的巫婆)所以这个概念从一开始就是错误的,即使您没有将border设置为null,其大小也将等于border insets(对于所有api边界来说,这都是紧密的!!!即使是简单的“嗨,字体大小为5 !!)。
所以在这种情况下最好的选择(但不是我所说的那样)是
back.getPreferredSize()
要使其正常工作(在您所处的情况下),您必须自行设置图像的初始大小,然后在将图标设置为按钮时,UI会为其提供额外的大小。
我还要动态调整字体大小,使其与按钮一样大
@AndrewThompson在他所写的答案中指出了一个很好的例子,而@trashgod很好的例子也都很棒!为此+1。
然后问按钮的大小,然后添加相同大小的图标?
您必须了解,在使用布局管理器时,每件事物的大小都是相对于其父项的!
举个例子
图标按钮->级别面板(女巫是内容窗格)->根窗格JLayeredPane
对象->根窗格本身->最后是框架!
一切都会根据父级大小进行调整,但是如果父级大小为0,0,那么不要期望子组件的大小会超过该值!
并且请记住,GridBagLayout
是所有布局中最复杂的,并且其行为可能很奇怪。
和
的用法component.getWidth();
//and
component.getHeight();
是要获得实际大小“ ON-THE-SCREEN”,因此返回值甚至可能与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
的话,它很简洁,而且很简单,很高兴编写代码。