在Java Swing中为JLabel图标绘制线条
大家好,我想用DrawLines()类将线绘制到Jlabel图标,但程序没有绘制。当我使用to在Java Swing中为JLabel图标绘制线条,java,swing,jframe,jlabel,Java,Swing,Jframe,Jlabel,大家好,我想用DrawLines()类将线绘制到Jlabel图标,但程序没有绘制。当我使用toframe.add(m)时,程序正在将线绘制到frame DrawLine m = new DrawLine(); frame.add(m); 但是当我使用label.add(m)方法时,程序不起作用。我需要弄清楚这个问题,为什么我不能给jlabelIcon画线,如何解决这个问题 这是我的抽绳课 package com.company; import javax.swing.*; import ja
frame.add(m)
时,程序正在将线绘制到frame
DrawLine m = new DrawLine();
frame.add(m);
但是当我使用label.add(m)
方法时,程序不起作用。我需要弄清楚这个问题,为什么我不能给jlabelIcon画线,如何解决这个问题
这是我的抽绳课
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);
}
}
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);
}
}
这是我的主课
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);
}
}
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(…)
例如,假设我们有两个BuffereImage对象upImg和dnImg,以及两个确定这些精灵位置的点对象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.*;
导入java.awt.event.*;
导入javax.swing.*;
导入java.net.URL;
导入java.io.IOException;
导入java.awt.image.buffereImage;
导入javax.imageio.imageio;
公共类Foo01扩展了JPanel{
私有静态最终字符串UP\u IMG\u PATH=”https://upload.wikimedia.org/wikipedia/commons/7/7d/Green_circle_icon.jpg";
专用静态最终字符串DN\U IMG\U PATH=”https://upload.wikimedia.org/wikipedia/commons/b/bc/Red_circle_icon.jpg";
私有静态最终int GUI_W=1000;
专用静态最终int GUI_H=800;
专用点upPt=新点(300100);
专用点dnPt=新点(700650);
专用缓冲区映像upImg、dnImg;
公共食品01(){
MyMouse MyMouse=新建MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
挫折地面(颜色:白色);
试一试{
URL=新的URL(上行路径);
upImg=ImageIO.read(url);
url=新url(DN\u IMG\u路径);
dnImg=ImageIO.read(url);
}捕获(ioe异常ioe){
ioe.printStackTrace();
}
}
@凌驾
公共维度getPreferredSize(){
返回新维度(GUI_W,GUI_H);
}
@凌驾
受保护组件(图形g){
超级组件(g);
if(upImg!=null&&dnImg!=null){
g、 drawImage(upImg、upPt.x、upPt.y、this);
g、 drawImage(dnImg、dnPt.x、dnPt.y、this);
图形2d g2=(图形2d)g;
g2.setRenderingHint(renderingHits.KEY\u ANTIALIASING,renderingHits.VALUE\u ANTIALIAS\u ON);
g2.设定行程(新基本行程(5f));
int x1=upPt.x+upImg.getWidth()/2;
inty1=upPt.y+upImg.getHeight()/2;
int x2=dnPt.x+dnImg.getWidth()/2;
int y2=dnPt.y+dnImg.getHeight()/2;
g、 抽绳(x1、y1、x2、y2);
}
}
私有类MyMouse扩展了MouseAdapter{
专用点p1=null;
@凌驾
公共无效鼠标按下(MouseEvent e){
如果(e.getX()upPt.x+upImg.getWidth()){
返回;
}
如果(e.getY()upPt.y+upImg.getHeight()){
返回;
}
p1=新点(e.getX(),e.getY());
}
@凌驾
公共无效MouseEvent(MouseEvent e){
如果(p1!=null){
moveSprite(e);
p1=零;
}
}
@凌驾
公共无效鼠标标记(鼠标事件e){
如果(p1!=null){
moveSprite(e);
}
}
私有void移动精灵(MouseEvent e){
点p2=新点(e.getX(),e.getY());
intx=upPt.x+p2.x-p1.x;
int y=upPt.y+p2.y-p1.y;
upPt=新点(x,y);
p1=p2;
重新油漆();
}
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(()->{
Foo01 Foo01=新的Foo01();
JFrame=新JFrame(“绘制精灵”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
添加框架(foo01);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
});
}
}
如果需要将自定义绘制添加到JLabel
中,您可以覆盖其绘制组件
:
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上运行长进程(如睡眠)会使该线程保持忙碌,因此它不会执行诸如更新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
}
}
}
天哪。永远不要在事件线程的Swing GUI中调用
Thread.sleep
,这在绘制方法中有千倍的作用。请理解,当您将事件线程或绘制置于睡眠状态时,整个GUI将进入睡眠状态,使其完全无用。此外,将组件添加到JLabel也不会起作用。标签没有布局管理器,因为它通常不作为容器使用,即使它这样做了,该代码在该位置也没有真正意义。我认为您可能需要阅读Swing图形教程,然后从第一原理开始