Java 在画布上设置原点

Java 在画布上设置原点,java,awt,Java,Awt,我正在尝试创建一个简单的图形程序,我希望/需要原点位于左下角,因此我使用以下自定义画布: public class GraphingCanvas extends Canvas { public GraphingCanvas() { } public void paint(Graphics g) { ((Graphics2D) g).translate(this.getWidth(), this.getHeight()); g.tran

我正在尝试创建一个简单的图形程序,我希望/需要原点位于左下角,因此我使用以下自定义画布:

public class GraphingCanvas extends Canvas {

    public GraphingCanvas() {

    }

    public void paint(Graphics g) {
        ((Graphics2D) g).translate(this.getWidth(), this.getHeight());
        g.translate(10, 10);
        g.setColor(Color.BLACK);
        g.drawLine(0, 0, 10, 10);
    }
}
但是,当我使用此画布时,如下所示:

private void initialize() {

    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    GraphingCanvas canvas = new GraphingCanvas();
    canvas.setBackground(Color.WHITE);
    canvas.setBounds(10, 10, 414, 241);
    frame.getContentPane().add(canvas);
}

原点似乎保持默认值。我做错了什么吗?

这可能会也可能不会做你想做的事,但基本上我使用了
scale(1,-1)
来翻转y轴方向(并转换上下文)

魔法基本上发生在
paintComponent
方法中,使用

g2d.scale(1, -1);
g2d.translate(0, -getHeight());
可运行的示例

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Rectangle box = new Rectangle(10, 10, 20, 20);

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            draw(g2d, Color.RED, Color.MAGENTA);
            g2d.dispose();

            g2d = (Graphics2D) g.create();
            g2d.scale(1, -1);
            g2d.translate(0, -getHeight());
            draw(g2d, Color.BLUE, Color.GREEN);
            g2d.dispose();
        }

        protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {

            g2d.setColor(boxColor);
            g2d.fill(box);
            g2d.setColor(lineColor);
            g2d.drawLine(0, 0, getWidth(), getHeight());

        }

    }

}
为了确定,我创建了一个简单的方法

protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {
    g2d.setColor(boxColor);
    g2d.fill(box);
    g2d.setColor(lineColor);
    g2d.drawLine(0, 0, getWidth(), getHeight());
}

用“法线”方向调用,然后用变换的方向再次调用,所以它与用于绘制输出的代码是相同的,唯一改变的是方向

这可能会或可能不会做你想要的,但基本上我使用了
缩放(1,-1)
通过y轴翻转方向(并根据上下文翻译)

魔法基本上发生在
paintComponent
方法中,使用

g2d.scale(1, -1);
g2d.translate(0, -getHeight());
可运行的示例

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Rectangle box = new Rectangle(10, 10, 20, 20);

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            draw(g2d, Color.RED, Color.MAGENTA);
            g2d.dispose();

            g2d = (Graphics2D) g.create();
            g2d.scale(1, -1);
            g2d.translate(0, -getHeight());
            draw(g2d, Color.BLUE, Color.GREEN);
            g2d.dispose();
        }

        protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {

            g2d.setColor(boxColor);
            g2d.fill(box);
            g2d.setColor(lineColor);
            g2d.drawLine(0, 0, getWidth(), getHeight());

        }

    }

}
为了确定,我创建了一个简单的方法

protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {
    g2d.setColor(boxColor);
    g2d.fill(box);
    g2d.setColor(lineColor);
    g2d.drawLine(0, 0, getWidth(), getHeight());
}

使用“正常”方向调用,然后使用转换的方向再次调用,因此它与用于绘制输出的代码相同,唯一更改的是方向

我不认为您可以…您“可能”能够将上下文缩放0x-1,但我不确定这是否能达到您想要的效果(事情会向上发展,而不是向下发展)。相反,您应该创建一种转换方法,该方法可以将您的点从正常的顶部/左侧上下文转换为所需的底部/左侧上下文。避免使用
null
布局,像素完美的布局在现代ui设计中是一种错觉。有太多的因素会影响组件的单个大小,其中没有一个因素会影响组件的大小你可以控制。Swing的设计初衷是与核心的布局管理人员合作,丢弃这些布局管理器将导致无休止的问题,你将花费越来越多的时间来纠正这些问题。因此,避免不必要地混合使用Swing和AWT组件。坚持使用所有Swing。我认为你不能……你“可能”能够将上下文扩展0x-1,但我不确定这是否会达到您想要的效果(事情会向上发展,而不是向下发展)。相反,您应该创建一种转换方法,该方法可以将您的点从正常的顶部/左侧上下文转换为所需的底部/左侧上下文。避免使用
null
布局,像素完美的布局在现代ui设计中是一种错觉。有太多的因素会影响组件的单个大小,其中没有一个因素会影响组件的大小你可以控制。Swing的设计初衷是与核心布局管理器一起工作,丢弃这些布局管理器将导致无休止的问题,你将花费越来越多的时间试图纠正这些问题。因此,避免不必要地混合Swing和AWT组件。坚持使用所有Swing。热爱它!并且你创建并处理了一个临时Graphics2D对象,这样就不会出现问题通过仿射变换来破坏JVM的图形对象。@HoverCraftfullOfels我真的很惊讶它能起作用:PQuestion:它会不会和enter按钮一样…@MadProgrammer,问题:将原点转换为0高度不是一回事吗?考虑到将y比例设置为负值并转换为负值,他我们可以相互抵消,比例为1,1,并转换为0,正高度将是相同的,不是吗?不是,转换将
图形
上下文的
0x0
点移动到新位置,但是Java的
图形
总是从
0x0
向右/向下绘制!您创建并处理了一个临时图形2d o对象,以免通过仿射变换损坏JVM的图形对象。@HovercraftFullOfEels我真的很惊讶它能起作用:PQuestion:它会不会有相同的输入按钮…@MadProgrammer,问题:仅仅将原点转换为0,高度不是一回事吗?考虑将y比例设置为负数并转换若要相互抵消负高度,比例为1,1并转换为0,则正高度将是相同的,否?否,转换将
Graphics
上下文的
0x0
点移动到新位置,但Java的
Graphics
始终从
0x0
向右/向下绘制