我正在开发一个JavaGUI的应用程序,我无法让ActionListener与我的按钮一起正常工作。当我单击按钮时,什么都没有发生,我的类中的相应方法也没有被执行。我不确定我做错了什么。以下是我代码中相关的类(特别是“Draw”和“DrawGUI”):
`package mydraw.logic;
import static mydraw.gui.DrawGUI.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import mydraw.gui.DrawGUI;
/**
The Draw class provides high-level API methods for drawing shapes using the DrawGUI.
It contains methods for drawing rectangles, ovals, and polylines, as well as a test method
for automatically drawing a set of shapes.
It also provides a constructor to create an instance of the DrawGUI and a method to get the
DrawGUI window component.
*/
/** The application class. Processes high-level commands sent by GUI */
public class Draw {
private static final Object QUIT = null;
private static final Object CLEAR = null;
private static final Object SAVE = null;
private static final Object AUTODRAW = "autoDraw";
public Graphics g;
protected DrawGUI window;
/** main entry point. Just create an instance of this application class */
public static void main(String[] args) {
new Draw();
}
/** Application constructor: create an instance of our GUI class */
public Draw() {
window = new DrawGUI(this);
g = window.getGraphics();
}
/**
* This is the application method that processes commands sent by the GUI.
*
* @param command - command sent by the GUI.
*/
public void doCommand(String command) {
if (command.equals(CLEAR)) {
window.clear();
System.out.println("CLEAR button clicked");
} else if (command.equals(QUIT)) {
window.dispose();
System.out.println("QUIT button clicked");
System.exit(0);
} else if (command.equals(SAVE)) {
Image img = window.createImageFromPanel();
try {
writeImage(img, "hallo.bmp");
System.out.println("SAVE button clicked");
} catch (IOException e) {
System.err.println("Not working");
}
} else if (command.equals(AUTODRAW)) {
autoDraw();
System.out.println("AUTODRAW button clicked");
}
}
/**
* API method: get height.
*
* @return height of the window.
*/
public int getHeight() {
return window.getContentPane().getHeight();
}
/**
* API method: set height.
*
* @param height - the new height of the window.
* @throws SizeException if the input is negative.
*/
public void setHeight(int height) throws SizeException {
if (height < 0) {
throw new SizeException("Höhe muss positiv sein.");
}
Dimension d = window.getContentPane().getPreferredSize();
d.height = height;
window.getContentPane().setPreferredSize(d);
window.pack();
}
/**
* API method: get width.
*
* @return width of the window.
*/
public int getWidth() {
return window.getContentPane().getWidth();
}
/**
* API method: set width.
*
* @param width - the new width of the window.
* @throws SizeException if the input is negative.
*/
public void setWidth(int width) throws SizeException {
if (width < 0) {
throw new SizeException("Breite muss positiv sein.");
}
Dimension d = window.getContentPane().getPreferredSize();
d.width = width;
window.getContentPane().setPreferredSize(d);
window.pack();
}
/**
* API method: set foreground color.
*
* @param new_color - new foreground color.
* @throws ColorException if the input is not a valid color.
*/
public void setFGColor(String new_color) throws ColorException {
Color color = Color.getColor(new_color);
if (color == null) {
throw new ColorException("Ungueltiger Farbname.");
}
window.setForeground(color);
}
/**
* API method: get foreground color.
*
* @return the current foreground color.
*/
public String getFGColor() {
return window.getForeground().toString();
}
/**
* API method: set background color.
*
* @param new_color - new background color.
* @throws ColorException if the input is not a valid color.
*/
public void setBGColor(String new_color) throws ColorException {
Color color = Color.getColor(new_color);
if (color == null) {
throw new ColorException("Ungueltiger Farbname.");
}
window.setBackground(color);
}
/**
* API method: get background color.
*
* @return the current background color.
*/
public String getBGColor() {
return window.getBackground().toString();
}
/**
* API method: get drawing.
*
* @return the drawing as a BufferedImage.
*/
public BufferedImage getDrawing() {
int width = window.getContentPane().getWidth();
int height = window.getContentPane().getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();
window.paintComponents(g2d);
g2d.dispose();
return image;
}
/**
* API method: write image.
*
* @param img - the image to be saved.
* @param filename - the filename to save the image to.
* @throws IOException if there is an error while writing the image.
*/
public void writeImage(Image img, String filename) throws IOException {
MyBMPFile.write(filename, img);
}
/**
* API method: read image.
*
* @param filename - the filename to read the image from.
* @return the image as an Image object.
* @throws IOException if there is an error while reading the image.
*/
public Image readImage(String filename) throws IOException {
return MyBMPFile.read(filename);
}
/**
* API method: clear the window.
*/
public void clear() {
g.setColor(window.getBackground());
g.fillRect(0, 0, window.getContentPane().getWidth(), window.getContentPane().getHeight());
}
/**
*
* Test method to automatically draw a set of shapes using the DrawGUI.
*
* Draws a rectangle, an oval, and a polyline.
*/
public void autoDraw() {
g.setColor(Color.RED);
drawRectangle(new Point(50, 100), new Point(150, 200)); // Rectangle 1
g.setColor(Color.BLUE);
drawRectangle(new Point(160, 100), new Point(260, 200)); // Rectangle 2
g.setColor(Color.GREEN);
drawRectangle(new Point(270, 100), new Point(370, 200)); // Rectangle 3
g.setColor(Color.BLACK);
drawRectangle(new Point(380, 100), new Point(480, 200)); // Rectangle 4
g.setColor(Color.RED);
drawOval(new Point(50, 250), new Point(150, 350)); // Oval 1
g.setColor(Color.BLUE);
drawOval(new Point(175, 250), new Point(275, 350)); // Oval 2
g.setColor(Color.GREEN);
drawOval(new Point(300, 250), new Point(400, 350)); // Oval 3
g.setColor(Color.BLACK);
drawOval(new Point(425, 250), new Point(525, 350)); // Oval 4
g.setColor(Color.RED);
java.util.List<Point> points1 = new ArrayList<>(Arrays.asList(new Point(90, 180), new Point(100, 150),
new Point(110, 180), new Point(120, 150), new Point(130, 180)));
drawPolyLine(points1); // Polyline 1
g.setColor(Color.BLUE);
java.util.List<Point> points2 = new ArrayList<>(Arrays.asList(new Point(190, 180), new Point(200, 150),
new Point(210, 180), new Point(220, 150), new Point(230, 180)));
drawPolyLine(points2); // Polyline 2
g.setColor(Color.GREEN);
java.util.List<Point> points3 = new ArrayList<>(Arrays.asList(new Point(290, 180), new Point(300, 150),
new Point(310, 180), new Point(320, 150), new Point(330, 180)));
drawPolyLine(points3); // Polyline 3
g.setColor(Color.BLACK);
java.util.List<Point> points4 = new ArrayList<>(Arrays.asList(new Point(390, 180), new Point(400, 150),
new Point(410, 180), new Point(420, 150), new Point(430, 180)));
drawPolyLine(points4); // Polyline 4
}
/**
*
* Method to draw a rectangle on the DrawGUI.
*
* @param upper_left the upper-left corner of the rectangle
*
* @param lower_right the lower-right corner of the rectangle
*/
public void drawRectangle(Point upper_left, Point lower_right) {
int width = lower_right.x - upper_left.x;
int height = lower_right.y - upper_left.y;
g.drawRect(upper_left.x, upper_left.y, width, height);
}
/**
*
* Method to draw an oval on the DrawGUI.
*
* @param upper_left the upper-left corner of the oval
*
* @param lower_right the lower-right corner of the oval
*/
public void drawOval(Point upper_left, Point lower_right) {
int width = lower_right.x - upper_left.x;
int height = lower_right.y - upper_left.y;
g.drawOval(upper_left.x, upper_left.y, width, height);
}
/**
*
* Method to draw a polyline on the DrawGUI.
*
* @param points a list of points defining the vertices of the polyline
*/
public void drawPolyLine(java.util.List<Point> points) {
int[] xpoints = new int[points.size()];
int[] ypoints = new int[points.size()];
for (int i = 0; i < points.size(); i++) {
xpoints[i] = points.get(i).x;
ypoints[i] = points.get(i).y;
}
g.drawPolyline(xpoints, ypoints, points.size());
}
/**
* Helper method for the test class.
*
* @return window return the window
*/
public Window getWindow() {
return window;
}
}`
`package mydraw.gui;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.*;
import mydraw.logic.Draw;
/** This class implements the GUI for our application */
public class DrawGUI extends JFrame {
private static final long serialVersionUID = 1L;
/**
* The default width of the drawing window.
*/
public static final int WIDTH = 800;
/**
* The default height of the drawing window.
*/
public static final int HEIGHT_DEFAULT = 400;
/**
* The labels for the buttons.
*/
public static final String SCRIBBLE = "Scribble";
public static final String RECTANGLE = "Rectangle";
public static final String OVAL = "Oval";
public static final String BLACK = "Black";
public static final String GREEN = "Green";
public static final String RED = "Red";
public static final String BLUE = "Blue";
public static final String CLEAR = "Clear";
public static final String QUIT = "Quit";
public static final String SAVE = "Save";
public static final String AUTODRAW = "autoDraw";
private final Draw logic;
private Color color;
private final DrawingPanel drawingPanel;
/**
* Constructs a new DrawGUI object with the specified Draw logic.
*
* @param logic the Draw object to use for the GUI's logic
*/
public DrawGUI(Draw logic) {
super("Draw");
this.logic = logic;
color = Color.black;
drawingPanel = new DrawingPanel();
setSize(WIDTH, HEIGHT_DEFAULT);
Choice shape_chooser = new Choice();
shape_chooser.add(SCRIBBLE);
shape_chooser.add(RECTANGLE);
shape_chooser.add(OVAL);
shape_chooser.addItemListener(new ShapeManager(this, drawingPanel));
Choice color_chooser = new Choice();
color_chooser.add(BLACK);
color_chooser.add(GREEN);
color_chooser.add(RED);
color_chooser.add(BLUE);
color_chooser.addItemListener(e -> {
if (e.getItem().equals(BLACK)) {
color = Color.black;
} else if (e.getItem().equals(GREEN)) {
color = Color.green;
} else if (e.getItem().equals(RED)) {
color = Color.red;
} else if (e.getItem().equals(BLUE)) {
color = Color.blue;
}
});
JButton clear = new JButton(CLEAR);
JButton quit = new JButton(QUIT);
JButton save = new JButton(SAVE);
JButton autodraw = new JButton(AUTODRAW);
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 5));
clear.addActionListener(e -> logic.doCommand(CLEAR));
quit.addActionListener(e -> logic.doCommand(QUIT));
save.addActionListener(e -> logic.doCommand(SAVE));
autodraw.addActionListener(e -> logic.doCommand(AUTODRAW));
setLayout(new BorderLayout());
topPanel.add(save);
topPanel.add(autodraw);
topPanel.add(new JLabel("Shape:"));
topPanel.add(shape_chooser);
topPanel.add(new JLabel("Color:"));
topPanel.add(color_chooser);
topPanel.add(clear);
topPanel.add(quit);
add(topPanel, BorderLayout.NORTH);
add(drawingPanel, BorderLayout.CENTER);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
DrawGUI.this.logic.doCommand("quit");
}
});
this.setBackground(Color.white);
this.setVisible(true);
}
/**
* Returns the currently selected drawing color.
*
* @return the currently selected drawing color
*/
public Color getColor() {
return color;
}
/**
* Creates a new BufferedImage of the drawing panel.
*
* @return a new BufferedImage of the drawing panel
*/
public BufferedImage createImageFromPanel() {
int width = drawingPanel.getWidth();
int height = drawingPanel.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
drawingPanel.paint(g2d);
g2d.dispose();
return image;
}
/**
* Clears the drawing panel and resets the GUI.
*/
public void clear() {
Graphics g = getGraphics();
g.setColor(getBackground());
g.fillRect(0, 0, getSize().width, getSize().height);
drawingPanel.clearImage();
}
}`
`package mydraw.gui;
import java.awt.*;
import java.awt.event.*;
@SuppressWarnings("unused")
public class ShapeManager implements ItemListener {
DrawGUI gui;
final DrawingPanel drawingPanel;
abstract class ShapeDrawer extends MouseAdapter implements MouseMotionListener {
@Override
public void mouseMoved(MouseEvent e) {
/* ignore */ }
}
// if this class is active, the mouse is interpreted as a pen
class ScribbleDrawer extends ShapeDrawer implements MouseMotionListener {
int lastx, lasty;
@Override
public void mousePressed(MouseEvent e) {
lastx = e.getX();
lasty = e.getY();
}
@Override
public void mouseDragged(MouseEvent e) {
Graphics2D g2d = drawingPanel.getImageGraphics();
int x = e.getX() - drawingPanel.getX(), y = e.getY() - drawingPanel.getY();
g2d.setColor(gui.getColor());
g2d.setPaintMode();
g2d.drawLine(lastx, lasty, x, y);
g2d.dispose();
lastx = x;
lasty = y;
drawingPanel.repaint(); // Neu hinzugefügt
}
}
// if this class is active, rectangles are drawn
class RectangleDrawer extends ShapeDrawer {
int pressx, pressy;
int lastx = -1, lasty = -1;
// mouse pressed => fix first corner of rectangle
@Override
public void mousePressed(MouseEvent e) {
pressx = e.getX();
pressy = e.getY();
}
// mouse released => fix second corner of rectangle
// and draw the resulting shape
@Override
public void mouseReleased(MouseEvent e) {
Graphics2D g2d = drawingPanel.getImageGraphics();
if (lastx != -1) {
// first undraw a rubber rect
g2d.setXORMode(gui.getColor());
g2d.setColor(gui.getBackground());
doDraw(pressx, pressy, lastx, lasty, g2d);
lastx = -1;
lasty = -1;
}
// these commands finish the rubberband mode
g2d.setPaintMode();
g2d.setColor(gui.getColor());
// draw the final rectangle
doDraw(pressx, pressy, e.getX(), e.getY(), g2d);
g2d.dispose();
drawingPanel.repaint(); // Neu hinzugefügt
}
// mouse released => temporarily set second corner of rectangle
// draw the resulting shape in "rubber-band mode"
@Override
public void mouseDragged(MouseEvent e) {
Graphics g = drawingPanel.getImageGraphics();
// these commands set the rubberband mode
g.setXORMode(gui.getColor());
g.setColor(gui.getBackground());
if (lastx != -1) {
// first undraw previous rubber rect
doDraw(pressx, pressy, lastx, lasty, g);
}
lastx = e.getX();
lasty = e.getY();
// draw new rubber rect
doDraw(pressx, pressy, lastx, lasty, g);
}
public void doDraw(int x0, int y0, int x1, int y1, Graphics g) {
// calculate upperleft and width/height of rectangle
int x = Math.min(x0, x1);
int y = Math.min(y0, y1);
int w = Math.abs(x1 - x0);
int h = Math.abs(y1 - y0);
// draw rectangle
g.drawRect(x, y, w, h);
}
}
// if this class is active, ovals are drawn
class OvalDrawer extends RectangleDrawer {
@Override
public void doDraw(int x0, int y0, int x1, int y1, Graphics g) {
int x = Math.min(x0, x1);
int y = Math.min(y0, y1);
int w = Math.abs(x1 - x0);
int h = Math.abs(y1 - y0);
// draw oval instead of rectangle
g.drawOval(x, y, w, h);
}
}
ScribbleDrawer scribbleDrawer = new ScribbleDrawer();
RectangleDrawer rectDrawer = new RectangleDrawer();
OvalDrawer ovalDrawer = new OvalDrawer();
ShapeDrawer currentDrawer;
public ShapeManager(DrawGUI gui, DrawingPanel drawingPanel) {
this.gui = gui;
this.drawingPanel = drawingPanel;
currentDrawer = scribbleDrawer;
this.gui.addMouseListener(currentDrawer);
this.gui.addMouseMotionListener(currentDrawer);
}
// reset the shape drawer
public void setCurrentDrawer(ShapeDrawer l) {
if (currentDrawer == l)
return;
// activate new drawer
gui.removeMouseListener(currentDrawer);
gui.removeMouseMotionListener(currentDrawer);
currentDrawer = l;
gui.addMouseListener(currentDrawer);
gui.addMouseMotionListener(currentDrawer);
}
// user selected new shape => reset the shape mode
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getItem().equals("Scribble")) {
setCurrentDrawer(scribbleDrawer);
} else if (e.getItem().equals("Rectangle")) {
setCurrentDrawer(rectDrawer);
} else if (e.getItem().equals("Oval")) {
setCurrentDrawer(ovalDrawer);
}
}
}`
`/**
This class represents a panel for drawing shapes.
It provides methods to clear the image, retrieve the graphics object of the image,
and paint the image on the panel.
*/
package mydraw.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private BufferedImage image;
/**
*
* Constructs a new DrawingPanel with a default image size of 800 x 400 pixels.
* The image is initialized with a white background.
*/
public DrawingPanel() {
image = new BufferedImage(800, 400, BufferedImage.TYPE_INT_ARGB);
clearImage();
}
/**
*
* Clears the image by filling it with a white color.
*/
public void clearImage() {
Graphics2D g2d = image.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
g2d.dispose();
}
/**
*
* Returns the graphics object of the image for drawing shapes on it.
*
* @return the graphics object of the image
*/
public Graphics2D getImageGraphics() {
return image.createGraphics();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}
`
我已经尝试使用System. out.println来“调试”“doCommand”方法,我发现只有当单击“autoDraw”时,“autoDraw被按下”的句子才会打印到控制台。当单击其余按钮时,没有任何东西会打印到控制台。只有当我通过macOS菜单关闭应用程序窗口时,“Quit按钮被按下”才会在控制台上输出,而不是通过单击Quit按钮本身。
稍后我会把这个编辑成一个真正的答案,但是是在黑暗中拍摄的。
更改下面的这一行。
if(命令. equals(CLEAR)){
改成这样吧。
if(命令. equals(DrawGUI.CLEAR)){
您可能需要进行一些导入。
发生这种情况是因为在本节中,最终变量CLEAR、QUIT、SAVE被初始化为null,因此您的if比较总是错误的。像IntelliJ这样的好IDE会发现这个问题并警告您。
我想你可能搞混了,因为你的Draw有这些变量(它们为空),DrawGUI类也有这些变量(它们有值),你正在相互比较这两个变量。去掉Draw类中的变量,这样你就可以将同一个变量与它本身进行比较。
public void doCommand(String command) {
if (command.equals(CLEAR)) {
window.clear();
System.out.println("CLEAR button clicked");
} else if (command.equals(QUIT)) {
window.dispose();
System.out.println("QUIT button clicked");
System.exit(0);
} else if (command.equals(SAVE)) {
Image img = window.createImageFromPanel();
try {
writeImage(img, "hallo.bmp");
System.out.println("SAVE button clicked");
} catch (IOException e) {
System.err.println("Not working");
}
} else if (command.equals(AUTODRAW)) {
autoDraw();
System.out.println("AUTODRAW button clicked");
}
}
附言:从风格上来说,我不喜欢你通过一个带有参数的doCommand()方法运行所有内容,该参数用于调度要采取的操作。如果它是我的,我会为每个操作使用不同的方法,只需从操作侦听器中调用这些方法。这样你就可以摆脱所有这些变量,根本不需要做任何比较if/else-if的东西。