Java自定义JSlider UI

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>
 * 
 * 
@author chenpeng
 * @email:ceponline@yahoo.com.cn
 * 
@version 0.1
 
*/

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

    
private static final long serialVersionUID = 1L;

    
public ExampleSlider() ...{
        
// 设定布局器
        super(new BorderLayout());
        
// 设定监听器
        ChangeListener listener = new ChangeListener() ...{
            
public void stateChanged(ChangeEvent e) ...{
                
if (e.getSource() instanceof JSlider) ...{
                    System.out.println(
"刻度: "
                            
+ ((JSlider) e.getSource()).getValue());
                }

            }

        }
;
        
// 设定JSlider1
        JSlider s1 = new JSlider(01000);
        
// 注入自定义ui
        s1.setUI(new MySliderUI());
        
// 主刻度
        s1.setMajorTickSpacing(10);
        
// 次刻度
        s1.setMinorTickSpacing(5);
        
// 设定为显示
        s1.setPaintTicks(true);
        s1.setPaintLabels(
true);
        
// 监听slider1
        s1.addChangeListener(listener);
        
// 设定JSlider2
        JSlider s2 = new JSlider(01000);
        
// 使用MetalSliderUI为ui
        s2.setUI(new javax.swing.plaf.metal.MetalSliderUI() ...{
            
protected void paintHorizontalLabel(Graphics g, int v, Component l) ...{
                JLabel lbl 
= (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);

        
//使用盒式容器
        Box box = 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(new Dimension(240100));
    }


    
public static void main(String[] args) ...{
        EventQueue.invokeLater(
new Runnable() ...{
            
public void run() ...{
                createUI();
            }

        }
);
    }


    
public static void createUI() ...{
        JFrame frame 
= new JFrame("音量刻度设置");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(
new ExampleSlider());
        frame.setResizable(
false);
        frame.pack();
        
//居中
        frame.setLocationRelativeTo(null);
        frame.setVisible(
true);
    }

}


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

    
public void paintThumb(Graphics g) ...{
        Graphics2D g2d 
= (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);
    }


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

    
public void paintTrack(Graphics g) ...{
        
int cy, cw;
        Rectangle trackBounds 
= trackRect;
        
if (slider.getOrientation() == JSlider.HORIZONTAL) ...{
            Graphics2D g2 
= (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);

            
int trackLeft = 0;

            
int trackRight = 0;

            trackRight 
= trackRect.width - 1;

            
int middleOfThumb = 0;

            
int fillLeft = 0;

            
int fillRight = 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(new GradientPaint(00new Color(0100100), cw, 0,
                    
new Color(0255100), true));
            g2.fillRect(
0-cy, fillRight - fillLeft, cy * 2);

            g2.setPaint(slider.getBackground());
            Polygon polygon 
= new Polygon();
            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);
        }

    }

}



效果图:
posted on 2007-12-18 14:05 cping 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/cping1982/archive/2007/12/18/2258085.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276980.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Chrome OS 云里雾里

昨天Google发布了ChromeOS&#xff0c;之前有牛人编译了它的源码并创建了虚拟机分享出来。具体的BT种子不记得了&#xff0c;有需要的可以搜索一下chromeos-image-999.999.32309.211410-a1.vmdk.bz2。看看哪还有种子可用。文件大概287M左右&#xff0c;解压后大概7、8百M。当下…

二叉树的遍历方式

2019独角兽企业重金招聘Python工程师标准>>> 二叉树遍历方式有三种&#xff1a;前序遍历&#xff0c;中序遍历&#xff0c;后序遍历&#xff08;其实还有一个层序遍历&#xff09; 使用两种方式来实现三种遍历&#xff1a; 1. 使用递归的方式实现 1&#xff09;&…

非常恶俗地分享一首歌曲(子陵·周郎顾)

歌词 [hjp3]hjptypesong&player5&filehttp://file.hjbbs.com/ayi/share/mp3/zhoulanggu.mp3&backColor990000&frontColorddddff&autoStarttrue&showDownloadtrue&width310&height20[/hjp3]子陵周郎顾 绿绮轻拂刹那玄冰破&#xff0c; 九霄仙音…

that is why用法

释义&#xff1a;这就是为什么&#xff0c;因此 Thats why I was getting married. ---《老友记》 第一季 第一集 这就是我为什么结婚的原因。 例句&#xff1a; Mr. Gorbachev, on the other hand, recognized that his sluggish and authoritarian bureaucracy was the worst…

阿里云超算集谛优化GPU异构并行性能:GROMACS

