Graphics.fillRect 不一致的行为 - 在某些机器上以负高度和宽度绘制,但在其他机器上则不然



我教一门Java课程,遇到了以下问题。发生此问题的项目是一个"绘制"应用程序。底部的相关代码:

对于大多数学生来说,调用 Graphics.fillRect 并传入负高度和宽度将导致矩形不显示在屏幕上。这是基于java文档的预期行为,以及我在过去4年中在数百名学生的机器上看到的行为。换句话说,如果没有额外的代码,您只能通过单击并从左上角拖动到右下角来绘制矩形。

突然,我看到一些学生将负高度和宽度传递到 Graphics.fillRect 中,矩形在屏幕上正确绘制(就好像传入了正高度和宽度一样(。换句话说,他们可以通过单击并从屏幕上的任何方向拖动来绘制矩形,而无需添加代码来正确计算最左上角,然后基于此获取高度和宽度。

这种情况发生在使用不同IDE(Eclipse和IntelliJ(的人身上。我已经检查了以下内容:

  • 使用甲骨文 JDK
  • 使用 JDK
  • 10.0.2(还尝试将我自己的 JDK 更新到 14.0.1,以防出现一些兼容级别问题但无法重现(
  • (在 IntelliJ 中(项目结构> SDK 和语言级别正确 (10(
  • (在 IntelliJ 中(指向正确 JDK 版本 (10.0.2( 的平台 SDK>项目结构
  • (在 IntelliJ 中(运行/调试配置指向正确的 JRE 版本 (10.0.2(
  • 调试以确保高度和宽度确实以负数的形式传入
  • 一名学生完全卸载并重新安装了所有内容,并遇到了同样的问题。

这是相关的代码(请记住,这是一门学习 .NET 开发人员教授的设计模式的课程,我知道代码并不完美(:


public class MyMouseListener extends MouseAdapter {
private Point startPoint;
private PaintCanvasBase paintCanvas;
public MyMouseListener(PaintCanvasBase paintCanvas){
this.paintCanvas = paintCanvas;
}
@Override
public void mousePressed(MouseEvent e){
startPoint = new Point(e.getX(), e.getY());
}
@Override
public void mouseReleased(MouseEvent e){
// Filled in rectangle
Graphics2D graphics2d = paintCanvas.getGraphics2D();
graphics2d.setColor(Color.GREEN);
int width = e.getX() - startPoint.getX();
int height = e.getY() - startPoint.getY();
graphics2d.fillRect(startPoint.getX(), startPoint.getY(), width, height);
}
}
public class Point {
private final int x;
private final int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
public class PaintCanvas extends PaintCanvasBase {
public Graphics2D getGraphics2D() {
return (Graphics2D)getGraphics();
}
}
public abstract class PaintCanvasBase extends JComponent {
public abstract Graphics2D getGraphics2D();
}
// Following lines in the main method:
// PaintCanvasBase paintCanvas = new PaintCanvas();
// paintCanvas.addMouseListener(new MyMouseListener(paintCanvas));

这种行为的原因是什么?

我创建了一个简单、可运行的 Java Swing 应用程序示例,该示例基于起点和终点绘制一个矩形。

我根据Java 8标准编译了这个应用程序,并在Java 13.0.2 JDK上运行它。 我正在使用 Windows 10。 无论我朝哪个方向绘制矩形,矩形都正确绘制。 我知道这对你没有帮助,但我想讨论一下我在你的代码片段中找到的一些东西。

所有摆动绘画都必须以JPanelpaintComponent方法完成。MouseAdapter执行Rectangle计算。paintComponent方法绘制Rectangle

这是我的示例代码。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SimpleDrawingArea implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new SimpleDrawingArea());
}
private Rectangle rectangle;
@Override
public void run() {
JFrame frame = new JFrame("Simple Drawing Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawingPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingPanel() {
this.setPreferredSize(new Dimension(400, 300));
this.addMouseListener(new MyMouseListener(this));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if (rectangle != null) {
g2d.setColor(Color.GREEN);
g2d.fillRect(rectangle.x, rectangle.y,
rectangle.width, rectangle.height);
}
}
}
public class MyMouseListener extends MouseAdapter {
private DrawingPanel drawingPanel;
private Point startPoint;
public MyMouseListener(DrawingPanel drawingPanel) {
this.drawingPanel = drawingPanel;
}
@Override
public void mousePressed(MouseEvent e){
startPoint = e.getPoint();
}
@Override
public void mouseReleased(MouseEvent e){
Point endPoint = e.getPoint();
int width = endPoint.x - startPoint.x;
int height = endPoint.y - startPoint.y;
rectangle = new Rectangle(startPoint.x, startPoint.y,
width, height);
drawingPanel.repaint();
}
}
}

最新更新