Swing Synth L&F
来源:互联网 发布:baidu软件中心 编辑:程序博客网 时间:2024/06/02 17:26
Synth 是Java Swing 中使用XML文件对Swing的外观进行定义的一种方式, 不必了解过于细节的UI的实现方式,只要学会编写Synth的XML格式文件, 就可以实现自己的Swing漂亮的皮肤.
public class MainFrame extends JFrame { public static void main(String[] args) throws Exception { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { createAndShowUI(); } catch (Exception e) { e.printStackTrace(); } } }); } private static void createAndShowUI() throws Exception { SynthLookAndFeel lookAndFeel = new SynthLookAndFeel(); lookAndFeel.load(MainFrame.class.getResourceAsStream("/laf.xml"), MainFrame.class); UIManager.setLookAndFeel(lookAndFeel); MainFrame mainFrame = new MainFrame(); mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); mainFrame.setSize(800, 900); mainFrame.getContentPane().add(new ComponentSet()); mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); mainFrame.setBackground(new Color(43, 43, 43)); mainFrame.setVisible(true); }}import javax.swing.*;import java.awt.*;/** * Created by GuoLiang on 2016/1/9. */public class ComponentSet extends JPanel { public ComponentSet() { this.setLayout(new FlowLayout()); this.setBorder(BorderFactory.createEmptyBorder(30, /*top*/ 30, /*left*/ 10, /*bottom*/ 30) /*right*/); JTextField jTextField = new JTextField("我是输入框 hello", 100); jTextField.setSelectionColor(new Color(90, 117, 171)); this.add(jTextField); JTextField jTextField1 = new JTextField("我是输入框 hello", 100); jTextField1.setSelectionColor(new Color(90, 117, 171)); this.add(jTextField1); }}/** * Created by GuoLiang on 2016/1/9. */public class GradientPainter extends SynthPainter { public void paintTextFieldBackground(SynthContext context, Graphics g, int x, int y, int w, int h) { // For simplicity this always recreates the GradientPaint. In a // real app you should cache this to avoid garbage.// Graphics2D g2 = (Graphics2D) g;// g2.setColor(Color.decode("#cccccc"));// g2.setStroke(new BasicStroke(1.5f));// g2.drawRoundRect(x+1, y+1, w-2, h-2, 5, 5); Graphics2D g2 = (Graphics2D) g; g2.fillRect(x, y, w, h); g2.setStroke(new BasicStroke(1f)); g2.setColor(new Color(69, 73, 74)); g2.fillRoundRect(x + 2, y + 2, w - 3, h - 3, 10, 10); g2.setColor(new Color(100, 100, 100)); g2.drawRoundRect(x + 1, y + 1, w - 2, h - 2, 10, 10); }}laf.xml文件:<!--<?xml version="1.0" encoding="UTF-8"?>--><!--<!DOCTYPE synth PUBLIC "-//oracle.com//DTD swign synth configuration 1.0//EN" "https://docs.oracle.com/javase/8/docs/api/javax/swing/plaf/synth/doc-files/synth.dtd">--><synth> <!-- Style that all regions will use --> <style id="backingStyle"> <!-- Make all the regions opaque--> <opaque value="TRUE"/> <font name="微软雅黑" size="12"/> <state> <!-- Provide default colors --> <color value="#2B2B2B" type="BACKGROUND"/> <color value="#ffffff" type="FOREGROUND"/> </state> </style> <bind style="backingStyle" type="REGION" key=".*"/> <style id="buttonStyle"> <!-- Shift the text one pixel when pressed --> <property key="Button.textShiftOffset" type="integer" value="0"/> <insets top="10" left="10" right="10" bottom="10"/> <state> <imagePainter method="buttonBackground" path="images/button.png" sourceInsets="10 10 10 10"/> </state> <state value="PRESSED"> <imagePainter method="buttonBackground" path="images/button2.png" sourceInsets="10 10 10 10"/> </state> </style> <!-- Bind buttonStyle to all JButtons --> <bind style="buttonStyle" type="REGION" key="button"/> <style id="textfield"> <opaque value="TRUE" /> <object id="gradient" class="com.lang.swing.GradientPainter"/> <state> <painter method="textFieldBackground" idref="gradient"/> </state> <state value="SELECTED"> </state> <insets top="4" left="4" right="4" bottom="4"/> </style> <bind style="textfield" type="REGION" key="textfield"/></synth>
<synth> <style id="basicStyle"> <font name="Verdana" size="16"/> <state> <color value="WHITE" type="BACKGROUND"/> <color value="BLACK" type="FOREGROUND"/> </state> </style> <bind style="basicStyle" type="region" key=".*"/></synth>说明:style标签,可以表述多个region,一般用一个style表现一个元素; style标签有个id属性,这个id属性是用在下面的bind标签中.style下的font 设置了字体.state标签下面会继续讨论.region的state可以有一个或多个.如果有有元素没有设置对应的type,那么将使用全局的state,bind标签,将上面声明的style样式,应用到了.*所有的元素上.------------------------------------------------------------------------------------------------------------------------bind标签: style标签定义完成之后,如果想使其生效,必须将其绑定到components或regions上. bind标签必须含有三个属性: 1). style必须有id,并且id是唯一的 2). type: name/region.如果为name,对应的是Component.getName()的返回值,如果为region,则使用javax.swing.plaf.synth.Region中的常量. 3). key: key为一个正则表达式,用于将样式绑定到匹配的components/regions上.Key中Region是用标识一个component或者component的一部分,对应的是Region中的常量中去掉下划线的部分.比如:SPLIT_PANE -> SPLITPANE, splitpane 或者 SplitPane (大小写不敏感).下面有个简答的例子:<style id="styleOne"> <!-- styleOne definition goes here --></style><style id="styleTwo"> <!-- styleTwo definition goes here --></style><bind style="styleOne" type="region" key="Button"/><bind style="styleOne" type="region" key="RadioButton"/><bind style="styleOne" type="region" key="ArrowButton"/><bind style="styleTwo" type="region" key="ArrowButton"/>可以绑定到一个单独的/已命名的component; 如果有两个按钮 "OK" 和 "Cancel",但你想将这两个按钮与其它的按钮区别对待,首先你可以给Ok和Cancel取个名字,使用 component.setName() 方法, 然后定义三个样式,第一个为普通的按钮(region = "Button"), 第一个是为 OK 按钮 (name = "OK"), 第三个是为 Cancel 按钮 (name = "Cancel").就像下面的这样:<bind style="styleButton" type="region" key="Button"><bind style="styleOK" type="name" key="OK"><bind style="styleCancel" type="name" key="Cancel">"OK"按钮有两个样式 "styleButton" 和 "styleOK," "Cancel" 按钮也有两个样式 "styleButton" 和 "styleCancel."当一个component/region有多个样式的时候,会进行合并Note:在样式进行合并时,文件后面声明的样式优先.------------------------------------------------------------------------------------------------------------------------state标签: 用于定义元素的状态,如按钮的"PRESSED","ENABLED"不同的状态.ENABLED, MOUSE_OVER, PRESSED, DISABLED, FOCUSED, SELECTED, DEFAULT可以使用 and 一次指定多个状态,如: ENABLED and FOCUSED. 如果没有指定value,那么这个state将会作为默认的state, 并且会应用到所有的state上面.As an example, here is a style that specifies painters per state. All buttons are painted a certain way, unless the state is "PRESSED," in which case they are painted differently:<style id="buttonStyle"> <property key="Button.textShiftOffset" type="integer" value="1"/> <insets top="10" left="10" right="10" bottom="10"/> <state> // 注意:这个state没有value,会作为默认的state,按钮的所有状态都会有这个样式 <imagePainter method="buttonBackground" path="images/button.png" sourceInsets="10 10 10 10"/> </state> <state value="PRESSED"> // 注意:只有在按钮被按下后,才会有这个state声明的样式 <color value="#9BC3B1" type="BACKGROUND"/> <imagePainter method="buttonBackground" path="images/button2.png" sourceInsets="10 10 10 10"/> </state></style><bind style="buttonStyle" type="region" key="Button"/>region会选择匹配最接近的state,匹配时会根据value中的的个数进行匹配. 如果和声明的state没有匹配,则使用没有value的state<state id="zero"> <color value="RED" type="BACKGROUND"/></state><state value="SELECTED and PRESSED" id="one"> <color value="RED" type="BACKGROUND"/></state><state value="SELECTED" id="two"> <color value="BLUE" type="BACKGROUND"/></state>如果region的state保研 SELECTED and PRESSED, 则选择 state one. 若state含有 SELECTED, 但不含 PRESSED, 则选择state two . 若 SELECTED nor PRESSED 一个都没有, 则选择 state zero.如果region的当前state满足多个state的value, 那么会选择第一个state, 比如按钮的MOUSE_OVER 与 PRESSED, 谁在前就选谁.<state value="PRESSED"> <imagePainter method="buttonBackground" path="images/button_press.png" sourceInsets="9 10 9 10" /> <color type="TEXT_FOREGROUND" value="#FFFFFF"/></state><state value="MOUSE_OVER"> <imagePainter method="buttonBackground" path="images/button_on.png" sourceInsets="10 10 10 10" /> <color type="TEXT_FOREGROUND" value="#FFFFFF"/></state>------------------------------------------------------------------------------------------------------------------------颜色和字体:<color>的属性:value:java.awt.Color中的常量,如:RED, WHITE, BLACK, BLUE,也可以是16进制表示的颜色,如:#FF00FF or #326A3B.type:降颜色应用给谁,如: BACKGROUND, FOREGROUND, FOCUS, TEXT_BACKGROUND, OR TEXT_FOREGROUND.如: <style id="basicStyle"> <state> <color value="WHITE" type="BACKGROUND"/> <color value="BLACK" type="FOREGROUND"/> </state> </style><font> 的属性:name: 字体的名称,如:Arial or Verdana.size: 字体的像素大小.style[可选]: 如: BOLD, ITALIC, 或 BOLD ITALIC. 默认为normal.如: <style id="basicStyle"> <font name="Verdana" size="16"/> </style><color>,<font>还有另外一种使用方式,加一个id,可以重用,在另一个<color/font>中使用idref进行引用.<color id="backColor" value="WHITE" type="BACKGROUND"/><font id="textFont" name="Verdana" size="16"/><color idref="backColor"/><font idref="textFont"/>------------------------------------------------------------------------------------------------------------------------内边距:Insets : <insets top="15" left="20" right="20" bottom="15"/>------------------------------------------------------------------------------------------------------------------------使用图片:Synth可以使用图片. Synth的 image painter 将图片切分为9个部分: top, top right, right, bottom right, bottom, bottom left, left, top left, and center.top, left, bottom, and right edges are 平铺/拉伸的, 四个角的图片保持原样 (原图:sourceInsets).Note:<insets>和sourceInsets无关,是相互独立的.中间的区域可以使用paintCenter属性,指定是否要画上去.如果希望图片的四个角的不会被拉伸,可以设置sourceInsets 为 10.<style id="buttonStyle"> <insets top="15" left="20" right="20" bottom="15"/> <state> <imagePainter method="buttonBackground" path="images/button.png" sourceInsets="10 10 10 10"/> </state></style><bind style="buttonStyle" type="region" key="button"/><imagePainter>的属性:method: 使用javax.swing.plaf.synth.SynthPainter 中的方法进行绘制,有100种方法,paintButtonBackground -> buttonBackground (去掉paint,剩下的首字母小写即可)path: 图片的路径,相对于SynthLookAndFeel.load方法中指定的Class路径sourceInsets: 指定使用原图,不尽兴拉伸绘制的大小,顺序如下:上、左、下、右.paintCenter[可选]: 是否绘制center区域,(如果是文本框,可以为false).The listing below shows the XML code for loading different images depending on the <state> of the button <style id="buttonStyle"> <property key="Button.textShiftOffset" type="integer" value="1"/> <insets top="15" left="20" right="20" bottom="15"/> <state> <imagePainter method="buttonBackground" path="images/button.png" sourceInsets="10 10 10 10"/> </state> <state value="PRESSED"> <imagePainter method="buttonBackground" path="images/button2.png" sourceInsets="10 10 10 10"/> </state> </style> <bind style="buttonStyle" type="region" key="button"/>下面这行的作用,是在按钮按下时,文字向右移动一个像素:<property key="Button.textShiftOffset" type="integer" value="1"/>------------------------------------------------------------------------------------------------------------------------<property>的属性:使用键值对给元素设置外观:key—属性的名称type—属性的类型value—属性的值下面的地址可以查看每个component可以使用那些属性:https://docs.oracle.com/javase/8/docs/api/javax/swing/plaf/synth/doc-files/componentProperties.html--- 一个简单的例子---------------------------------------------------------------------------------------------------------<!-- Synth skin that includes an image for buttons --><synth> <!-- Style that all regions will use --> <style id="backingStyle"> <!-- Make all the regions that use this skin opaque--> <opaque value="TRUE"/> <font name="Dialog" size="12"/> <state> <!-- Provide default colors --> <color value="#9BC3B1" type="BACKGROUND"/> <color value="RED" type="FOREGROUND"/> </state> </style> <bind style="backingStyle" type="region" key=".*"/> <style id="buttonStyle"> <!-- Shift the text one pixel when pressed --> <property key="Button.textShiftOffset" type="integer" value="1"/> <insets top="15" left="20" right="20" bottom="15"/> <state> <imagePainter method="buttonBackground" path="images/button.png" sourceInsets="10 10 10 10"/> </state> <state value="PRESSED"> <imagePainter method="buttonBackground" path="images/button2.png" sourceInsets="10 10 10 10"/> </state> </style> <!-- Bind buttonStyle to all JButtons --> <bind style="buttonStyle" type="region" key="button"/></synth>------------------------------------------------------------------------------------------------------------------------使用图标:单选框和浮选,可以使用固定大小的图标:<style id="radioButton"> <imageIcon id="radio_off" path="images/radio_button_off.png"/> <imageIcon id="radio_on" path="images/radio_button_on.png"/> <property key="RadioButton.icon" value="radio_off"/> <state value="SELECTED"> <property key="RadioButton.icon" value="radio_on"/> </state></style><bind style="radioButton" type="region" key="RadioButton"/>------------------------------------------------------------------------------------------------------------------------特殊情况下比较有用:自定义画笔: 不使用图片,而是使用自定义的颜色(渐变的颜色等)进行定义样式:<synth> <object id="gradient" class="GradientPainter"/> <style id="textfield"> <painter method="textFieldBackground" idref="gradient"/> </style> <bind style="textfield" type="region" key="textfield"/></synth>GradientPainter 类的定义如下:public class GradientPainter extends SynthPainter { public void paintTextFieldBackground(SynthContext context, Graphics g, int x, int y, int w, int h) { // For simplicity this always recreates the GradientPaint. In a // real app you should cache this to avoid garbage. Graphics2D g2 = (Graphics2D)g; g2.setPaint(new GradientPaint((float)x, (float)y, Color.WHITE, (float)(x + w), (float)(y + h), Color.RED)); g2.fillRect(x, y, w, h); g2.setPaint(null); }}------------------------------------------------------------------------------------------------------------------------
1 0
- Swing Synth L&F
- NimROD L&F swing UI
- Swing Synth外观定制UI
- Java Swing Synth - JRadioButton Style
- L-F-S
- for /d /r /l /f
- 高级 Synth
- 高级 Synth
- 千年之恋(F.L.R)
- f i n a l 的注意事项
- 好的测试(Q\L\G\F)
- A、D、S、L、C、F、I
- f i n a l 的注意事项
- C语言中常量后缀,u或U,l或L,f或F问题
- def f(x,l=[]): for i in range(x): l.append(i*i) print l
- java中的Synth外观
- java中的Synth外观
- ExeInfo PE ver.0.0.0.8 f by A.S.L
- Git忽略规则及.gitignore规则不生效的解决办法
- WebView的简单讲解
- JavaScript > 使用JSONP或HttpClient跨域请求
- 设计模式之Builder模式
- MySql导入导出数据库(含远程导入导出)
- Swing Synth L&F
- 207,省市联动效果
- Visual Studio CUDA文件高亮设置 win10+VS2015+CUDA7.5
- 进入保护模式(一)——《x86汇编语言:从实模式到保护模式》读书笔记12
- c语言学习
- 在TextView周围添加图片
- 第2章 基础语法 — 循环语句
- android animation rotate to specific angle
- VC 生成 exe 可执行程序 然后在cmd窗口调用