画线,圈出任何东西(Java)

画线,圈出任何东西(Java),java,swing,draw,Java,Swing,Draw,所以我是stackoverflow的新手 我将要创建一条直线,一个三角形,任何东西,但我只是专注于直线和一个好的面向对象编程 所以我创建了Point2D类: package draw; /** * * @author Pedro */ public class Point2D { private int x,y; // Construtores public Point2D(){ this(0,0); } public

所以我是stackoverflow的新手

我将要创建一条直线,一个三角形,任何东西,但我只是专注于直线和一个好的面向对象编程

所以我创建了Point2D类:

    package draw;

/**
 *
 * @author Pedro
 */
public class Point2D {
    private int x,y;

    // Construtores
    public Point2D(){
        this(0,0);
    }

    public Point2D(int x, int y){
        this.x=x;
        this.y=y;
    }

    // Set's e Get's
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
稍后,我使用类point2D创建类线,以获得起点和终点

    package draw;

/**
 *
 * @author Pedro
 */
public class Linha extends Figura{
    private Point2D pinicial;
    private Point2D pfinal;

    //construtores    
    public Linha(int xinicial, int yinicial, int xfinal, int yfinal){
        pinicial=new Point2D(xinicial, yinicial);
        pfinal=new Point2D(xfinal, yfinal);
    }
    public Linha(Point2D pinicial, Point2D pfinal){
        this.pinicial=pinicial;
        this.pfinal=pfinal;
    }
    //Get's e Set's
    public Point2D getPinicial() {
        return pinicial;
    }
    public void setPinicial(Point2D pinicial) {
        this.pinicial = pinicial;
    }
    public Point2D getPfinal() {
        return pfinal;
    }
    public void setPfinal(Point2D pfinal) {
        this.pfinal = pfinal;
    }

}
然后我用一个叫做“line”的按钮创建了一个Jframe,然后把它放在Jframe里面的一个面板上,就是它要画线的地方

问题是。。。我不知道该怎么画线,也不知道该怎么标定


您能帮我吗?

简单地说,在您的JPanel类ovverride
paintComponent()
方法中:

JPanel panel = new JPanel() {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g)
        g.drawLine(x1, y1, x2, y2);
    }
}
其中,
x1
y1
x2
y2
是您线路的跳线。 如果只希望在按下按钮后绘制线,请在主类中创建一个全局
布尔
变量,当按下按钮时,将其设置为true,然后在创建JPanel时执行以下操作:

JPanel panel = new JPanel() {
        @Override
        protected void paintComponent(Graphics g) {
            if (myBoolean) {
                super.paintComponent(g)
                g.drawLine(x1, y1, x2, y2);
            }
        }
    }

虽然在另一个答案中给出的建议太好了,但我还是无法阻止自己,在同一个答案中添加一两个词,比如,为了让绘画发生,你需要调用
repaint()
,从
actionPerformed
JButton
附件中调用
repaint()

正如@camickr所述,在绘图扩展类中使用
getPreferredSize()
,将提供一个有效的暂存区域,需要在该区域进行绘图。这可能在这方面也有帮助

此外,如果您希望保持迄今为止在
板上绘制的所有线条完好无损,那么只要将它们存储在
列表中
,并在该
列表上迭代,以便在绘制新线时再次绘制所有线条

一个简单的例子如下:

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;

public class LineExample {

    private DrawingBoard board;
    private JButton drawLineButton;

    private Random random;

    private ActionListener buttonAction = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            int width = board.getWidth();
            int height = board.getHeight();
            Line line = new Line(random.nextInt(width),
                                random.nextInt(height),
                                random.nextInt(width),
                                random.nextInt(height));
            board.setValues(line);
        }    
    };

    public LineExample() {
        random = new Random();
    }

    private void displayGUI() {
        JFrame frame = new JFrame("Drawing Lines Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel(new BorderLayout(5, 5));
        board = new DrawingBoard(400, 400);
        contentPane.add(board, BorderLayout.CENTER);

        drawLineButton = new JButton("LINE");
        drawLineButton.addActionListener(buttonAction);
        contentPane.add(drawLineButton, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new LineExample().displayGUI();
            }    
        };
        EventQueue.invokeLater(runnable);
    }
}

