[英]Can not draw oval on a JPanel
I have a JFrame created with GUI builder of Netbeans, which contains a JPanel only. 我有一个使用Netbeans的GUI构建器创建的JFrame,它只包含一个JPanel。 I have created a method
getPanel
for getting a reference to this JPanel: 我创建了一个方法
getPanel
来获取对这个JPanel的引用:
public class ShowDrawings extends JFrame {
public ShowDrawings() {
initComponents();
}
public JPanel getPanel(){
return panel;
}
private JPanel panel;
}
In my main function I am doing: 在我的主要功能中我正在做:
public class Main {
public static void main(String[] args){
ShowDrawings sd = new ShowDrawings();
sd.setSize(800, 600);
Graphics g = sd.getPanel().getGraphics();
g.setColor(Color.BLACK);
g.drawOval(400, 300, 50, 50);
sd.getPanel().paint(g);
sd.repaint();
sd.setVisible(true);
}
}
But it does not draw anything. 但它没有任何吸引力。 Please help me.
请帮我。 I have looked some related questions but they are all suggesting extending
JPanel
and overriding its paint
method. 我看了一些相关的问题,但他们都建议扩展
JPanel
并覆盖其paint
方法。 But I did not want to do that way. 但我不想这样做。 Thanks.
谢谢。
I have looked some related questions but they are all suggesting extending
JPanel
and overriding itspaint
method.我看了一些相关的问题,但他们都建议扩展
JPanel
并覆盖其paint
方法。 But I did not want to do that way但我不想这样做
You should not override JPanel
paint()
method, rather paintComponent(..)
. 您不应该覆盖
JPanel
paint()
方法,而应该覆盖paintComponent(..)
。 This is best practice and should be done if you want code that will not produce anomalies. 这是最佳实践,如果您希望代码不会产生异常,则应该这样做。 Also doing it in your current approach (as you have seen) makes creating persistent drawings a lot harder as they are wiped away on
repaint()
在你当前的方法中做到这一点(正如你所看到的那样)使得创建持久性绘图变得更加困难,因为它们在
repaint()
消失了repaint()
Rather extend JPanel
and override paintComponent(Graphics g)
not forgetting to call super.paintComponent(g)
as first call in overridden paintComponent(..)
method. 而是扩展
JPanel
并覆盖paintComponent(Graphics g)
不要忘记在重写的paintComponent(..)
方法中调用super.paintComponent(g)
作为第一次调用。 Also dont forget to override getPreferredSize()
of JPanel
so that we can return correct dimensions and pack()
may be called on JFrame
(+1 to @mKorbels comment): 另外不要忘记覆盖
JPanel
getPreferredSize()
,以便我们可以返回正确的维度,并且可以在JFrame
上调用pack()
(+1到@mKorbels注释):
Here is some example code: 这是一些示例代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
initComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel testPanel = new JPanel() {
@Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GREEN);
//g2d.drawOval(10,10,100,100);//I like fill :P
g2d.fillOval(10,10,100,100);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
};
frame.add(testPanel);
frame.pack();
frame.setVisible(true);
}
}
The first time you repaint()
your ShowDrawings sd
frame anything you've painted like this ( sd.getPanel().getGraphics().drawOval(...)
) would be erased by the original JPanel#paintComponent()
method. 第一次
repaint()
你的ShowDrawings sd
框架时,你所绘制的任何东西( sd.getPanel().getGraphics().drawOval(...)
)都将被原始的JPanel#paintComponent()
方法擦除。
As Andrew Thompson has written : 正如安德鲁汤普森所写 :
Do not use Component.getGraphics().
不要使用Component.getGraphics()。 Instead, subclass and override the paint() (AWT), or paintComponent() (Swing) method.
相反,子类和覆盖paint()(AWT)或paintComponent()(Swing)方法。
Component.getGraphics() simply can't work.
Component.getGraphics()根本无法工作。 Java uses a callback mechanism for drawing graphics.
Java使用回调机制绘制图形。 You are not supposed to "push" graphics information into a component using getGraphics().
您不应该使用getGraphics()将图形信息“推送”到组件中。 Instead you are supposed to wait until Java calls your paint()/paintComponent() method.
相反,你应该等到Java调用你的paint()/ paintComponent()方法。 At that moment you are supposed to provide the Component with the drawings you would like to do.
那时你应该为Component提供你想要做的图纸。
If you're just checking/debugging something you could even do something like this: 如果您只是检查/调试某些内容,您甚至可以执行以下操作:
class Test {
private JPanel panel = new JPanel() {
public void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.drawOval(400, 300, 50, 50);
}
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.