“集谛”是一款内置于阿里云弹性高性能计算(Elastic High Performance Computing&#xff0c;E-HPC)的云上性能监控与分析引擎&#xff0c;支持集群资源利用情况的实时监控和用户作业运行情况的在线分析。对于采用GPU加速的异构计算应用场景&#xff0c;“集谛”除了监控节点ho…

MySQl看这一篇就够了

MySQl看这一篇就够了 MySQL分享 一、数据库结构 语句 DDL&#xff08;Data Definition Languages&#xff09;&#xff1a;数据定义语句&#xff0c;常用的语句关键字主要包括 create、drop、alter等操作表结构 DML&#xff08;Data Manipulation Language&#xff09;&#xf…

IDEA 实用功能Auto Import:自动优化导包(自动删除、导入包)

JetBrains公司的intellij Idea堪称JAVA编程界的苹果&#xff0c;用户体验非常好 下面介绍一下IDEA的一个能显著提升写代码效率的非常好用的功能设置—— Auto Import Auto Import的功能是可以帮助我们自动删除无用的包Import(未被引用)&#xff0c;以及自动Import填充尚未导入的…

怎么看网站是否被黑防止网站被黑

2019独角兽企业重金招聘Python工程师标准>>> 网站被黑&#xff0c;打开网站竟然跳转到博cai网站上去了&#xff0c;一开始以为自己看错了&#xff0c;多次从百度点击自己网站进去&#xff0c;还是会跳转到彩piao网站上&#xff0c;第一反应是自己的网站被黑了&#…

c#事务的使用、示例及注意事项

一、事务的介绍.NET Framework 开发员指南事务是一组组合成逻辑工作单元的操作&#xff0c;虽然系统中可能会出错&#xff0c;但事务将控制和维护事务中每个操作的一致性和完整性。例如&#xff0c;在将资金从一个帐户转移到另一个帐户的银行应用中&#xff0c;一个帐户将一定的…

Nginx学习系列二Linux下Nginx实现负载均衡

关于在本地虚拟机(VMware 14)下安装Linux同时安装Nginx,请参考Nginx学习系列之搭建环境 1、启动Nginx 在Nginx安装成功的前提下,启动Nginx 已root模式登陆(权限需要),接着找到Nginx的安装目录,启动Nginx,并且指定Nginx启动所需的配置文件,该文件也在Nginx的安装目录下. 2、查看…

设计模式初学者系列-策略模式 -------为什么总是继承

设计模式初学者系列&#xff0d;策略模式 -------为什么总是继承 模板方法的延续 这篇稿子是基于我的前一篇模板方法设计模式之上演绎的&#xff0c;如果没有阅读请点击这里查看&#xff0c;以了解这篇稿子的上下文。 在模板方法设计模式里我举了一个例子&#xff1a;教育部…

红米airdots掉了怎么查找_红米K30 Pro 荣耀V30pro 这两款手机该怎么选呢?

点击?玩机数码君?关注我&#xff0c;加★星标★你好 我是岁月神偷昨天可以说是小米拍手称快的一天&#xff0c;红米K30 Pro以2999的超低价成为目前最便宜的骁龙865旗舰&#xff0c;让友商拍马难追。友商明眼人都知道说的华为&#xff0c;怎么感觉小米每次发布会也替华为宣传了…

返回一个循环整数组最大子数组和

任务要求&#xff1a; 1、输入一个整形数组&#xff0c;数组里有正数也有负数。 2、数组中连续的一个或多个整数组成一个子数组&#xff0c;每个子数组都有一个和。 3、如果数组A[0]……A[j-1]首尾相邻&#xff0c;允许A[i-1]&#xff0c; …… A[n-1]&#xff0c; A[0]……A…

4K 海思 联咏 芯片_老电视也有春天,换装海美迪4K电视盒子H7 Plus

写在前面YALL&#xff0c;大家好&#xff0c;我是老炮儿许老板。疫情进入六月逐渐好转&#xff0c;各级各类学校相继开学&#xff0c;年前给儿子报的托班也终于迎来了开学&#xff0c;平日里帮忙照看儿子的爷爷奶奶也终于得到了解放。现在白天有大把大把的时间来追剧看电视&…

WCF从理论到实践(4):路在何方

本文的出发点 通过阅读本文&#xff0c;您能了解以下知识&#xff1a; Address是什么&#xff1f; Address的组成&#xff1f; 如何在配置文件中指定Address? 如何通过编程方式设置Address? Address有什么特殊应用&#xff1f; 本文适合的读者 适合WCF初学者&#xff…

office 2007图标_微软Office 365桌面版新图标开始测试

IT之家3月1日消息 此前&#xff0c;微软公布了全新的Office图标&#xff0c;微软Office 365在线网页版在2月15日开始已经全面更新新版图标&#xff0c;而桌面版Office 365现在也陆续开始测试新版图标。目前微软Office Dogfood通道上推送的开发者预览版本已经在2月27日开始测试O…

【动态规划BFS】相遇

这是我第一次模拟题测试点全部AC。。。 同机房的DALAO都用的BFS 然而我用的DP&#xff08;其实不会BFS&#xff09; 话不多说&#xff0c;上题&#xff01; &#xff08;灰常详细&#xff09;DP解法&#xff1a; 重点还是状态转移方程式的推导 1个点i要么是后面的位置i-1往前走…

五个思路,教你如何建立金融业的数据分析管理模型

说起银行、保险、股票投资这样的金融行业&#xff0c;很多人都认为它们是依靠数据驱动的企业&#xff0c;毕竟大数据的诞生本来就是为了金融信息流通而服务的&#xff0c;但在我身边很多搞证券、投资的朋友看来&#xff0c;事实却并非如此。 真正在金融行业做数据分析的人&…

【SSH网上商城项目实战19】订单信息的级联入库以及页面的缓存问题

购物车这一块还剩最后两个问题&#xff0c;就是订单信息的级联入库和页面缓存&#xff0c;这里的信息是指购物车和购物项&#xff0c;即我们将购物车的信息存入数据库的同时&#xff0c;也存入每个购物项的信息&#xff0c;而且外键都关联好&#xff0c;这涉及到了Hibernate中的…

exfat分配单元大小选多少_安防监控摄像机视角大小和镜头毫米数的基础知识!...

关于选择监控镜头毫米数的问题&#xff0c;虽然只有新手才有此困惑&#xff0c;但是我们还是要认真地说一说。监控视角&#xff0c;就是指监控照射的镜头所能覆盖到的范围&#xff0c;就是监控画面所能看到的角度统称叫监控视角。我们正常选购监控的时候&#xff0c;除了可以选…