为 VLCJ 音频创建音量滑块
Creating a volume slider for VLCJ audio
我正在尝试创建一个音量级别条,其中不同级别的音量用不同的颜色表示,这是我的方法
我有 2 个数组
Color[]
刻度为每个音量级别提供不同的颜色表示,如果这个数组的长度是 4,则有 4 个音量级别,依此类推
float[]
权重表示 percentage/space 每种颜色在栏中应占多少
例如
private final Color scales[]={Color.GREEN,Color.YELLOW,Color.RED};
private final float weights[]={0.3f,0.2f,0.5f};
表示有 3 个级别的音量,其中
如果当前音量 <= 最大值的 30%,则 30% 的音量条被绿色覆盖
如果当前音量 >30% 且 <= (30+20)=50%,则音量栏的下一个 20% 会被黄色覆盖
如果当前音量 >50% 且 <= (50+50)=100%,则音量条的最后 50% 会被红色覆盖
现在用户通过单击和拖动鼠标与音量条交互,因此假设音量条是否具有尺寸 (x=120,y=50) 并假设我单击或拖动直到 Xposition=25 然后
30% of 120=36
XPosition=25
25<36 hence must draw an green color rect of dimensions x=0,y=0,width=36-25=12,height=50
对于剩余的位置,我们继续计算用户点击的位置,并在该点之前绘制不同颜色的矩形。
现在我想我把解释搞砸了,但我不是要我已经在这里实现的代码
final class VolumeBar extends JPanel
{
VolumeBar()
{
super(new BorderLayout());
add(Box.createRigidArea(new Dimension(500,100)),BorderLayout.NORTH);
add(Box.createRigidArea(new Dimension(500,100)),BorderLayout.SOUTH);
JPanel container=new JPanel(new BorderLayout());
container.add(Box.createRigidArea(new Dimension(120,50)),BorderLayout.WEST);
container.add(Box.createRigidArea(new Dimension(120,50)),BorderLayout.EAST);
container.add(new JVolume(),BorderLayout.CENTER);
add(container,BorderLayout.CENTER);
}
private final class JVolume extends JLabel
{
private final Color scales[]={Color.GREEN,Color.YELLOW,Color.RED};
private final float weights[]={0.6f,0.2f,0.2f};
private int endingX;
private JVolume()
{
addMouseMotionListener(new Drag());
addMouseListener(new Click());
setPreferredSize(new Dimension(260,50));
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
Dimension size=getSize();
float endPoints[]=new float[scales.length+1];
endPoints[0]=0;
for(int i=1;i<endPoints.length;i++){endPoints[i]=endPoints[i-1]+(size.width*weights[i-1]);}
for(int i=1;i<endPoints.length;i++)
{
float
prev=endPoints[i-1],
current=endPoints[i];
if(endingX>prev)
{
g2d.setColor(scales[i-1]);
g2d.fill(new Rectangle2D.Float(prev,0,endingX>current?current-prev:endingX-prev,size.height));
}
else{break;}
}
g2d.setColor(getBackground());
Polygon clear=new Polygon();
clear.addPoint(0,0);
clear.addPoint(size.width,0);
clear.addPoint(0,size.height);
clear.addPoint(0,0);
g2d.fill(clear); //clear the upper left triangle with background to make it look like an increasing triangle
g2d.setColor(Color.BLACK); draw the lower right triangle to give the bar some border
Polygon polygon=new Polygon();
polygon.addPoint(1,size.height-1);
polygon.addPoint(size.width-1,1);
polygon.addPoint(size.width-1,size.height-1);
polygon.addPoint(1,size.height-1);
g2d.drawPolygon(polygon);
}
private void compute(MouseEvent m)
{
endingX=m.getX();
repaint();
}
private final class Drag extends MouseMotionAdapter
{
@Override
public void mouseDragged(MouseEvent m){compute(m);}
}
private final class Click extends MouseAdapter
{
@Override
public void mouseClicked(MouseEvent m){compute(m);}
}
}
}
下面是它的外观,只需单击或拖动栏上的任意位置
大部分看起来很棒,但我的目标是 VLC 媒体播放器中的音量条
请原谅模糊,我不得不按比例放大图像,但如果你仔细观察,你会注意到颜色在边界处是如何混合的,例如有一个从绿色到黄色的渐变,在边界处中间有一些白色并且有一个从黄色到红色的渐变,中间有一些橙色
我想实现这个渐变。
有人有想法吗?
正如@AndrewThompson 在上面的评论中所推荐的,您可以使用 MultipleGradientPaint
使用 LinearGradientPaint
.
目前我对你需要哪两个感到困惑,上面你说:
if the current volume is <=30% of max then 30% of the volume bar is covered in GREEN
if the current volume is >30% and <= (30+20)=50% the next 20% of the volume bar is covered in YELLOW
if the current volume is >50% and <= (50+50)=100% the final 50% of the volume bar is covered in RED
然后你说:
I need 60% of my bar in green then 20% in yellow not the other way around which is what LinearGradient requires.you see why it's a problem now?
但这些只是数字。
您可以这样创建 LinearGradientPaint
:
Rectangle2D rect = new Rectangle2D.Double(10, 10, 250, 150);
Point2D startPoint = new Point2D.Double(rect.getMinX(), rect.getCenterY());
Point2D endPoint = new Point2D.Double(rect.getMaxX(), rect.getCenterY());
float[] percentages = new float[] {0.0f, 0.6f, 0.8f};
Color[] colors = new Color[] {Color.GREEN, Color.YELLOW, Color.RED};
LinearGradientPaint gradient = new LinearGradientPaint(startPoint, endPoint, percentages, colors, CycleMethod.REPEAT);
您对需要从哪里开始渐变感到困惑,因为我猜您的百分比是:0.6f, 0.2f, 0.2f
但您需要定义起点,然后从那里添加下一个百分比,0.0f, 0.6f, 0.8f
(这将从 0% 开始,然后上升到 60% 变为绿色,然后上升到 80% 变为黄色,然后其余变为 100% 变为红色。
你得到这个输出。
MRE 供您测试更改:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.RenderingHints;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class LinearGradientExample {
private JFrame frame;
private JPanel pane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new LinearGradientExample()::createAndShowGUI);
}
@SuppressWarnings("serial")
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
Rectangle2D rect = new Rectangle2D.Double(10, 10, 250, 150);
Point2D startPoint = new Point2D.Double(rect.getMinX(), rect.getCenterY());
Point2D endPoint = new Point2D.Double(rect.getMaxX(), rect.getCenterY());
float[] percentages = new float[] {0.0f, 0.6f, 0.8f};
Color[] colors = new Color[] {Color.GREEN, Color.YELLOW, Color.RED};
LinearGradientPaint gradient = new LinearGradientPaint(startPoint, endPoint, percentages, colors, CycleMethod.REPEAT);
pane = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(gradient);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fill(rect);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
};
frame.add(pane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
我正在尝试创建一个音量级别条,其中不同级别的音量用不同的颜色表示,这是我的方法
我有 2 个数组
Color[]
刻度为每个音量级别提供不同的颜色表示,如果这个数组的长度是 4,则有 4 个音量级别,依此类推
float[]
权重表示 percentage/space 每种颜色在栏中应占多少
例如
private final Color scales[]={Color.GREEN,Color.YELLOW,Color.RED};
private final float weights[]={0.3f,0.2f,0.5f};
表示有 3 个级别的音量,其中
如果当前音量 <= 最大值的 30%,则 30% 的音量条被绿色覆盖
如果当前音量 >30% 且 <= (30+20)=50%,则音量栏的下一个 20% 会被黄色覆盖
如果当前音量 >50% 且 <= (50+50)=100%,则音量条的最后 50% 会被红色覆盖
现在用户通过单击和拖动鼠标与音量条交互,因此假设音量条是否具有尺寸 (x=120,y=50) 并假设我单击或拖动直到 Xposition=25 然后
30% of 120=36
XPosition=25
25<36 hence must draw an green color rect of dimensions x=0,y=0,width=36-25=12,height=50
对于剩余的位置,我们继续计算用户点击的位置,并在该点之前绘制不同颜色的矩形。
现在我想我把解释搞砸了,但我不是要我已经在这里实现的代码
final class VolumeBar extends JPanel
{
VolumeBar()
{
super(new BorderLayout());
add(Box.createRigidArea(new Dimension(500,100)),BorderLayout.NORTH);
add(Box.createRigidArea(new Dimension(500,100)),BorderLayout.SOUTH);
JPanel container=new JPanel(new BorderLayout());
container.add(Box.createRigidArea(new Dimension(120,50)),BorderLayout.WEST);
container.add(Box.createRigidArea(new Dimension(120,50)),BorderLayout.EAST);
container.add(new JVolume(),BorderLayout.CENTER);
add(container,BorderLayout.CENTER);
}
private final class JVolume extends JLabel
{
private final Color scales[]={Color.GREEN,Color.YELLOW,Color.RED};
private final float weights[]={0.6f,0.2f,0.2f};
private int endingX;
private JVolume()
{
addMouseMotionListener(new Drag());
addMouseListener(new Click());
setPreferredSize(new Dimension(260,50));
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
Dimension size=getSize();
float endPoints[]=new float[scales.length+1];
endPoints[0]=0;
for(int i=1;i<endPoints.length;i++){endPoints[i]=endPoints[i-1]+(size.width*weights[i-1]);}
for(int i=1;i<endPoints.length;i++)
{
float
prev=endPoints[i-1],
current=endPoints[i];
if(endingX>prev)
{
g2d.setColor(scales[i-1]);
g2d.fill(new Rectangle2D.Float(prev,0,endingX>current?current-prev:endingX-prev,size.height));
}
else{break;}
}
g2d.setColor(getBackground());
Polygon clear=new Polygon();
clear.addPoint(0,0);
clear.addPoint(size.width,0);
clear.addPoint(0,size.height);
clear.addPoint(0,0);
g2d.fill(clear); //clear the upper left triangle with background to make it look like an increasing triangle
g2d.setColor(Color.BLACK); draw the lower right triangle to give the bar some border
Polygon polygon=new Polygon();
polygon.addPoint(1,size.height-1);
polygon.addPoint(size.width-1,1);
polygon.addPoint(size.width-1,size.height-1);
polygon.addPoint(1,size.height-1);
g2d.drawPolygon(polygon);
}
private void compute(MouseEvent m)
{
endingX=m.getX();
repaint();
}
private final class Drag extends MouseMotionAdapter
{
@Override
public void mouseDragged(MouseEvent m){compute(m);}
}
private final class Click extends MouseAdapter
{
@Override
public void mouseClicked(MouseEvent m){compute(m);}
}
}
}
下面是它的外观,只需单击或拖动栏上的任意位置
大部分看起来很棒,但我的目标是 VLC 媒体播放器中的音量条
请原谅模糊,我不得不按比例放大图像,但如果你仔细观察,你会注意到颜色在边界处是如何混合的,例如有一个从绿色到黄色的渐变,在边界处中间有一些白色并且有一个从黄色到红色的渐变,中间有一些橙色
我想实现这个渐变。
有人有想法吗?
正如@AndrewThompson 在上面的评论中所推荐的,您可以使用 MultipleGradientPaint
使用 LinearGradientPaint
.
目前我对你需要哪两个感到困惑,上面你说:
if the current volume is <=30% of max then 30% of the volume bar is covered in GREEN
if the current volume is >30% and <= (30+20)=50% the next 20% of the volume bar is covered in YELLOW
if the current volume is >50% and <= (50+50)=100% the final 50% of the volume bar is covered in RED
然后你说:
I need 60% of my bar in green then 20% in yellow not the other way around which is what LinearGradient requires.you see why it's a problem now?
但这些只是数字。
您可以这样创建 LinearGradientPaint
:
Rectangle2D rect = new Rectangle2D.Double(10, 10, 250, 150);
Point2D startPoint = new Point2D.Double(rect.getMinX(), rect.getCenterY());
Point2D endPoint = new Point2D.Double(rect.getMaxX(), rect.getCenterY());
float[] percentages = new float[] {0.0f, 0.6f, 0.8f};
Color[] colors = new Color[] {Color.GREEN, Color.YELLOW, Color.RED};
LinearGradientPaint gradient = new LinearGradientPaint(startPoint, endPoint, percentages, colors, CycleMethod.REPEAT);
您对需要从哪里开始渐变感到困惑,因为我猜您的百分比是:0.6f, 0.2f, 0.2f
但您需要定义起点,然后从那里添加下一个百分比,0.0f, 0.6f, 0.8f
(这将从 0% 开始,然后上升到 60% 变为绿色,然后上升到 80% 变为黄色,然后其余变为 100% 变为红色。
你得到这个输出。
MRE 供您测试更改:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.RenderingHints;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class LinearGradientExample {
private JFrame frame;
private JPanel pane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new LinearGradientExample()::createAndShowGUI);
}
@SuppressWarnings("serial")
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
Rectangle2D rect = new Rectangle2D.Double(10, 10, 250, 150);
Point2D startPoint = new Point2D.Double(rect.getMinX(), rect.getCenterY());
Point2D endPoint = new Point2D.Double(rect.getMaxX(), rect.getCenterY());
float[] percentages = new float[] {0.0f, 0.6f, 0.8f};
Color[] colors = new Color[] {Color.GREEN, Color.YELLOW, Color.RED};
LinearGradientPaint gradient = new LinearGradientPaint(startPoint, endPoint, percentages, colors, CycleMethod.REPEAT);
pane = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(gradient);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fill(rect);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
};
frame.add(pane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}