Java自定义JSlider UI

JSlider作为Swing中提供的滑标组件, 以图形方式在有界区间内通过移动滑块来选择值,滑块可以显示主刻度标记和次刻度标记。大量应用于如播放器中的音量设定等领域中。

但是JSlider本身提供的UI样式很单调,不足以满足用户的审美需求,往往需要我们自行重构其UI。

下面我给出一个简单的例子。

package org.loon.framework.swing.test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/***/ /**
*<p>
*Title:LoonFramework
*</p>
*<p>
*Description:
*</p>
*<p>
*Copyright:Copyright(c)2007
*</p>
*<p>
*Company:LoonFramework
*</p>
*
*
@authorchenpeng
*@email:ceponline@yahoo.com.cn
*
@version0.1
*/

public class ExampleSlider extends JPanel ... {
/***//**
*
*/

privatestaticfinallongserialVersionUID=1L;

publicExampleSlider()...{
//设定布局器
super(newBorderLayout());
//设定监听器
ChangeListenerlistener=newChangeListener()...{
publicvoidstateChanged(ChangeEvente)...{
if(e.getSource()instanceofJSlider)...{
System.out.println(
"刻度:"
+((JSlider)e.getSource()).getValue());
}

}

}
;
//设定JSlider1
JSliders1=newJSlider(0,100,0);
//注入自定义ui
s1.setUI(newMySliderUI());
//主刻度
s1.setMajorTickSpacing(10);
//次刻度
s1.setMinorTickSpacing(5);
//设定为显示
s1.setPaintTicks(true);
s1.setPaintLabels(
true);
//监听slider1
s1.addChangeListener(listener);
//设定JSlider2
JSliders2=newJSlider(0,100,0);
//使用MetalSliderUI为ui
s2.setUI(newjavax.swing.plaf.metal.MetalSliderUI()...{
protectedvoidpaintHorizontalLabel(Graphicsg,intv,Componentl)...{
JLabellbl
=(JLabel)l;
lbl.setForeground(Color.green);
super.paintHorizontalLabel(g,v,lbl);
}

}
);

s2.setForeground(Color.BLUE);
s2.setMajorTickSpacing(
10);
s2.setMinorTickSpacing(
5);
s2.setPaintTicks(
true);
s2.setPaintLabels(
true);
s2.addChangeListener(listener);

//使用盒式容器
Boxbox=Box.createVerticalBox();
box.add(Box.createVerticalStrut(
5));
box.add(s1);
box.add(Box.createVerticalStrut(
5));
box.add(s2);
box.add(Box.createVerticalGlue());
add(box,BorderLayout.CENTER);
add(Box.createHorizontalStrut(
5),BorderLayout.WEST);
add(Box.createHorizontalStrut(
5),BorderLayout.EAST);
//设定窗体大小
setPreferredSize(newDimension(240,100));
}


publicstaticvoidmain(String[]args)...{
EventQueue.invokeLater(
newRunnable()...{
publicvoidrun()...{
createUI();
}

}
);
}


publicstaticvoidcreateUI()...{
JFrameframe
=newJFrame("音量刻度设置");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(
newExampleSlider());
frame.setResizable(
false);
frame.pack();
//居中
frame.setLocationRelativeTo(null);
frame.setVisible(
true);
}

}


class MySliderUI extends javax.swing.plaf.metal.MetalSliderUI ... {
/***//**
*绘制指示物
*/

publicvoidpaintThumb(Graphicsg)...{
Graphics2Dg2d
=(Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
//填充椭圆框为当前thumb位置
g2d.fillOval(thumbRect.x,thumbRect.y,thumbRect.width,
thumbRect.height);
//也可以帖图(利用鼠标事件转换image即可体现不同状态)
//g2d.drawImage(image,thumbRect.x,thumbRect.y,thumbRect.width,thumbRect.height,null);
}


/***//**
*绘制刻度轨迹
*/

publicvoidpaintTrack(Graphicsg)...{
intcy,cw;
RectangletrackBounds
=trackRect;
if(slider.getOrientation()==JSlider.HORIZONTAL)...{
Graphics2Dg2
=(Graphics2D)g;
cy
=(trackBounds.height/2)-2;
cw
=trackBounds.width;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.translate(trackBounds.x,trackBounds.y
+cy);

//背景设为灰色
g2.setPaint(Color.GRAY);
g2.fillRect(
0,-cy,cw,cy*2);

inttrackLeft=0;

inttrackRight=0;

trackRight
=trackRect.width-1;

intmiddleOfThumb=0;

intfillLeft=0;

intfillRight=0;

//坐标换算
middleOfThumb=thumbRect.x+(thumbRect.width/2);
middleOfThumb
-=trackRect.x;

if(!drawInverted())...{
fillLeft
=!slider.isEnabled()?trackLeft:trackLeft+1;
fillRight
=middleOfThumb;
}
else...{
fillLeft
=middleOfThumb;
fillRight
=!slider.isEnabled()?trackRight-1
:trackRight
-2;
}

//设定渐变
g2.setPaint(newGradientPaint(0,0,newColor(0,100,100),cw,0,
newColor(0,255,100),true));
g2.fillRect(
0,-cy,fillRight-fillLeft,cy*2);

g2.setPaint(slider.getBackground());
Polygonpolygon
=newPolygon();
polygon.addPoint(
0,cy);
polygon.addPoint(
0,-cy);
polygon.addPoint(cw,
-cy);
g2.fillPolygon(polygon);
polygon.reset();

g2.setPaint(Color.WHITE);
g2.drawLine(
0,cy,cw-1,cy);

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2.translate(
-trackBounds.x,-(trackBounds.y+cy));
}
else...{
super.paintTrack(g);
}

}

}



效果图:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值