我正在编写一个Java程序,该程序将根据按下的按钮绘制一个圆形或矩形。虽然确实绘制了给定的形状,但在绘制时会在窗口的左上角(最有可能是((0,0)))创建新按钮。我是否违反了paint()/ repaint()的某些规则?
这是我的课程:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Components extends JPanel implements ActionListener
{
String em="Nothing";
public Components()
{
JButton c=new JButton("Rectangle");
JButton b=new JButton("Circle");
b.addActionListener(this);
c.addActionListener(this);
add(c, 0);
add(b, 1);
setBackground(Color.WHITE);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Rectangle"))
{
em="Rectangle";
repaint();
}
else
{
em="Circle";
repaint();
}
}
public void paint(Graphics g)
{
if(em.equals("Rectangle"))
{
g.drawRect(50, 50, 50, 50);
}
else if(em.equals("Circle"))
{
g.drawOval(50, 50, 50, 50);
}
}
}
以及不太重要的JFrame类:
import java.awt.Graphics;
import javax.swing.JFrame;
public class Wndw extends JFrame
{
public Wndw()
{
setTitle("Hello");
setSize(400, 400);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(new Components());
}
public static void main (String [] args)
{
new Wndw();
}
}
答案 0 :(得分:2)
repaint
与(很少)有关,而与您违反绘画程序的一切有关
首先查看Performing Custom Painting和Painting in AWT and Swing,以详细了解绘画的工作原理。
paint
通过调用paintComponent
,paintBorder
和paintChildren
来委派职责。当您覆盖paint
并无法调用它的super
方法时,您将失去责任,最终会遇到像现在这样的问题。
Graphics
上下文是Swing组件之间的共享资源。在绘制周期中绘制的每个组件都具有相同的Graphics
。这意味着,应该做的第一件事之一是,Graphics
上下文应为组件准备以在其上绘制。通常是通过paintComponent
方法来完成的,而您不再调用该方法
要做的第一件事是停止覆盖paint
,而通常建议覆盖paintComponent
,这会限制您的总体责任并降低引入更多问题的风险。
接下来,在进行任何自定义绘画之前,请致电super.paintComponent
...
public class Components extends JPanel implements ActionListener
{
//....
@Overrride
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if(em.equals("Rectangle"))
{
g.drawRect(50, 50, 50, 50);
}
else if(em.equals("Circle"))
{
g.drawOval(50, 50, 50, 50);
}
}
但是当我这样做时,以前的绘画会被删除
是的,这就是绘画的工作方式。这是破坏性的。每当执行绘制过程时,都应按该时间点重新绘制组件的整个状态。
如果希望保留以前绘制的内容,则有两个基本选择。
List
的形式存储从头开始重绘上下文的“命令” 两者都有很多例子