繁体   English   中英

在 Java Swing 中为 JLabel 图标绘制线条

[英]Drawing Lines to JLabel Icon in Java Swing

大家好,我想用 DrawLines() class 为 Jlabel 图标画线,但程序没有画线。当我使用frame.add(m)时,程序正在画线到框架.....

DrawLine m = new DrawLine();
frame.add(m);

但是当我使用label.add(m)方法时。程序不起作用。我需要弄清楚这个问题为什么我不能在 jlabelIcon 上画线,我该如何解决这个问题?

这是我的 DrawLine Class

package com.company;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Line2D;

public class DrawLine extends JComponent {


    public void paint(Graphics g) {
        super.paintComponents(g);


        g.drawLine(300, 152, 63, 185);

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {

        }
        g.drawLine(63, 185, 120, 198);

    }
}

这是我的主要 class

package com.company;

import com.sun.source.tree.Tree;
import jdk.swing.interop.SwingInterOpUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.awt.geom.Line2D;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;


public class Main extends JFrame {

 public static void main(String[] args) {

        JFrame frame = new JFrame("Display Image");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = (JPanel) frame.getContentPane();
        frame.setSize(1000,560);
        JLabel label = new JLabel();
        label.setSize(1000,560);

        label.setIcon(new ImageIcon("myimage path"));
        DrawLine m = new DrawLine();
        label.add(m);

        panel.add(label);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
}
}

如果您的目标是将线条和图像绘制在一起,那么您最好的选择是摆脱 ImageIcon 和 JLabel,而是将它们全部绘制在一个 paintComponent 中。 可以通过调用Graphics#drawLine(...)将图像绘制为图像精灵,将线条绘制为线条,或者使用Graphics2D#draw(...)为 Line2D 对象

例如,假设我们有两个 BufferedImage 对象,upImg 和 dnImg,以及两个确定这些精灵位置的 Point 对象,upPt 和 dnPt

public class Foo01 extends JPanel {
    // .....
    private Point upPt = new Point(300, 100);
    private Point dnPt = new Point(700, 650);
    private BufferedImage upImg, dnImg;

假设我们想画一条连接两个图像精灵的线,那么这些都可以在paintComponent方法中绘制,如下所示:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);  // tell the JPanel to do its house-keeping painting

    // make sure that neither image is null
    if (upImg != null && dnImg != null) {

        // draw both images at their respective locations
        g.drawImage(upImg, upPt.x, upPt.y, this);
        g.drawImage(dnImg, dnPt.x, dnPt.y, this);

        // to get a smooth line, use rendering hiints
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // to give the line some thickness
        g2.setStroke(new BasicStroke(5f));  

        // calculate the end-points of the line
        int x1 = upPt.x + upImg.getWidth() / 2;
        int y1 = upPt.y + upImg.getHeight() / 2;
        int x2 = dnPt.x + dnImg.getWidth() / 2;
        int y2 = dnPt.y + dnImg.getHeight() / 2;

        // and then draw it
        g.drawLine(x1, y1, x2, y2);
    }       
}

这是一个执行此操作的示例程序——用一条线连接绘制两个图像。 我还添加了一个 MouseAdapter 以允许用户移动第一个图像,即绿色向上箭头,表明线条也会移动,因为它是在绘画方法中计算的:

