【问题标题】:Creating a volume slider for VLCJ audio为 VLCJ 音频创建音量滑块
【发布时间】:2020-07-29 11:28:13
【问题描述】:

我正在尝试创建一个音量级别条,其中不同级别的音量用不同的颜色表示这是我的方法

我有 2 个数组

Color[] scales 为每个音量级别提供不同的颜色表示,如果这个数组的长度是 4,那么有 4 个音量级别,依此类推

float[] 权重表示每种颜色应在条形中占据多少百分比/空间

例如

private final Color scales[]={Color.GREEN,Color.YELLOW,Color.RED};
private final float weights[]={0.3f,0.2f,0.5f};

表示有 3 个级别的音量

  1. 如果当前音量

  2. 如果当前成交量 >30% 且

  3. 如果当前音量 >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 媒体播放器中的音量条

请原谅模糊,我不得不放大图像,但如果你仔细观察,你会注意到颜色在边界处是如何混合的,例如从绿色到黄色的渐变在边界和那里之间产生了一些白色是从黄色到红色的渐变,在两者之间形成一些橙色

我想实现这个渐变。

有什么想法吗?

【问题讨论】:

  • 哪一个是线性的或径向的?我以前从未使用过这些颜料,所以请在这里帮助我
  • 线性的应该做,径向的从中心到圆的尽头。
  • 那么,您是否查看了 每个图像的 Java 文档中显示的图像“帮帮我”“给男人一条鱼..”
  • 问题是我在问这里之前尝试了这些颜料。 LinearGradient 要求权重按递增顺序排列,否则我会得到一个非法参数异常,但从我的示例中您可以看到我的权重完全相反,径向根本不符合我的目的。我需要一条更异国情调的鱼

标签: java swing gradient


【解决方案1】:

按照@AndrewThompson 在上述 cmets 中的建议,您可以使用 MultipleGradientPaintLinearGradientPaint

目前我很困惑你需要哪两个,上面你说:

  1. 如果当前音量

  2. 如果当前交易量 >30% 并且

  3. 如果当前音量 >50% 并且

然后你说:

我需要 60% 的绿色条形图,然后 20% 的黄色条形图,而不是 LinearGradient 需要的其他方式。你明白为什么现在会出现问题了吗?

但这些只是数字。

您可以通过这种方式创建您的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);
    }
}

【讨论】:

  • 我现在明白了。我以为我们在谈论剩余的百分比值,所以我真的很困惑。如果我能感谢你,我会投票两次
  • 但我确实有一个问题,你为什么使用 getCenterY()?如果我只使用 miny=0 和 maxY=getSize()。身高有什么区别?
  • 我发布了整个代码,试一试看看会发生什么。没有区别,我就是这样开始的,就是这样。因为它在重复,所以你使用哪一个没有区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2021-11-28
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多