Как рисовать линии в Java
мне интересно, есть ли функитон в Java, который может нарисовать линию из координат (x1, x2) в (y1, y2)?
Я хочу сделать что-то вроде этого:
drawLine(x1, x2, x3, x4);
и я хочу иметь возможность делать это в любое время в коде, делая несколько строк одновременно.
Я попытался сделать это:
public void paint(Graphics g){
g.drawLine(0, 0, 100, 100);
}
но это не дает мне никакого контроля над тем, когда функция используется, и я не могу понять, как назвать ее несколькими раз.
надеюсь, вы понимаете, что я имею в виду!
P. S. Я хочу создать систему координат со многими координатами.
10 ответов
очень простой пример компонента swing для рисования линий. Он держит внутри списка со строками, которые были добавлены с помощью метода 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);
}
}
хранить строки в списке. Когда приходит время, чтобы нарисовать их, itereate списка и нарисовать каждого из них. Что-то вроде этого.
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()
);
}
}
}
скриншот
вам нужно создать класс, который расширяет компонент. Там вы можете переопределить метод paint и поместить код рисования в:
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...
}
}
поместите этот компонент в GUI вашего приложения. Если вы используете Swing, вам нужно расширить JComponent и переопределить paintComponent.
Как упоминал Гелиос, код рисования фактически сообщает системе, как выглядит ваш компонент. Система запросит эту информацию (назовите свой код рисования), когда она думает он должен быть (повторно)окрашен, например, если окно перемещается перед вашим компонентом.
в вашем классе, вы должны иметь:
public void paint(Graphics g){
g.drawLine(x1, y1, x2, y2);
}
затем в коде, если есть необходимость, вы измените x1, y1, x2, y2 и вызовите repaint();
.
Я понимаю, что вы используете JAVA AWT API для рисования. Метод Paint вызывается, когда элемент управления нуждается в перекраске. И я уверен, что он предоставляет в графическом аргументе, что прямоугольник-это тот, кто нуждается в перекраске (чтобы избежать перерисовки всех).
поэтому, если вы представляете фиксированное изображение, вы просто рисуете все, что вам нужно в этом методе.
Если вы анимируете, я предполагаю, что вы можете аннулировать некоторую область, и метод paint будет вызван автоматически. Так вы можно изменить состояние, вызвать invalidate, и он будет вызван снова.
можно использовать getGraphics метод компонента, на котором вы хотите рисовать. Это в свою очередь позволит вам рисовать линии и делать другие вещи, которые доступны через графика класс
чтобы дать вам некоторые идеи:
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);
}
}
Я построил целый класс методов для рисования точек, линий, прямоугольников, кругов и т. д. Я разработал его, чтобы рассматривать окно как лист графической бумаги, где начало координат не должно быть в левом верхнем углу, а значения 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
объект с использованием двойников вместо ints. Помимо других фигур, мой класс поддерживает 3D-перспективный рисунок и несколько удобных методов (например, рисование круга с центром в определенной точке с заданным радиусом.) Если кто-то заинтересованный, я был бы рад поделиться больше этого класса.
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);
}
});
}
}
чтобы ответить на ваш исходный вопрос, это (x1, y1)
to (x2, y2)
.
например,
это, чтобы нарисовать горизонтальную линию:
g.drawLine( 10, 30, 90, 30 );
vs
это, чтобы нарисовать вертикальную линию:
g.drawLine( 10, 30, 10, 90 );
надеюсь, это поможет.