在此处输入图像描述

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.URL;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class Foo01 extends JPanel {
    private static final String UP_IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/7/7d/Green_circle_icon.jpg";
    private static final String DN_IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/b/bc/Red_circle_icon.jpg";
    private static final int GUI_W = 1000;
    private static final int GUI_H = 800;
    private Point upPt = new Point(300, 100);
    private Point dnPt = new Point(700, 650);
    private BufferedImage upImg, dnImg;

    public Foo01() {
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
        setBackground(Color.WHITE);
        try {
            URL url = new URL(UP_IMG_PATH);
            upImg = ImageIO.read(url);

            url = new URL(DN_IMG_PATH);
            dnImg = ImageIO.read(url);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(GUI_W, GUI_H);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (upImg != null && dnImg != null) {
            g.drawImage(upImg, upPt.x, upPt.y, this);
            g.drawImage(dnImg, dnPt.x, dnPt.y, this);

            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setStroke(new BasicStroke(5f));

            int x1 = upPt.x + upImg.getWidth() / 2;
            int y1 = upPt.y + upImg.getHeight() / 2;
            int x2 = dnPt.x + dnImg.getWidth() / 2;
            int y2 = dnPt.y + dnImg.getHeight() / 2;
            g.drawLine(x1, y1, x2, y2);
        }       
    }

    private class MyMouse extends MouseAdapter {
        private Point p1 = null;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getX() < upPt.x || e.getX() > upPt.x + upImg.getWidth()) {
                return;
            }
            if (e.getY() < upPt.y || e.getY() > upPt.y + upImg.getHeight()) {
                return;
            }
            p1 = new Point(e.getX(), e.getY());
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (p1 != null) {
                moveSprite(e);
                p1 = null;
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (p1 != null) {
                moveSprite(e);
            }
        }

        private void moveSprite(MouseEvent e) {
            Point p2 = new Point(e.getX(), e.getY());
            int x = upPt.x + p2.x - p1.x;
            int y = upPt.y + p2.y - p1.y;
            upPt = new Point(x, y);

            p1 = p2;
            repaint();
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> {
            Foo01 foo01 = new Foo01();

            JFrame frame = new JFrame("Draw Sprites");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(foo01);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

如果需要向JLabel添加自定义绘画,您可以覆盖其paintComponent

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;


public class Main extends JFrame {

    private static final String BUG = "https://www.growtopiagame.com/forums/attachment.php?attachmentid=141847&d=1477126665";

    public static void main(String[] args) throws MalformedURLException {

        JFrame frame = new JFrame("Display Image");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        DrawLine m = new DrawLine("A crossed bug", new ImageIcon(new URL(BUG)));
        frame.add(m);
        frame.pack();
        frame.setVisible(true);
    }
}

class DrawLine extends JLabel {

    DrawLine(String text, Icon icon) {
        super(text, icon, SwingConstants.CENTER);
        setVerticalTextPosition(SwingConstants.BOTTOM);
        setHorizontalTextPosition(SwingConstants.CENTER);
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.YELLOW);

        g2d.setStroke(new BasicStroke(10));
        int w = getWidth();   int h = getHeight();
        g2d.drawLine(0, 0, w, h); //draw right to left diagonal
        g2d.drawLine(0, h, w, 0); //draw left to right diagonal
    }
}

Swing 是一个单线程库。 所有绘画任务都在事件调度线程 ( EDT ) 中执行。 在 EDT 上运行长时间的进程(例如睡眠)会使该线程保持忙碌,因此它不会执行其他操作,例如更新 gui。 gui 变得无响应(冻结)。
如果要在一定延迟后添加一行,请使用 swing Timer进行作业:

public class Main extends JFrame {

    private static final String BUG = "https://www.growtopiagame.com/forums/attachment.php?attachmentid=141847&d=1477126665";

    public static void main(String[] args) throws MalformedURLException {

        JFrame frame = new JFrame("Display Image");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        DrawLine m = new DrawLine("A crossed bug", new ImageIcon(new URL(BUG)));
        frame.add(m);
        frame.pack();
        frame.setVisible(true);
    }
}

class DrawLine extends JLabel {

    private static final int DELAY = 1500; //millies
    private boolean isDrawSecondDialgonal = false;

    DrawLine(String text, Icon icon) {
        super(text, icon, SwingConstants.CENTER);
        setVerticalTextPosition(SwingConstants.BOTTOM);
        setHorizontalTextPosition(SwingConstants.CENTER);

        //use timer to enable painting of a second diagonal
        javax.swing.Timer timer = new javax.swing.Timer(DELAY, e->  {
            isDrawSecondDialgonal = true;
            repaint();
        });
        timer.setRepeats(false);
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.YELLOW);

        g2d.setStroke(new BasicStroke(10));
        int w = getWidth();   int h = getHeight();
        g2d.drawLine(0, 0, w, h); //draw right to left diagonal
        if(isDrawSecondDialgonal) {
            g2d.drawLine(0, h, w, 0);//draw left to right diagonal
        }
    }
}

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM