dynamicgraphics对象绘画
试图找出最好的方法来做到这一点(并没有跨越任何细节,不,我不知道)。
我正在用圆圈和线条来直观地显示一个graphics(各种节点,用边连接它们)来表示。 每个节点将在运行时添加,我不能硬编码。 据我所知,所有的绘画都需要在paint(Graphics g)方法中完成 – 这不是很有帮助,因为我不能改变参数,而且这只是在初始创build时才调用的。
现在我正考虑让它调用各种其他方法,传递Graphics对象,并根据其他variables – 我将决定是否我甚至想调用它(因为paint()方法是我可以调用的唯一方法)。
我是否完全错误? 以前从来没有打扰过这个。
为了给你一个更好的想法:我希望能够传递我想为节点添加的形状的坐标,然后把它添加到我到目前为止的任何graphics上。 然后与边缘相同,我希望能够通过该行的开始和结束点重新绘制在当时存在的任何之上。
不完全是我现在想要的 – 但你会从我补丁到目前为止的想法:
import java.awt.*; import javax.swing.*; public class MyCanvas extends Canvas { public MyCanvas() { } public void paint(Graphics graphics) { // Keep this until I figured out if it's painted on load or not. graphics.drawLine(10, 20, 350, 380); } public static void main(String[] args) { MyCanvas canvas = new MyCanvas(); JFrame frame = new JFrame(); int vertexes = 0; // Change this next part later to be dynamic. vertexes = 10; int canvasSize = vertexes * vertexes; frame.setSize(canvasSize, canvasSize); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(canvas); frame.setVisible(true); } public void drawNode(int x, int y, Graphics g) { // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5 int xLoc = (x*10) - 5; int yLoc = (y*10) - 5; g.setColor(Color.white); g.fillOval(xLoc, yLoc, 8, 8); g.drawOval(xLoc, yLoc, 8, 8); } public void drawArc(int x, int y, int xx, int yy, Graphics g) { int xLoc = (x*10) - 5; int yLoc = (y*10) - 5; int xxLoc = (xx*10) - 5; int yyLoc = (yy*10) - 5; g.drawLine(xLoc, yLoc, xxLoc, yyLoc); } }
编辑:(安德鲁回应)
import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; public class MyCanvas extends JPanel { public MyCanvas() { } public void paintComponent(Graphics g) { super.paintComponent(g); } public static void main(String[] args) { int vertexes = 0; // Change this next part later to be dynamic. vertexes = 10; int canvasSize = vertexes * vertexes; JFrame frame = new JFrame(); JLabel label = new JLabel(); BufferedImage bImage = new BufferedImage(canvasSize, canvasSize, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = bImage.createGraphics(); g2d.drawLine(50, 50, 300, 300); ImageIcon iIcon = new ImageIcon(bImage); label.setIcon(iIcon); frame.add(label); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); g2d = drawNode(1,1,g2d); label.repaint(); } public static Graphics2D drawNode(int x, int y,Graphics2D g2d) { // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5 int xLoc = (x*10) - 5; int yLoc = (y*10) - 5; g2d.setColor(Color.white); g2d.fillOval(xLoc, yLoc, 8, 8); g2d.drawOval(xLoc, yLoc, 8, 8); return g2d; } public static void drawArc(int x, int y, int xx, int yy) { int xLoc = (x*10) - 5; int yLoc = (y*10) - 5; int xxLoc = (xx*10) - 5; int yyLoc = (yy*10) - 5; // g.drawLine(xLoc, yLoc, xxLoc, yyLoc); } }
你可能会为此采取各种策略。
- 如果一旦完成,对象不会从graphics中移除,请使用
BufferedImage
,将其放入JLabel
中的(ImageIcon
)。 当需要更新时:- 获取图像的graphics实例并绘制新的元素。
- 处理graphics对象。
- 调用标签上的
repaint()
。
- 保留绘制元素的列表。 在绘画方法中,将它们全部绘制。 添加新元素时,请在渲染组件上调用
repaint()
。
这里是第一种技术的例子:
import java.awt.image.BufferedImage; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Random; public class MyCanvas { JLabel view; BufferedImage surface; Random random = new Random(); public MyCanvas() { surface = new BufferedImage(600,400,BufferedImage.TYPE_INT_RGB); view = new JLabel(new ImageIcon(surface)); Graphics g = surface.getGraphics(); g.setColor(Color.ORANGE); g.fillRect(0,0,600,400); g.setColor(Color.BLACK); // Keep this until I figured out if it's painted on load or not. g.drawLine(10, 20, 350, 380); g.dispose(); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent ae) { addNewElement(); } }; Timer timer = new Timer(200, listener); timer.start(); } public void addNewElement() { boolean drawArc = random.nextBoolean(); int x = random.nextInt(60); int y = random.nextInt(40); Graphics g = surface.getGraphics(); if (drawArc) { g.setColor(Color.BLUE); int xx = random.nextInt(60); int yy = random.nextInt(40); drawArc(x,y,xx,yy,g); } else { drawNode(x,y,g); } g.dispose(); view.repaint(); } public static void main(String[] args) { MyCanvas canvas = new MyCanvas(); JFrame frame = new JFrame(); int vertexes = 0; // Change this next part later to be dynamic. vertexes = 10; int canvasSize = vertexes * vertexes; frame.setSize(canvasSize, canvasSize); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(canvas.view); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public void drawNode(int x, int y, Graphics g) { // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5 int xLoc = (x*10) - 5; int yLoc = (y*10) - 5; g.setColor(Color.white); g.fillOval(xLoc, yLoc, 8, 8); g.drawOval(xLoc, yLoc, 8, 8); } public void drawArc(int x, int y, int xx, int yy, Graphics g) { int xLoc = (x*10) - 5; int yLoc = (y*10) - 5; int xxLoc = (xx*10) - 5; int yyLoc = (yy*10) - 5; g.drawLine(xLoc, yLoc, xxLoc, yyLoc); } }
进一步提示
你可能会注意到这些线条看起来相当“锯齿”和丑陋。 BufferedImage
或JComponent
都可以访问更有用的Graphics2D
对象(对于JComponent
,则需要将其转换为paintComponent()
)。 Graphics2D
实例接受可用于平滑(抖动)绘制元素的渲染提示。