Comment dessiner des lignes en Java
je me demande s'il y a un funciton en Java qui peut tracer une ligne à partir des coordonnées (x1, x2) à (y1, y2)?
Ce que je veux, c'est faire quelque chose comme ceci:
drawLine(x1, x2, x3, x4);
et je veux pouvoir le faire à tout moment dans le code, en faisant apparaître plusieurs lignes à la fois.
j'ai essayé de faire ceci:
public void paint(Graphics g){
g.drawLine(0, 0, 100, 100);
}
Mais cela me donne aucun contrôle lorsque la fonction est utilisée et je ne peux pas comprendre comment l'appeler plusieurs fois.
j'Espère vous comprenez ce que je veux dire!
<!-Je veux créer un système de coordonnées avec beaucoup de coordonnées.10 réponses
Un exemple très simple d'un composant swing pour dessiner des lignes. Il conserve en interne une liste avec les lignes qui ont été ajoutées avec la méthode addLine. Chaque fois qu'une nouvelle ligne est ajoutée, repaint est invoqué pour informer le sous-système graphique qu'une nouvelle peinture est nécessaire.
la classe inclut aussi quelques exemples d'utilisation.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LinesComponent extends JComponent{
private static class Line{
final int x1;
final int y1;
final int x2;
final int y2;
final Color color;
public Line(int x1, int y1, int x2, int y2, Color color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.color = color;
}
}
private final LinkedList<Line> lines = new LinkedList<Line>();
public void addLine(int x1, int x2, int x3, int x4) {
addLine(x1, x2, x3, x4, Color.black);
}
public void addLine(int x1, int x2, int x3, int x4, Color color) {
lines.add(new Line(x1,x2,x3,x4, color));
repaint();
}
public void clearLines() {
lines.clear();
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
g.setColor(line.color);
g.drawLine(line.x1, line.y1, line.x2, line.y2);
}
}
public static void main(String[] args) {
JFrame testFrame = new JFrame();
testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final LinesComponent comp = new LinesComponent();
comp.setPreferredSize(new Dimension(320, 200));
testFrame.getContentPane().add(comp, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
JButton newLineButton = new JButton("New Line");
JButton clearButton = new JButton("Clear");
buttonsPanel.add(newLineButton);
buttonsPanel.add(clearButton);
testFrame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
newLineButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int x1 = (int) (Math.random()*320);
int x2 = (int) (Math.random()*320);
int y1 = (int) (Math.random()*200);
int y2 = (int) (Math.random()*200);
Color randomColor = new Color((float)Math.random(), (float)Math.random(), (float)Math.random());
comp.addLine(x1, y1, x2, y2, randomColor);
}
});
clearButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
comp.clearLines();
}
});
testFrame.pack();
testFrame.setVisible(true);
}
}
stocker les lignes dans un type de liste. Quand vient le temps de les peindre, itérez la liste et dessinez chacun. Quelque chose comme cela.
DrawLines.java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.geom.Line2D;
import javax.swing.JOptionPane;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.util.ArrayList;
import java.util.Random;
class DrawLines {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
LineComponent lineComponent = new LineComponent(400,400);
for (int ii=0; ii<30; ii++) {
lineComponent.addLine();
}
JOptionPane.showMessageDialog(null, lineComponent);
}
};
SwingUtilities.invokeLater(r);
}
}
class LineComponent extends JComponent {
ArrayList<Line2D.Double> lines;
Random random;
LineComponent(int width, int height) {
super();
setPreferredSize(new Dimension(width,height));
lines = new ArrayList<Line2D.Double>();
random = new Random();
}
public void addLine() {
int width = (int)getPreferredSize().getWidth();
int height = (int)getPreferredSize().getHeight();
Line2D.Double line = new Line2D.Double(
random.nextInt(width),
random.nextInt(height),
random.nextInt(width),
random.nextInt(height)
);
lines.add(line);
repaint();
}
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
Dimension d = getPreferredSize();
g.setColor(Color.black);
for (Line2D.Double line : lines) {
g.drawLine(
(int)line.getX1(),
(int)line.getY1(),
(int)line.getX2(),
(int)line.getY2()
);
}
}
}
Capture d'écran
vous devez créer une classe qui étend Component. Là vous pouvez outrepasser la méthode de peinture et mettre votre code de peinture dans:
package blah.whatever;
import java.awt.Component;
import java.awt.Graphics;
public class TestAWT extends Component {
/** @see java.awt.Component#paint(java.awt.Graphics) */
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawLine(0,0,100,100);
g.drawLine(10, 10, 20, 300);
// more drawing code here...
}
}
mettez ce composant dans l'interface graphique de votre application. Si vous utilisez Swing, vous devez étendre JComponent et remplacer paintComponent, à la place.
comme Helios l'a mentionné, le code de peinture indique au système à quoi ressemble votre composant. Le système demandera ces informations (appelez votre code de peinture) quand il pense il doit être (re)peint, par exemple, si une fenêtre est déplacée à l'avant de votre composant.
Dans votre classe, vous devez avoir:
public void paint(Graphics g){
g.drawLine(x1, y1, x2, y2);
}
puis en code s'il y a besoin vous changerez x1, y1, x2, y2 et appellerez repaint();
.
je comprends que vous êtes à l'aide de Java AWT API pour le dessin. La méthode de la peinture est invoquée lorsque la commande doit être repeinte. Et je suis assez sûr qu'il fournit dans l'argument graphique quel rectangle est celui qui doit repeindre (pour éviter de redessiner tout).
donc si vous présentez une image fixe, vous n'avez qu'à dessiner tout ce dont vous avez besoin dans cette méthode.
si vous animez, je suppose que vous pouvez invalider une région et la méthode paint sera invoquée automatiquement. Si vous peut modifier l'état, appel d'invalider, et il sera de nouveau appelée.
Vous pouvez utiliser le getGraphics méthode de l'élément sur lequel vous souhaitez attirer. Cela devrait à son tour vous permettre de tracer des lignes et de faire d'autres choses qui sont disponibles à travers le carte Graphique classe
Pour vous donner une idée:
public void paint(Graphics g) {
drawCoordinates(g);
}
private void drawCoordinates(Graphics g) {
// get width & height here (w,h)
// define grid width (dh, dv)
for (int x = 0; i < w; i += dh) {
g.drawLine(x, 0, x, h);
}
for (int y = 0; j < h; j += dv) {
g.drawLine(0, y, w, y);
}
}
j'ai construit toute une classe de méthodes pour dessiner des points, des lignes, des rectangles, des cercles, etc. Je l'ai conçu pour traiter la fenêtre comme un morceau de papier graphique où l'origine ne doit pas être en haut à gauche et les valeurs de y augmentent en montant. Voici comment je dessine les lignes:
public static void drawLine (double x1, double y1, double x2, double y2)
{
((Graphics2D)g).draw(new Line2D.Double(x0+x1*scale, y0-y1*scale, x0+x2*scale, y0-y2*scale));
}
Dans l'exemple ci-dessus, (x0, y0)
représente l'origine dans l'écran des coordonnées et scale
est un facteur d'échelle. Les paramètres d'entrée sont fournis graphique coordonnées, pas de coordonnées de l'écran. Il est pas de repaint()
appelé. Vous pouvez enregistrer jusqu'à ce que tu ai dessiné toutes les lignes dont vous avez besoin.
Il me semble que quelqu'un pourrait ne pas vouloir penser en termes de papier graphique:
((Graphics2D)g).draw(new Line2D.Double(x1, y1, x2, y2));
notez l'utilisation de Graphics2D
. Cela nous permet de tirer une balise Line2D
objet à l'aide de doubles au lieu d'entiers. Outre d'autres formes, ma classe dispose d'un support pour le dessin en perspective 3D et plusieurs méthodes pratiques (comme dessiner un cercle centré à un certain point donné un rayon.) Si quelqu'un est intéressé, je serais heureux de partager plus de cette classe.
a simple line , after that you can see also a doted line
import java.awt.*;
import javax.swing.*;
import java.awt.Graphics.*;
import java.awt.Graphics2D.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BasicStroke;
import java.awt.Event.*;
import java.awt.Component.*;
import javax.swing.SwingUtilities;
/**
*
* @author junaid
*/
public class JunaidLine extends JPanel{
//private Graphics Graphics;
private void doDrawing(Graphics g){
Graphics2D g2d=(Graphics2D) g;
float[] dash1 = {2f,0f,2f};
g2d.drawLine(20, 40, 250, 40);
BasicStroke bs1 = new BasicStroke(1,BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND,1.0f,dash1,2f);
g2d.setStroke(bs1);
g2d.drawLine(20, 80, 250, 80);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent( g);
doDrawing(g);
}
}
class BasicStrokes extends JFrame{
public BasicStrokes(){
initUI();
}
private void initUI(){
setTitle("line");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
add(new JunaidLine());
setSize(280,270);
setLocationRelativeTo(null);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
BasicStrokes bs = new BasicStrokes();
bs.setVisible(true);
}
});
}
}
pour répondre À ta question d'origine, c'est (x1, y1)
(x2, y2)
.
Par exemple,
ceci est pour tracer une ligne horizontale:
g.drawLine( 10, 30, 90, 30 );
et
ceci est pour tracer une ligne verticale:
g.drawLine( 10, 30, 10, 90 );
j'espère que cela aide.