所以我只是在这里做一些学习决赛,但是我无法让它发挥作用。我之前一直在做的是调用paintComponent(Graphics g) 事情只是很好的。但是现在我在编译时得到了“paintComponent在JComponent中具有受保护的访问”错误。我可以让它编译的唯一方法是告诉它调用paint。但即使它编译,也不会在applet窗口中调用paint。我在这里看不到什么?
public class LineDraw extends JComponent
{
private final Point p1;
private final Point p2;
private final JApplet callingWindow;
private final ArrayList<Line2D.Double> lines;
public LineDraw(JApplet callingWindow)
{
this.p1 = new Point();
this.p2 = new Point();
this.callingWindow = callingWindow;
this.lines = new ArrayList<Line2D.Double>();
MouseListener mouse = new MouseHandler();
callingWindow.addMouseListener(mouse);
}
public class MouseHandler extends MouseAdapter
{
private boolean firstClick;
public MouseHandler()
{
firstClick = true;
}
public void mouseClicked(MouseEvent e)
{
if(firstClick)
{
p1.setLocation(e.getPoint());
firstClick = false;
}
else
{
p2.setLocation(e.getPoint());
lines.add(new Line2D.Double(p1, p2));
p2.setLocation(p1.getLocation());
callingWindow.repaint();
}
}
public void paintComponent(Graphics2D g2)
{
for(Line2D.Double e: lines)
{
g2.draw(e);
}
}
}
}
小程序类本身
public class AppletWin extends JApplet
{
private LineDraw lineDrawer;
public void init()
{
setBackground(Color.white);
lineDrawer = new LineDraw(this);
}
public void paint(Graphics h)
{
Graphics2D g = (Graphics2D)h;
//Clear background
g.setColor(getBackground());
g.fillRect(1, 1, getWidth(), getHeight());
lineDrawer.paintComponent(g);
}
}
答案 0 :(得分:1)
LineDrawer
是一个组件,你应该将它添加到applet中,它会自动绘制。
您似乎陷入了命名冲突问题。
JComponent
定义了两种绘画方法(实际上它定义了一些,但让我们保持简单),paint
和paintComponent
。
你遇到的问题是你从JComponent
继承但似乎在表演自己的画作。当你想要开发自己的“画家”课程时,这很好,但与Swing组件相悖。还有更多的Swing组件,然后只是绘制它。
你遇到的另一个问题是你在MouseHandler
方法中定义了一个“paint”方法,似乎假设它可以从LineDraw
类调用。问题是,你实际上正在调用JComponent
的{{1}}方法,而不是你想要/认为你的方法。
尝试删除paint
并将extends JComponent
方法移至paint
类。
正如MouseEvent所说,在大多数情况下,您不应该直接致电LineDraw
或paint
。
你可能会发现:
有用的
<强>已更新强>
paintComponent
public class AppletWin extends JApplet {
private LineDraw lineDrawer;
public void init() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
setBackground(Color.white);
lineDrawer = new LineDraw(AppletWin.this);
setLayout(new BorderLayout());
add(lineDrawer);
}
});
}
public class LineDraw extends JComponent {
private final Point p1;
private final Point p2;
private final JApplet callingWindow;
private final ArrayList<Line2D.Double> lines;
public LineDraw(JApplet callingWindow) {
this.p1 = new Point();
this.p2 = new Point();
this.callingWindow = callingWindow;
this.lines = new ArrayList<Line2D.Double>();
MouseListener mouse = new MouseHandler();
addMouseListener(mouse);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
for (Line2D.Double e : lines) {
g2.draw(e);
}
}
public class MouseHandler extends MouseAdapter {
private boolean firstClick;
public MouseHandler() {
firstClick = true;
}
public void mouseClicked(MouseEvent e) {
if (firstClick) {
p1.setLocation(e.getPoint());
firstClick = false;
} else {
p2.setLocation(e.getPoint());
lines.add(new Line2D.Double(p1, p2));
p2.setLocation(p1.getLocation());
}
repaint();
}
}
}
}
你真的应该避免覆盖顶级容器的public class AppletWin extends JApplet {
private LineDraw lineDrawer;
public void init() {
setBackground(Color.white);
lineDrawer = new LineDraw(this);
}
public void paint(Graphics h) {
// The the applet clear the background
super.paint(h);
Graphics2D g = (Graphics2D) h;
lineDrawer.paintComponent(g);
}
public class LineDraw {
private final Point p1;
private final Point p2;
private final JApplet callingWindow;
private final ArrayList<Line2D.Double> lines;
public LineDraw(JApplet callingWindow) {
this.p1 = new Point();
this.p2 = new Point();
this.callingWindow = callingWindow;
this.lines = new ArrayList<Line2D.Double>();
MouseListener mouse = new MouseHandler();
callingWindow.addMouseListener(mouse);
}
public void paintComponent(Graphics2D g2) {
System.out.println("...");
for (Line2D.Double e : lines) {
g2.draw(e);
}
}
public class MouseHandler extends MouseAdapter {
private boolean firstClick;
public MouseHandler() {
firstClick = true;
}
public void mouseClicked(MouseEvent e) {
if (firstClick) {
p1.setLocation(e.getPoint());
firstClick = false;
} else {
p2.setLocation(e.getPoint());
lines.add(new Line2D.Double(p1, p2));
p2.setLocation(p1.getLocation());
}
callingWindow.repaint();
}
}
}
}
方法。 paint
方法是一种非常复杂的方法,从长远来看,绕过它只会给你带来问题,而且它不是双缓冲的;)
答案 1 :(得分:0)
此代码的问题在于LineDraw中的paintComponent方法位于内部类MouseHandler中。