我正在尝试这样做,以便在按下命令时两个形状都会移动。我的问题是:如何让蓝色多边形与黄色矩形一起移动?无论我做什么,我似乎无法弄明白。任何帮助表示赞赏!谢谢!
编辑:删除定时器代码(用于不同的东西)
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.Color;
import java.awt.Polygon;
import java.util.Scanner;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.Timer;
public class Original {
public static void main(String[] args) {
// contruction of new JFrame object
JFrame frame = new JFrame();
// mutators
frame.setSize(400,400);
frame.setTitle("SwingBot");
// program ends when window closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Robot r = new Robot();
frame.add(r);
// voila!
frame.setVisible(true);
// your Scanner-based command loop goes here
int noend = 0;
System.out.println("Type a Command:");
while(noend == 0)
{
Scanner input = new Scanner(System.in);
String command = input.next();
if(command.equals("left"))
r.moveBot(-10,0);
if(command.equals("right"))
r.moveBot(10,0);
if(command.equals("down"))
r.moveBot(0,10);
if(command.equals("up"))
r.moveBot(0,-10);
}
// call methods on the Robot instance like w.moveBot(10,10) in response to
// user input
}
public static class Robot extends JComponent
{
private Rectangle rect = new Rectangle(20,60);
private Polygon poly = new Polygon();
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// set the color
g2.setColor(Color.ORANGE);
// draw the shape`
g2.fill(rect);
int xPoly[] = {75, 125, 170, 170, 200, 105, 60};
int yPoly[] = {75, 50, 88, 111, 125, 180, 150};
poly = new Polygon(xPoly, yPoly, xPoly.length);
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawPolygon(poly);
}
public void moveBot(int x, int y)
{
// move the rectangle
rect.translate(x,y);
poly.translate(x,y);
// redraw the window
repaint();
}
}
}
答案 0 :(得分:4)
建议:
paintComponent
方法创建形状。Timer
或按键,或者您尝试移动它们的位置,更改这些变量并致电repaint()
interface
Shape
Shape
,其中每个move()
都有move()
方法可以调用。Shape
方法,然后重绘()`drawShape(Graphics g)
可以使用Shape
方法,您可以在paintComponent
方法中循环浏览drawShape(g)
的数据结构并调用import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class MoveShape extends JPanel {
List<Shape> shapes;
public MoveShape() {
shapes = createShapeList();
InputMap im = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke("RIGHT"), "moveRight");
ActionMap am = getActionMap();
am.put("moveRight", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
for (Shape sh : shapes) {
sh.moveRight();
repaint();
}
}
});
}
private List<Shape> createShapeList() {
List<Shape> list = new ArrayList<>();
int xPoly[] = {75, 125, 170, 170, 200, 105, 60};
int yPoly[] = {75, 50, 88, 111, 125, 180, 150};
list.add(new MyPolygon(xPoly, yPoly, 6));
list.add(new MyRectangle(75, 250, 150, 150));
return list;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Shape sh : shapes) {
sh.drawShape(g);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(450, 450);
}
public class MyRectangle implements Shape {
int x, y, width, height;
public MyRectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public void drawShape(Graphics g) {
g.fillRect(x, y, width, height);
}
@Override
public void moveRight() {
x += INCREMENT;
}
}
public class MyPolygon implements Shape {
int[] xPoints;
int[] yPoints;
int numPoints;
public MyPolygon(int[] xPoints, int[] yPoints, int numPoints) {
this.xPoints = xPoints;
this.yPoints = yPoints;
this.numPoints = numPoints;
}
@Override
public void drawShape(Graphics g) {
g.fillPolygon(xPoints, yPoints, numPoints);
}
@Override
public void moveRight() {
for (int i = 0; i < xPoints.length; i++) {
xPoints[i] += INCREMENT;
}
}
}
public interface Shape {
public static final int INCREMENT = 5;
public void drawShape(Graphics g);
public void moveRight();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Move Shapes");
frame.add(new MoveShape());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
您可以查看this answer作为示例。
以上是我上面提到的所有观点的一个例子。
{{1}}
答案 1 :(得分:2)
正如@peeskillet已经在你的paintComponent
方法中指出的那样,每次调用时都会重新创建poly
对象...意味着它从未移动过,事实上潜在的NullPointerException
等待发生...
public void paintComponent(Graphics g)
{
//...
// This is a bad idea...
poly = new Polygon(xPoly, yPoly, xPoly.length);
//...
}
相反,请在构造函数中为Robot
面板创建poloygon。
此示例还演示了Initial Threads和key bindings以及Stroking and Filling Graphics Primitives
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Original {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setTitle("SwingBot");
Robot r = new Robot();
frame.add(r);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class Robot extends JComponent {
private Rectangle rect = new Rectangle(20, 60);
private Polygon poly = new Polygon();
public Robot() {
int xPoly[] = {75, 125, 170, 170, 200, 105, 60};
int yPoly[] = {75, 50, 88, 111, 125, 180, 150};
poly = new Polygon(xPoly, yPoly, xPoly.length);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Right");
ActionMap am = getActionMap();
am.put("Up", new MoveAction(0, -10));
am.put("Down", new MoveAction(0, 10));
am.put("Left", new MoveAction(-10, 0));
am.put("Right", new MoveAction(10, 0));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
// set the color
g2.setColor(Color.ORANGE);
// draw the shape`
g2.fill(rect);
g2.setColor(Color.BLUE);
g2.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.drawPolygon(poly);
g2.dispose();
}
public void moveBot(int x, int y) {
// move the rectangle
rect.translate(x, y);
poly.translate(x, y);
// redraw the window
repaint();
}
public class MoveAction extends AbstractAction {
private int xDelta;
private int yDelta;
public MoveAction(int xDelta, int yDelta) {
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
moveBot(xDelta, yDelta);
}
}
}
}
请确保您全权归功于@peeskillet,我只想强调您可能会考虑的一些问题区域和解决方案