Swing使用Substance外观包异常问题
问题一: 今天更新我的Java版QQ,在网上找到了Substance外观包,效果不错,直接用了,可是设置水印问题时就出现问题,网上有现成的例子
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
try {
SubstanceImageWatermark watermark = new SubstanceImageWatermark(LoginFrame. class .getResourceAsStream( " /demo/001.jpg " ));
watermark.setKind(ImageWatermarkKind.SCREEN_CENTER_SCALE);
SubstanceSkin skin = new OfficeBlue2007Skin().withWatermark(watermark); //初始化有水印的皮肤
UIManager.setLookAndFeel( new SubstanceOfficeBlue2007LookAndFeel());
SubstanceLookAndFeel.setSkin(skin); //设置皮肤
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(LoginFrame. class .getName()).log(Level.SEVERE, null , ex);
}
可是在我导入的包里死活包withWatermark方法不存在,于是就Google,最后看到一哥们说,自从subtance6.0以后就去掉了withWatermark设置水印方法,原因貌似是不安全,可是想用水印的效果呢?那你就换成substance5.0版本吧!换了之后果然能用了效果图:北京比较淡,水印不明显。
问题二:使用subtance出现异常UIDefaults.getUI() failed: 和org.jvnet.substance.api.UiThreadingViolationException,有一前辈说是包不能识别啥的,就我遇到的问题,只是换了皮肤之后框架布局变了,不在于能不能用的问题,关键还是在代码上,我遇到的这个问题就在于我的代码设置问题,先把我的部分代码贴出来分析一下:
package com.client.frm;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.api.SubstanceSkin;
import org.jvnet.substance.api.SubstanceConstants.ImageWatermarkKind;
import org.jvnet.substance.skin.OfficeBlue2007Skin;
import org.jvnet.substance.skin.SubstanceOfficeBlue2007LookAndFeel;
import org.jvnet.substance.watermark.SubstanceImageWatermark;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import tools.PicturePane;
import data.ChatMessage;
import data.FriendUser;
import data.Portrait;
import data.QQMessage;
import data.UserState;
public class UserMainView extends JFrame implements ActionListener {
/**
* @author Mackalli
× 2011/10/3
*/
private static final long serialVersionUID = 1L;
private JButton btnPhoto;
private JComboBox jcbState;
private JLabel lblNickName;
private JTextArea areaSignature;
private JLabel lblLoginBar = new JLabel();
private JButton btnLoginCancel;
private JPanel fillWidth = new FillWidth(300, 200,false);
private JButton btnZone;
private JButton btnEmail;
private JButton btnNews;
private JButton btnShop;
private JButton btnSkin;
//Color bgColor = new Color(211, 234, 224);
private JList listFriend;
private DefaultListModel listModel = null;
// Integer存入的类型(K-此映射所维护的键的类型),ChatView对应映射(V - 所映射值的类型)
private HashMap<Integer, ChatView> chat;
FriendUser friendUser = null;
private FriendUser selfUser = null;
private Vector<FriendUser> v;
private ObjectInputStream ois;
private ObjectOutputStream oos;
String QQ_NickName;
String QQ_Num;
Integer photo;
Integer QQ_State;
String signature;
JPopupMenu popupMenu;
JMenuItem itemChat;
JMenuItem itemDelete;
JMenuItem itemFriendInfo;
private JButton btnFind;
private JButton btnHelp;
//private SystemTray systemTray=null;
private SystemTray tray=null;
static TrayIcon trayIcon=null; // 静态托盘图标,收到信息闪动提醒
private Image trayImage=null;
private PopupMenu popupTray=new PopupMenu(); //托盘列表
private MenuItem itemExit=new MenuItem("退出");
private MenuItem itemSetSound=new MenuItem("关闭声音");
private PicturePane bgPane=new PicturePane();
private static SearchView searchView;
private TrayThread trayThread=null;
private static boolean isAvailable=true; //设置声音默认开启,在托盘中设置,就两种形式,故用static
//ChatView isVisible
private boolean isShow=false;
private boolean isOpenMsg=false;
//if message is new
private boolean isNewMessage=false;
private ChatView chatView;
public UserMainView(ObjectOutputStream oos, ObjectInputStream ois,
Vector<FriendUser> v) {
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
try {
SubstanceImageWatermark watermark = new SubstanceImageWatermark(
UserMainView.class
.getResourceAsStream("/client/images/backImages/2.jpg "));
watermark.setKind(ImageWatermarkKind.SCREEN_CENTER_SCALE);
SubstanceSkin skin = new OfficeBlue2007Skin()
.withWatermark(watermark); // 初始化有水印的皮肤
UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel());
SubstanceLookAndFeel.setSkin(skin); // 设置皮肤
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(UserMainView.class.getName()).log(Level.SEVERE,
null, ex);
}
this.oos = oos;
this.ois = ois;
this.v = v;
setTitle("QQ_li");
setSize(280, 630);
setResizable(false);
// getContentPane().setBackground(bgColor);
// this.setContentPane(bgPane);
setLocation(920, 60);
this.addWindowListener(new WindowAdapter() {
public void windowIconified(WindowEvent e) {
setVisible(false);
}
});
addTray();
initMainView(v);
setVisible(true);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
QQMessage message = new QQMessage();
message.setType(77);
message.setObj(selfUser);
new WriteThread(message).start();
System.out.println(selfUser.getNickName() + "退出了");
chat = null;
UserMainView.this.dispose();
System.exit(0);
}
});
}
这是一个类,时刻要记得UIManager设置前提,放在构造方法的最前面,调用时要用到Swing工作线程 SwingUtilities.invokeLater()来调用,我在LoginView中调用的方法:
//userMainView = new UserMainView(oos, ois, v); // 加载用户信
SwingUtilities.invokeLater(new Runnable() {
public void run() { userMainView = new UserMainView(oos, ois, v); // 加载用户信息 userMainView.setVisible(true); } }); LoginView.this.setVisible(false);
}
当你出现上述异常时是不是直接
userMainView = new UserMainView(oos, ois, v); // 加载用户信息
没有少量一句,SwingUtilities.invokeLater(new Runnable()} 这是Swing工作形式,我的最后出来结果了,和以前系统默认的就是大小比例的不同,不再抛出异常,我认为是代码的问题,这是今天的收获写出来大家分享一下,希望对一些困惑的朋友
有所帮助,我们这一行很多问题就要自己解决,太多的差异网上的东西只能是参考!Good luck,friends!
最后感谢Java.net的精英们制作出来这么漂亮的Swing外观来! GNU-UP UP!!!!!!
对你有所帮助就收藏一下,大家一起分享程序的快乐!