java.awt.Label 与 javax.swing.JLabel 对比
JLabel不是Label的子类
public class Label extends Component implements Accessible { // Label
public class JLabel extends JComponent implements SwingConstants, Accessible //JLabel
Object ▶ Component ▶ Label Object ▶ Component ▶ Container ▶ JComponent ▶ JLabel
JLabel要setOpaque(true)才能看到background
Label和JLabel默认的isOpaque()都是false, Label看得到background, JLabel看不到
因为JComponent重新定义了opaque
package labelJLabel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.*;
import javax.swing.*;
public class LabelJLabel对比isOpaque {
static Frame frame = new Frame("LabelJLabel对比isOpaque");
static Label label001 = new Label();
static JLabel jlabel001 = new JLabel();
static Label label002 = new Label();
static JLabel jlabel002 = new JLabel();
static {
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {System.exit(0);}
});
frame.setBounds(100, 100, 1600, 900);
label001.setBackground(Color.red);
label001.setText("我是Label001, 设置了background为红色, 我的isOpaque()="+label001.isOpaque()+" 但还是能看到背景色");
jlabel001.setBackground(Color.ORANGE);
jlabel001.setText("我是JLabel001, 设置了background为橙色, 看不到是因为我的isOpaque()="+jlabel001.isOpaque());
label002.setBackground(Color.yellow);
label002.setText("我是Label002, 设置了background为黄色, 我的isOpaque()="+label002.isOpaque()+" Label没有setOpaque()方法");
jlabel002.setBackground(Color.green); jlabel002.setOpaque(true);
jlabel002.setText("我是JLabel002, 设置了background为绿色, 我的isOpaque()="+jlabel002.isOpaque()+", 因为我setOpaque(true)了; 所以能看到background");
frame.setLayout(new GridLayout(0, 1, 10, 10));
try {
Field fields[] = LabelJLabel对比isOpaque.class.getDeclaredFields();
for(Field field : fields) {
if(field.getModifiers()==Modifier.STATIC) {
Object o = field.get(null); System.out.println(o);
if(o!=frame)frame.add((Component)o);
((Component)o).setFont(new Font("", Font.BOLD, 25));
}
}
}catch(Throwable th) {th.printStackTrace();}
// frame.setFont(new Font("", Font.BOLD, 30));
frame.setVisible(true);
}
public static void main(String...arguments) {
}
}
设置Frame的Font能影响到Label, 影响不到JLabel
package labelJLabel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.*;
import javax.swing.*;
public class 设置Frame的Font能影响Label不能影响JLabel {
static Frame frame = new Frame("LabelJLabel对比isOpaque");
static Label label001 = new Label();
static JLabel jlabel001 = new JLabel();
static Label label002 = new Label();
static JLabel jlabel002 = new JLabel();
static {
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {System.exit(0);}
});
frame.setBounds(100, 100, 1600, 900);
label001.setBackground(Color.red);
label001.setText("我是Label001, 设置了background为红色, 我的isOpaque()="+label001.isOpaque()+" 但还是能看到背景色");
jlabel001.setBackground(Color.ORANGE);
jlabel001.setText("我是JLabel001, 设置了background为橙色, 看不到是因为我的isOpaque()="+jlabel001.isOpaque());
label002.setBackground(Color.yellow);
label002.setText("我是Label002, 设置了background为黄色, 我的isOpaque()="+label002.isOpaque()+" Label没有setOpaque()方法");
jlabel002.setBackground(Color.green); jlabel002.setOpaque(true);
jlabel002.setText("我是JLabel002, 设置了background为绿色, 我的isOpaque()="+jlabel002.isOpaque()+", 因为我setOpaque(true)了; 所以能看到background");
frame.setLayout(new GridLayout(0, 1, 10, 10));
try {
Field fields[] = 设置Frame的Font能影响Label不能影响JLabel.class.getDeclaredFields();
for(Field field : fields) {
if(field.getModifiers()==Modifier.STATIC) {
Object o = field.get(null); System.out.println(o);
if(o!=frame)frame.add((Component)o);
// ((Component)o).setFont(new Font("", Font.BOLD, 25));
}
}
}catch(Throwable th) {th.printStackTrace();}
frame.setFont(new Font("", Font.BOLD, 50));
frame.setVisible(true);
}
public static void main(String...arguments) {
}
}
文字超出边界的效果不一样
Label好像没法换行, JLabel可以使用HTML !!! 帅
package labelJLabel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Field;
import java.util.stream.Stream;
import javax.swing.*;
public class LabeJLabel换行 {
static Frame frame ;
static Label label001 , label002;
static JLabel jlabel001 , jlabel002;
static {
try {
frame = (Frame)Frame.class.getDeclaredConstructor(String.class).newInstance("LabeJLabel换行");
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {System.exit(0);}
});
frame.setLayout(new GridLayout(0, 1, 5, 5));
frame.setBounds(100, 50, 1600, 900);
}catch(Throwable th) {th.printStackTrace();}
label001=new Label("Label的换行用\\n\r\n换行没有用"); label001.setBackground(Color.red);
label002 = new Label("""
<html>
<h1 style="color:red">label不能用Html</h1>
<br/>
<b style="font-size:30px; color:blue" > 不能用<br/>换行 </b>
<svg>
<line x1="0" y1="0" x2="100%" y2="100%" stroke="black" strokewidth="10" />
</svg>
</html>
""");
label002.setBackground(Color.orange);
jlabel001 = new JLabel("JLabel用\\n\r\n换行没有用"); jlabel001.setBackground(Color.yellow); jlabel001.setOpaque(true);;
jlabel002 = new JLabel("""
<html>
<span style="color:red; font-size:30px;">JLabel竟然能用Html!!! 太帅了!</span> <br/>
<b style="font-size:30px; color:blue" > 用<br/>换行 </b>
<svg>
<line x1="0" y1="0" x2="100%" y2="100%" stroke="black" strokewidth="10" />
</svg>
<div style="position:fixed; left:300px; top:10px; width:500px; height:50px; font-size:20px; background:#0099ff; border:10px solid black; border-radius:50%;" >html功能不完整</style>
<script>alert()</script>
</html>
""");
jlabel002.setOpaque(true); jlabel002.setBackground(Color.green);
try {
Field fields[] = Class.forName(new Throwable().getStackTrace()[0].getClassName()).getDeclaredFields();
Stream.of(fields).forEach(field->{
try {
Component component = (Component)field.get(null);
if(frame!=component) {
frame.add(component);
}
} catch (Exception e) {e.printStackTrace(); }
});
}catch(Throwable th) {th.printStackTrace();}
frame.setVisible(true);
}
public static void main(String...arguments) {}
}
Label和Button在代码编码与系统编码不同时显示中文会乱码
package labelJLabel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.stream.Stream;
import javax.swing.*;
public class Label和Button在代码编码与系统编码不同时中文会乱码 {
static Label label = new Label("Label在.java代码编码与系统编码不同时,显示中文会乱码");
static JLabel jlabel = new JLabel("JLabel在.java代码编码与系统编码不同时,显示中文不会乱码");
static Button button = new Button("Button在.java代码编码与系统编码不同时,显示中文会乱码");
static JButton jbutton = new JButton("JButton在.java代码编码与系统编码不同时,显示中文不会乱码");
public static void main(String...arguments) {
Frame frame = new Frame(Thread.currentThread().getStackTrace()[1].getClassName());
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {System.exit(0);}
});
frame.setLayout(new GridLayout(0, 2, 5, 5)); frame.setBounds(100, 50, 1600, 900);
try {
throw new Exception("不要大惊小怪");
}catch(Throwable th) {th.printStackTrace();
try {
Field fields[] = Class.forName(th.getStackTrace()[0].getClassName()).getDeclaredFields();
Stream.of(fields).forEach(field->{
if(field.getModifiers()==Modifier.STATIC) {
try {
Component component = (Component)field.get(null);
component.setBackground(Color.CYAN);
component.setFont(new Font("", Font.BOLD, 25));
frame.add(component);
}catch(Exception ex) {}
}
});
}catch(Exception ex) {}
}
frame.setVisible(true);
}
}
在BorderLayout中的效果对比
测试1
Label在BorderLayout中的效果
package labelJLabel;
import java.awt.* ;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Label在BorderLayout中的效果 {
static Frame root = new Frame("Label在BorderLayout中的效果");
static {
root.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent ev) {System.exit(0);}
});
root.setBounds(100, 100, 1600, 900);
}
public static void main(String...arguments) {
final Label LabelEast = new Label("LabelEast"); root.add(LabelEast, BorderLayout.EAST);
final Label LabelWest = new Label("LabelWest"); root.add(LabelWest, BorderLayout.WEST);
final Label LabelSouth = new Label("LabelSouth"); root.add(LabelSouth, BorderLayout.SOUTH);
final Label LabelNorth = new Label("LabelNorth"); root.add(LabelNorth, BorderLayout.NORTH);
final Label LabelCenter = new Label("LabelCenter"); root.add(LabelCenter);
Color colors[] = new Color[] {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE};
for(int i=0; i<root.getComponentCount(); i++) {
Component child = root.getComponent(i); child.setBackground(colors[i]);
}
root.setVisible(true);
}
}
JLabel在BorderLayout中的效果
package labelJLabel;
import java.awt.* ;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class JLabel在BorderLayout中的效果 {
static Frame root = new Frame("JLabel在BorderLayout中的效果");
static {
root.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent ev) {System.exit(0);}
});
root.setBounds(100, 100, 1600, 900);
}
public static void main(String...arguments) {
final JLabel JLabelEast = new JLabel("JLabelEast"); root.add(JLabelEast, BorderLayout.EAST);
final JLabel JLabelWest = new JLabel("JLabelWest"); root.add(JLabelWest, BorderLayout.WEST);
final JLabel JLabelSouth = new JLabel("JLabelSouth"); root.add(JLabelSouth, BorderLayout.SOUTH);
final JLabel JLabelNorth = new JLabel("JLabelNorth"); root.add(JLabelNorth, BorderLayout.NORTH);
final JLabel JLabelCenter = new JLabel("JLabelCenter"); root.add(JLabelCenter);
Color colors[] = new Color[] {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE};
for(int i=0; i<root.getComponentCount(); i++) {
Component child = root.getComponent(i); child.setBackground(colors[i]);
if(child instanceof JLabel) {((JLabel)child).setOpaque(true);}
}
root.setVisible(true);
}
}
可看出
Label和JLabel都被BorderLayout拉伸了
JLabel比Label字体粗
Label比JLabel宽一点, 字体后宽度有余量
在FlowLayout中的效果对比
测试代码1
package labelJLabel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.*;
public class LabelJLabel在FlowLayout中的效果 {
static Frame frame;
static ArrayList<Label> labelAl = new ArrayList<>();
static ArrayList<JLabel> jlabelAl = new ArrayList<>();
static {
try {
frame = (Frame)Frame.class.getDeclaredConstructor(String.class).newInstance("LabelJLabel在FlowLayout中的效果");
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {System.exit(0);}
});
frame.setBounds(100, 50, 1600, 900);
FlowLayout flowLayout = new FlowLayout(); frame.setLayout(flowLayout);
}catch(Throwable th) {th.printStackTrace();}
for(int c=0; c<200; c++) {
Font font = new Font("", Font.PLAIN, 20);
Label lb = new Label("Label-"+c); labelAl.add(lb); frame.add(lb); lb.setBackground(new Color(0,255,188));
lb.setFont(font);
JLabel jlb = new JLabel("JLabel-"+c); jlabelAl.add(jlb); frame.add(jlb); jlb.setBackground(new Color(0,188,255)); jlb.setOpaque(true);
jlb.setFont(font);
}
frame.setVisible(true);
}
public static void main(String...arguments) {}
}
Label的右边有空白 , JLabel紧贴
在Box或BoxLayout中的效果对比
在 BoxLayout.Y_AXIS 中的效果, Label被拉伸, JLabel没被拉伸
package labelJLabel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LabelJLabel在VBox中的效果 {
static Frame frame = new Frame("LabelJLabel在VBox中的效果");
public static void main(String...arguments) {
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {frame.dispose();System.exit(0);}
});
frame.setBounds(100, 50, 1600, 900);
frame.setLayout(new BoxLayout(frame, BoxLayout.Y_AXIS));
for(int c=0;c<5;c++) {
Label lb = new Label("Label-"+c); frame.add(lb); lb.setBackground(Color.YELLOW);
JLabel jlb=new JLabel("JLabel-"+c); frame.add(jlb); jlb.setBackground(Color.BLUE); jlb.setOpaque(true);
}
frame.setVisible(true);
}
}
Label被拉伸, JLabel没被拉伸
在 BoxLayout.X_AXIS 中的效果, Label被拉伸, JLabel没被拉伸
package labelJLabel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LabelJLabel在HBox中的效果 {
static Frame frame = new Frame("LabelJLabel在HBox中的效果");
public static void main(String...arguments) {
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent event) {frame.dispose();System.exit(0);}
});
frame.setBounds(100, 50, 1600, 900);
frame.setLayout(new BoxLayout(frame, BoxLayout.X_AXIS));
for(int c=0;c<5;c++) {
Label lb = new Label("Label-"+c); frame.add(lb); lb.setBackground(Color.YELLOW);
JLabel jlb=new JLabel("JLabel-"+c); frame.add(jlb); jlb.setBackground(Color.BLUE); jlb.setOpaque(true);
}
frame.setVisible(true);
}
}
Label被拉伸, JLabel没被拉伸
性能对比 , JLabel竟然比Label快好多
加载9980个Label 用时 22079 毫秒
package labelJLabel;
import java.awt.*;
import java.awt.event.*;
public class 加载多个Label的用时 {
public static void main(String...arguments) {
long beginning = System.currentTimeMillis();
Frame frame = new Frame("加载一万个Label的用时");
frame.addWindowListener(new WindowAdapter() {@Override public void windowClosing(WindowEvent event) {frame.dispose();System.exit(0);}});
frame.setBounds(100,50,1600,800);
frame.setLayout(new FlowLayout());
for(int c=0;c<9980;c++) { // Win10下 9988 会报 Exception in thread "main" java.lang.InternalError: 当前程序已使用了 Window 管理器对象的系统允许的所有句柄。
Label lb = new Label("Label-"+c); lb.setBackground(Color.PINK);
frame.add(lb);
}
frame.setVisible(true);
long cost = System.currentTimeMillis()-beginning;
System.out.println("用时 "+cost+" 毫秒");
}
}
加载9980个JLabel 才用时 695 毫秒
package labelJLabel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JLabel;
public class 加载多个JLabel的用时 {
public static void main(String...arguments) {
long beginning = System.currentTimeMillis();
Frame frame = new Frame("加载一万个JLabel的用时");
frame.addWindowListener(new WindowAdapter() {@Override public void windowClosing(WindowEvent event) {frame.dispose();System.exit(0);}});
frame.setBounds(100,50,1600,800);
frame.setLayout(new FlowLayout());
for(int c=0;c<9980;c++) { // Win10下 9988个Label 会报 Exception in thread "main" java.lang.InternalError: 当前程序已使用了 Window 管理器对象的系统允许的所有句柄。
JLabel lb = new JLabel("JLabel-"+c); lb.setBackground(Color.PINK); lb.setOpaque(true);
frame.add(lb);
}
frame.setVisible(true);
long cost = System.currentTimeMillis()-beginning;
System.out.println("用时 "+cost+" 毫秒");
}
}
加载 5万个JLabel 用时 19394 毫秒 比9000个Label还快, 没有windows句柄限制
package labelJLabel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JLabel;
public class 加载多个JLabel的用时 {
public static void main(String...arguments) {
long beginning = System.currentTimeMillis();
Frame frame = new Frame("加载一万个JLabel的用时");
frame.addWindowListener(new WindowAdapter() {@Override public void windowClosing(WindowEvent event) {frame.dispose();System.exit(0);}});
frame.setBounds(100,50,1600,800);
frame.setLayout(new FlowLayout());
for(int c=0;c<50000;c++) { // Win10下 9988个Label 会报 Exception in thread "main" java.lang.InternalError: 当前程序已使用了 Window 管理器对象的系统允许的所有句柄。
JLabel lb = new JLabel("JLabel-"+c); lb.setBackground(Color.PINK); lb.setOpaque(true);
frame.add(lb);
}
frame.setVisible(true);
long cost = System.currentTimeMillis()-beginning;
System.out.println("用时 "+cost+" 毫秒");
}
}