在绘制另一个对象(Java)时,将一个绘制的对象保存在JPanel中
我有一个9x9网格可以自己绘制,一个矩形可以自己绘制,还有一个构造函数可以用箭头键移动矩形。但是,我不知道如何在矩形移动的同时保持网格在屏幕上。最终,我希望矩形能够充当网格的导航,当用户按向右键时,它向右移动一个正方形,等等在绘制另一个对象(Java)时,将一个绘制的对象保存在JPanel中,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我有一个9x9网格可以自己绘制,一个矩形可以自己绘制,还有一个构造函数可以用箭头键移动矩形。但是,我不知道如何在矩形移动的同时保持网格在屏幕上。最终,我希望矩形能够充当网格的导航,当用户按向右键时,它向右移动一个正方形,等等 据我所知,每当调用paint时,整个JPanel都会重新绘制,这意味着一种方法是每当按下一个键时重新绘制每一行,但这似乎太过分了。还有别的办法吗?实际上,绘制矩形会导致网格被绘制 import java.awt.*; import java.awt.event.*; imp
据我所知,每当调用paint时,整个JPanel都会重新绘制,这意味着一种方法是每当按下一个键时重新绘制每一行,但这似乎太过分了。还有别的办法吗?实际上,绘制矩形会导致网格被绘制
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestDoubleObject extends JFrame
{
private Color ourRectColor = new Color(28,222,144);
private int ourRectWidth = 50;
private int ourRectHeight = 50;
private Point ourRecLocation = new Point(150,150);
public class Rectangle
{
protected void paint(Graphics2D g2d)
{
g2d.setColor(ourRectColor);
g2d.fillRect(ourRecLocation.x, ourRecLocation.y, ourRectWidth, ourRectHeight);
}
} // Rectangle class
public class OurRectangle extends JPanel
{
private Rectangle capableRectangle;
public OurRectangle()
{
capableRectangle = new Rectangle();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
capableRectangle.paint(g2d);
g2d.dispose();
}
} // OurRectangle class
public class CoreGrid
{
protected void paint(Graphics2D g2d)
{
g2d.setColor(new Color(0,0,0));
// Draw Horizontal Lines
for(int i=100;i<=640;i+=60)
g2d.drawLine(100,i,640,i);
// Draw Vertical Lines
for(int i=100;i<=640;i+=60)
g2d.drawLine(i,100,i,640);
}
} // CoreGrid class
public class OurCoreGrid extends JPanel
{
private CoreGrid capableCoreGrid;
public OurCoreGrid()
{
capableCoreGrid = new CoreGrid();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
capableCoreGrid.paint(g2d);
g2d.dispose();
}
} // OurCoreGrid class
KeyStroke pressRight = KeyStroke.getKeyStroke("RIGHT");
KeyStroke pressLeft = KeyStroke.getKeyStroke("LEFT");
KeyStroke pressUp = KeyStroke.getKeyStroke("UP");
KeyStroke pressDown = KeyStroke.getKeyStroke("DOWN");
OurRectangle recToWorkWith = new OurRectangle();
OurCoreGrid gridToWorkWith = new OurCoreGrid();
public TestDoubleObject()
{
InputMap inputMap = recToWorkWith.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = recToWorkWith.getActionMap();
Action rightAction = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
ourRecLocation.x += 20;
recToWorkWith.repaint();
}
};
inputMap.put(pressRight, "rightAction");
actionMap.put("rightAction",rightAction);
Action leftAction = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
ourRecLocation.x -= 20;
recToWorkWith.repaint();
}
};
inputMap.put(pressLeft, "leftAction");
actionMap.put("leftAction",leftAction);
Action downAction = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
ourRecLocation.y += 20;
recToWorkWith.repaint();
}
};
inputMap.put(pressDown, "downAction");
actionMap.put("downAction",downAction);
Action upAction = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
ourRecLocation.y -= 20;
recToWorkWith.repaint();
}
};
inputMap.put(pressUp, "upAction");
actionMap.put("upAction",upAction);
add(gridToWorkWith);
add(recToWorkWith);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800,800);
setVisible(true);
}
public static void main(String[] argv)
{
EventQueue.invokeLater(
new Runnable()
{
@Override
public void run()
{
new TestDoubleObject();
}
});
}
}
一种方法是,每当按下一个键时,重新绘制每一行,但这似乎太过分了
这正是绘画的工作方式。Swing是双缓冲的,所以您不会注意到绘画问题
然而,这不是你目前的问题
我不知道如何在矩形移动的同时保持网格在屏幕上
JFrame内容窗格的默认布局管理器是BorderLayout。将零部件添加到BorderLayout且未指定约束时,假定为BorderLayout.CENTER
add(gridToWorkWith);
add(recToWorkWith);
因此,使用上述代码,您将尝试向BorderLayout.CENTER添加两个组件。但是,只有添加的最后一个组件由BorderLayout管理,这意味着第一个组件的大小将为0,因此它永远不会被绘制
Swing组件具有父/子关系,因此如果希望在网格顶部绘制矩形,则需要将矩形添加到网格中,方法与将网格添加到框架中的方法相同
因此,代码可能类似于:
gridToWorkWith.setLayout( new BorderLayout() );
gridToWorkWith.add( recToWorkWith );
add(gridToWorkWith);
//add(recToWorkWith);
但是,这仍然不起作用,因为默认情况下JPanel是不透明的,因此您将看不到网格,因为矩形在其上方绘制。因此,需要使矩形不不透明:
recToWorkWith.setOpaque( false );
很高兴看到您正在使用键绑定。一个建议是创建一个带有参数的动作来控制矩形的移动。所以这两个参数就是x/y位置的变化
有关此方法的示例,请查看中MotionWithKeyBindings示例中的MotionAction。通过使用不同的参数,您的四个操作可以轻松替换为同一操作的四个实例。你甚至可以创建一个对角线运动。据我所知,只要调用“你是对的”,整个JPanel都会重做。您应该重写JPanel的paintComponent方法。如果希望网格显示在矩形上,请先绘制矩形,然后绘制网格。为动画的每一帧重新绘制整个JPanel要容易得多。