我不明白为什么我必须设置 Component.setPreferredSize()来绘制,以及为什么我的椭圆不会放在一个地方。我还有一些其他问题,如下所述。
public class PaintPanel extends JPanel implements ActionListener
{
private void initStructure()
{
for (int i : new Range(MAX_AGENTS)) {
Agent agent = new Agent();
agents.add(agent);
add(agent);
}
}
//i want to override parent class 'add', to easy call 'actionPerformed' on children elements.
public Component add(Element comp)
{
elements.add(comp);
return super.add(comp);
}
@Override
public void actionPerformed(ActionEvent e)
{
for(Element element: elements){
element.actionPerformed(e);
}
repaint();
}
//ELEMENT is abstract class: 'public class Element extends JComponent implements ActionListener'
public class Agent extends Element
{
public Agent()
{
super();
// setPreferredSize(new Dimension(120,120)); !!!! a-a, i don't know the future size of the oval or triangle, i don't want and i can't set this :(
setVisible(true);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
System.out.println("draw"); //called
Point p1 = new Point(1, 1);
Point p2 = new Point(101, 101);
Point p3 = new Point(10, 10);
int[] xs = { p1.x, p2.x, p3.x };
int[] ys = { p1.y, p2.y, p3.y };
Polygon triangle = new Polygon(xs, ys, xs.length);
g.setColor(new Color(255,255,255)); // !! never painted
g.fillPolygon(triangle); //!! never painted
g.drawOval(10,10,10,10); // !!!! painted only when i set preferredSize
}
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("i am alive"); //working
}
}
如果我设置了首选尺寸,我得到了下面的图片。
所以
问题
1)是否有任何模式不设置首选大小并在内容中绘制组件在 contentPanel <上调用 paint() / em>的
2)为什么 g.fillPolygon 无效?
3)为什么我的 ovals 没有放在一个点上?
答案 0 :(得分:3)
问题是如果JPanel没有首选大小,并且如果它被添加到使用不填充容器的布局管理器的容器(例如FlowLayout),那么如何GUI会知道绘图JPanel应该是多大?我听说比在JPanel上调用setPreferredSize(...)
更好的是覆盖其Dimension getPreferredSize()
方法(请问kleopatra,这个网站上的Swing专家)。
关于:
为什么g.fillShape无效?
检查API - Graphics是否有fillShape方法?不。但是Graphics2D有fill(Shape s)
方法,这就是你想要的。
为什么我的椭圆不放在一个点上?
请澄清并提供详细信息。你是什么意思&#34;放在一点&#34;?你期待的是什么行为以及为什么?
编辑:您的三角形未被绘制,因为所有点都是共线!
例如:
import java.awt.*;
import javax.swing.*;
public class MyDrawingPanel extends JPanel {
private static final int PREF_W = 100;
private static final int PREF_H = PREF_W;
// private Point p1 = new Point(1, 1);
private Point p1 = new Point(30, 1);
private Point p2 = new Point(100, 101);
// private Point p3 = new Point(10, 10);
private Point p3 = new Point(50, 10);
private int[] xs = { p1.x, p2.x, p3.x };
private int[] ys = { p1.y, p2.y, p3.y };
private Polygon triangle = new Polygon(xs, ys, xs.length);
public MyDrawingPanel() {
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(255, 255, 255)); // !! never painted
g.fillPolygon(triangle); // !! never painted
g.drawOval(10, 10, 10, 10); // !!!! painted only when i set preferredSize
}
private static void createAndShowGui() {
int rows = 4;
int cols = 4;
JPanel gridPanel = new JPanel(new GridLayout(rows, cols));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
gridPanel.add(new MyDrawingPanel());
}
}
JFrame frame = new JFrame("PaintPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(gridPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
答案 1 :(得分:3)
为什么我的椭圆不会放在一个点上?
我猜您要将Agent
组件添加到JPanel中。默认情况下,JPanel使用FlowLayout
。因此,每个组件放置120个像素,并在行填充时流向新行。
我不知道椭圆形或三角形的未来大小,我不想要,我也无法设置这个
不要使用drawOval(...)方法。而是使用表示椭圆的Shape对象。然后你可以得到Shape的大小,并在@hovercraft提到的getPreferredSize()
方法中使用这个值。
查看Playing With Shapes以获取有关此概念的更多信息。当然,如果使用此概念,则需要将Shapes定义为实例变量,以便paintComponent()和getpreferredSize()方法都可以引用Shape。