class DrawingBoard extends JPanel {

    private int width;
    private int height;

    private  List<Line> lines;

    public DrawingBoard(int w, int h) {
        width = w;
        height = h;
        lines = new ArrayList<Line>();
    }

    public void setValues(Line line) {
        lines.add(line);
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(width, height);
    }    

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Line line : lines) {
            int xs = line.getXStart();
            int ys = line.getYStart();
            int xe = line.getXEnd();
            int ye = line.getYEnd();
            g.drawLine(xs, ys, xe, ye);
        }
    }    
}

class Line {

    private Point startPoint;
    private Point endPoint;

    public Line(int xs, int ys, int xe, int ye) {
        startPoint = new Point(xs, ys);
        endPoint = new Point(xe, ye);
    }

    public int getXStart() {
        return startPoint.getX();
    }

    public int getYStart() {
        return startPoint.getY();
    }

    public int getXEnd() {
        return endPoint.getX();
    }

    public int getYEnd() {
        return endPoint.getY();
    }
}

class Point {

    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}
import java.awt.*;
导入java.awt.event.*;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Random;
导入javax.swing.*;
公共类行示例{
私人抽绳板;
私有JButton drawLineButton;
私有随机;
私有ActionListener按钮操作=新建ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
int width=board.getWidth();
int height=board.getHeight();
线条=新行(随机的.nextInt(宽度),
随机。nextInt(高度),
随机。nextInt(宽度),
随机。nextInt(高度));
板。设置值(行);
}    
};
公共线路示例(){
随机=新随机();
}
私有void displayGUI(){
JFrame=新JFrame(“绘制线示例”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane=新的JPanel(新的BorderLayout(5,5));
板=新的绘图板(400400);
contentPane.add(board,BorderLayout.CENTER);
drawLineButton=新的JButton(“线”);
drawLineButton.addActionListener(buttonAction);
contentPane.add(drawLineButton,BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
Runnable Runnable=新的Runnable(){
@凌驾
公开募捐{
新建LineExample().displayGUI();
}    
};
invokeLater(可运行);
}
}
类DrawingBoard扩展JPanel{
私有整数宽度;
私人内部高度;
私有列表行;
公共绘图板(内部w、内部h){
宽度=w;
高度=h;
行=新的ArrayList();
}
公共void设置值(行){
行。添加(行);
重新油漆();
}
@凌驾
公共维度getPreferredSize(){
返回新尺寸(宽度、高度);
}    
@凌驾
受保护组件(图形g){
超级组件(g);
用于(行:行){
int xs=line.getXStart();
int ys=line.getYStart();
int xe=line.getXEnd();
int ye=line.getYEnd();
g、 抽绳(xs、ys、xe、ye);
}
}    
}
班级线{
专用点起始点;
专用点端点;
公共线路(int xs、int ys、int xe、int ye){
起始点=新点(xs,ys);
端点=新点(xe,ye);
}
public int getXStart(){
返回startPoint.getX();
}
public int getYStart(){
返回startPoint.getY();
}
public int getXEnd(){
返回endPoint.getX();
}
public int getYEnd(){
返回endPoint.getY();
}
}
类点{
私人INTX;
私营企业;
公共点(整数x,整数y){
这个.x=x;
这个。y=y;
}
公共int getX(){
返回x;
}
公共int getY(){
返回y;
}
}

您看到这个了吗?啊,我应该在秋千上温习一下。事实上,我的评论是如此错误,以至于我甚至会删除它。很抱歉1+但请不要忘了提醒OP在JPanel扩展类中调用super的
paintComponent(g)
方法,在
paintComponent(Graphics g)
override中,对于被重写的方法,请尽量保持访问说明符不变。这里它是受保护的,而不是公共的。另外,您需要覆盖面板的
getPreferredSize()
方法,否则大小将是(0,0),面板可能不会显示,具体取决于使用的布局管理器。@camickr您能编辑我的答案并添加吗?我不明白你的意思,而且我以前从未遇到过getPreferredSize()的问题。谢谢。@Victor2748,请尝试使用将自定义组件添加到框架中