Dynamische Grafikobjekt-Bemalung

Versuchen Sie, den besten Weg zu finden, dies zu tun (Und ohne irgendwelche Besonderheiten zu überschreiten DO NOTs, die ich nicht kenne).

Ich arbeite daran, einen Graphen visuell darzustellen (verschiedene Knoten, mit Kanten, die sie verbinden) mit Kreisen und Linien, um solche darzustellen. Jeder Knoten wird zur Laufzeit hinzugefügt und ich kann diesen nicht fest codieren. Von dem, was ich verstehe, muss alle Malerei in der Farbe (Grafik g) -Methode getan werden – was ist nicht so hilfreich, da ich nicht die Parameter ändern kann und es scheint, dass dies nur während der ersten Erstellung aufgerufen wird?

Im Moment dachte ich darüber nach, verschiedene andere Methoden aufzurufen, das Graphics-Objekt zu übergeben und abhängig von anderen Variablen – ich werde entscheiden, ob ich das überhaupt nennen möchte (Da die paint () -Methode die einzige ist, die ich aufrufen kann ).

Tue ich das völlig falsch? Ich habe mich nie zuvor darum gekümmert.

Um Ihnen eine bessere Vorstellung davon zu geben, womit ich enden möchte: Ich möchte in der Lage sein, die Koordinaten der Form zu übergeben, die ich für den Knoten hinzufügen möchte, und sie dann zu dem, was ich bisher in der Grafik habe, hinzuzufügen. Und dann, mit den Kanten, möchte ich in der Lage sein, den Anfangs- und Endpunkt der Linie zu übergeben, um über dem, was zu dieser Zeit existiert, neu zu streichen.

Nicht genau, was ich gerade will – aber du wirst die Idee von dem bekommen, was ich bisher zusammengeflickt habe:

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); } } 

Edit: (Antwort für Andrew)

 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); } } 

Dafür gibt es verschiedene Strategien.

  1. Wenn die Objekte nie aus der Zeichnung entfernt werden, verwenden Sie ein BufferedImage und legen Sie es in ein ( ImageIcon in a) JLabel . Wenn es an der Zeit ist zu aktualisieren:
    1. Holen Sie sich die Grafikinstanz des Bildes und zeichnen Sie das neue Element.
    2. Entsorgen Sie das Grafikobjekt.
    3. Rufen Sie repaint() auf dem Etikett auf.
  2. Behalte eine Liste der gezeichneten Elemente. Bemale sie in der Malmethode. Wenn ein neues Element hinzugefügt wird, rufen Sie repaint() für die Renderkomponente auf.

Hier ist ein Beispiel für die 1. Technik:

MyCanvas

 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); } } 

Weiterer Tipp

Sie werden vielleicht bemerken, dass die Linien ziemlich “gezackt” und hässlich aussehen. Sowohl JComponent als auch JComponent haben Zugriff auf das nützlichere Graphics2D Objekt (für die JComponent muss es in paintComponent() ). Eine Graphics2D Instanz akzeptiert Rendering-Hinweise, die zum Glätten (Dithering) der gezeichneten Elemente verwendet werden können.