Как рисовать линии в Java - PullRequest
21 голосов
/ 27 апреля 2011

Мне интересно, есть ли в Java функция, которая может нарисовать линию от координат (x1, x2) до (y1, y2)?

Я хочу сделать что-то вроде этого:

drawLine(x1, x2, x3, x4);

И я хочу иметь возможность сделать это в любое время в коде, чтобы сразу появилось несколько строк.

Я пытался сделать это:

public void paint(Graphics g){
   g.drawLine(0, 0, 100, 100);
}

Но это не дает мне контроля над тем, когда функция используется, и я не могу понять, как ее вызвать несколько раз.

Надеюсь, вы понимаете, о чем я!

PS Iхочу создать систему координат с множеством координат.

Ответы [ 10 ]

35 голосов
/ 27 апреля 2011

Очень простой пример компонента свинга для рисования линий. Внутренне хранит список со строками, которые были добавлены с помощью метода addLine. Каждый раз, когда добавляется новая строка, вызывается перекраска, чтобы сообщить графическому подсистеме, что требуется новая краска.

Класс также включает в себя несколько примеров использования.

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

}
9 голосов
/ 27 апреля 2011

Сохранение строк в каком-либо списке. Когда приходит время рисовать их, повторяйте список и рисуйте каждый. Как это:

DrawLines

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

Скриншот

enter image description here

3 голосов
/ 27 апреля 2011

Вам необходимо создать класс, расширяющий Компонент. Там вы можете переопределить метод рисования и ввести код рисования в:

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...
}

}

Поместите этот компонент в графический интерфейс вашего приложения. Если вы используете Swing, вам нужно вместо этого расширить JComponent и переопределить paintComponent.

Как упоминал Гелиос, код рисования фактически сообщает системе, как выглядит ваш компонент. Система запросит эту информацию (вызовет ваш код рисования), когда сочтет, что ее необходимо (пере) нарисовать, например, если перед вашим компонентом было перемещено окно.

1 голос
/ 27 апреля 2011

Чтобы дать вам представление:

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);
  }
}
1 голос
/ 27 апреля 2011

Я понимаю, что вы используете Java AWT API для рисования. Метод рисования вызывается, когда элемент управления нуждается в перерисовке. И я почти уверен, что в аргументе Graphics он указывает, какой прямоугольник нужно перекрасить (чтобы не перерисовывать все).

Так что, если вы представляете фиксированное изображение, вы просто рисуете все, что вам нужно в этом методе.

Если вы анимируете, я предполагаю, что вы можете сделать недействительной некоторую область, и метод рисования будет вызван автоматически. Таким образом, вы можете изменить состояние, вызвать инвалида, и он будет вызван снова.

1 голос
/ 27 апреля 2011

В вашем классе вы должны иметь:

public void paint(Graphics g){
   g.drawLine(x1, y1, x2, y2);
}

Тогда в коде, если это необходимо, вы измените x1, y1, x2, y2 и вызовете repaint();.

0 голосов
/ 22 декабря 2013
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);

}                

});

}


}
0 голосов
/ 16 августа 2013

Чтобы ответить на ваш оригинальный вопрос, это (x1, y1) до (x2, y2).

Например,

Это нарисовать горизонтальную линию:

g.drawLine( 10, 30, 90, 30 );

против

Это нарисовать вертикальную линию:

g.drawLine( 10, 30, 10, 90 );

Надеюсь, это поможет.

0 голосов
/ 21 февраля 2013

Я создал целый класс методов для рисования точек, линий, прямоугольников, окружностей и т. Д. Я разработал его для обработки окна как листа миллиметровки, где начало координат не обязательно должно быть вверху слева, а значения y увеличиваются с ростом. Вот как я рисую линии:

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

В приведенном выше примере (x0, y0) представляет начало координат в экранных координатах, а scale - коэффициент масштабирования. Входные параметры должны быть представлены в виде координат графика, а не экранных координат. repaint() не вызывается. Вы можете сохранить, пока не начертите все нужные вам линии.

Мне приходит в голову, что кто-то, возможно, не хочет думать в терминах миллиметровки:

    ((Graphics2D)g).draw(new Line2D.Double(x1, y1, x2, y2));

Обратите внимание на использование Graphics2D. Это позволяет нам рисовать Line2D объект, используя двойные числа вместо целых. Помимо других форм, в моем классе есть поддержка трехмерного перспективного рисования и несколько удобных методов (например, рисование круга, центрированного в определенной точке с заданным радиусом.) Если кому-то интересно, я был бы рад поделиться с вами большим количеством этого класса.

0 голосов
/ 27 апреля 2011

Вы можете использовать метод getGraphics компонента, на котором вы хотите рисовать. Это, в свою очередь, должно позволить вам рисовать линии и делать другие вещи, которые доступны через Графика класс

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...