所以,我正在使用Swing在Java中开发一个拖放式的可视化设计器。
由于您在设计器上看到的组件不是实际组件,只有可视化表示(例如按钮无法单击,文本字段无法接受文本等)我直接在我的面板上绘制它们,覆盖方法getX()
,getY()
,getWidth()
和getHeight()
。
除了WindowsLookAndFeel之外,它在任何LookAndFeel上都能正常工作。在那里,由于某种原因,JButtons的背景没有被绘制。我必须为设计人员使用Windows LookAndFeel,因为这是我们软件的部署方式,如果我使用不同的LookAndFeel,设计师布局将与我们的软件不同。
我已经失去了几个小时试图解决这个问题,我怀疑它正在发生,因为没有在容器上添加JButton,它的本地对等体尚未实例化。我试图手动创建对等,但没有成功。
我在Windows 7(使用Aero)和Windows 8上注意到了这个问题。如果我在Windows 7上使用经典主题它可以工作,所以我认为它也适用于Windows XP(但我没有测试过这个)。我正在使用Java 1.7.0_25-b17对此进行测试。
以下是我为展示问题所做的一个示例:
package test;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestSwing {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { }
JFrame f = new JFrame();
f.setSize(300, 150);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.X_AXIS));
JPanel p1 = new JPanel();
p1.setPreferredSize(new Dimension(150, 150));
p1.setBorder(BorderFactory.createLineBorder(Color.yellow));
p1.add(new JButton("Test"));
f.add(p1);
final MyButton b = new MyButton();
b.addNotify();
JPanel p2 = new JPanel() {
@Override
public void paint(Graphics g) {
super.paint(g);
b.paint(g);
}
};
p2.setPreferredSize(new Dimension(150, 150));
p2.setBorder(BorderFactory.createLineBorder(Color.red));
f.add(p2);
f.setVisible(true);
}
private static class MyButton extends JButton {
public MyButton() {
super("Test");
}
@Override
public int getWidth() {
return 70;
}
@Override
public int getHeight() {
return 25;
}
}
}
以下是使用WindowsLookAndFeel的示例:
这里有MetalLookAndFeel:
答案 0 :(得分:1)
作为一种潜在的解决方案。您可以使用类似Screen Image的类来创建按钮的图像。然后只需在JLabel上显示一个图标,你将拥有一个可以拖拽的真实组件。
答案 1 :(得分:0)
好的,我找到了它,感谢你的消化@camickr。
我所要做的就是在绘画之前打电话给setSize(int width, int height)
。查看组件源代码,我在resize
方法(由setSize
调用)中找到了这个代码:
setBoundsOp(ComponentPeer.SET_SIZE);
我假设这个命令告诉本机组件它的大小已经改变,并且没有调用它实际上正在绘制背景,但是大小为0x0。
现在,我不是创建一个MyButton类并重写getWidth()
和getHeight()
方法,而是我要做的就是:
final JButton b = new JButton("Test");
b.setSize(70, 25);
还在我的JPanel上画它。