如何使 JProgressBar 匹配 Windows LaF? [英] How to make JProgressBar match Windows LaF?

查看:24
本文介绍了如何使 JProgressBar 匹配 Windows LaF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 WindowsLookAndFeelJProgressBar 上工作了一段时间,但我发现与原生进度条有一些主要区别:

I've been working for a while with JProgressBar using WindowsLookAndFeel, but I found some major differences from the native progress bar:

这是正常状态下的原生栏:

Here is the native bar, in its regular state:

虽然这是 Java 的:

While this is Java's:

敏锐的眼睛可能会看到 Java 的顶部白色更亮,绿色也更亮一点.本机也是填充"的.而 Java 的边框是空的.

A sharp eye might see Java's top white color much brighter, and the green a little brighter too. Also the native is "filled" while Java's has an empty border.

现在,本机不确定:

和 Java 的:

闪烁更短,速度也更快(未显示).此外,由于本机看起来像一个发光体,Java 看起来很像一颗彗星".(有尾巴,只有一侧……).

The flicker is much shorter, and much much faster (not shown). Also as the native could look like a glow, Java's looks much like a "comet" (with a tail, only from one side...).

还有我的最后一个问题,被屏蔽的栏:

And my final question, the blocked bar:

这可以用 Java 完成吗?

Can this be done in Java?

推荐答案

  • 这只是最后一个问题的一个例子:
    • Windows 7(绿色进度条)
    • JDK 1.7.0_25 (WindowsLookAndFeel)
    • import java.awt.*;
      import java.awt.event.*;
      import java.awt.image.*;
      import java.beans.*;
      import javax.swing.*;
      import javax.swing.plaf.LayerUI;
      
      public class TurnProgressBarRedTest {
        public JComponent makeUI() {
          final BoundedRangeModel model = new DefaultBoundedRangeModel();
          final BlockedColorLayerUI layerUI = new BlockedColorLayerUI();
          final JPanel p = new JPanel(new GridLayout(4, 1, 12, 12));
          p.setBorder(BorderFactory.createEmptyBorder(24,24,24,24));
      
          final JProgressBar pb1 = new JProgressBar(model);
          pb1.setStringPainted(true);
          p.add(pb1);
          final JProgressBar pb2 = new JProgressBar(model);
          pb2.setStringPainted(true);
          p.add(pb2);
      
          p.add(new JProgressBar(model));
          p.add(new JLayer<JProgressBar>(new JProgressBar(model), layerUI));
      
          JPanel box = new JPanel();
          box.add(new JButton(new AbstractAction("+10") {
            private int i = 0;
            @Override public void actionPerformed(ActionEvent e) {
              model.setValue(i = (i>=100) ? 0 : i + 10);
            }
          }));
          //http://msdn.microsoft.com/en-us/library/windows/desktop/aa511486.aspx
          box.add(new JCheckBox(new AbstractAction(
              "<html>Turn the progress bar red<br />"+
              " when there is a user recoverable condition<br />"+
              " that prevents making further progress.") {
            @Override public void actionPerformed(ActionEvent e) {
              boolean b = ((JCheckBox)e.getSource()).isSelected();
              pb2.setForeground(b? new Color(255,0,0,100) : pb1.getForeground());
              layerUI.isPreventing = b;
              p.repaint();
            }
          }));
      
          JPanel panel = new JPanel(new BorderLayout());
          panel.add(p, BorderLayout.NORTH);
          panel.add(box, BorderLayout.SOUTH);
          return panel;
        }
        public static void main(String[] args) {
          EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
              createAndShowGUI();
            }
          });
        }
        public static void createAndShowGUI() {
          try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
          } catch(Exception e) {
            e.printStackTrace();
          }
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          f.getContentPane().add(new TurnProgressBarRedTest().makeUI());
          f.setSize(320, 240);
          f.setLocationRelativeTo(null);
          f.setVisible(true);
        }
      }
      class BlockedColorLayerUI extends LayerUI<JProgressBar> {
        public boolean isPreventing = false;
        private BufferedImage bi;
        private int prevw = -1;
        private int prevh = -1;
        @Override public void paint(Graphics g, JComponent c) {
          if(isPreventing) {
            JLayer jlayer = (JLayer)c;
            JProgressBar progress = (JProgressBar)jlayer.getView();
            int w = progress.getSize().width;
            int h = progress.getSize().height;
      
            if(bi==null || w!=prevw || h!=prevh) {
              bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            }
            prevw = w;
            prevh = h;
      
            Graphics2D g2 = bi.createGraphics();
            super.paint(g2, c);
            g2.dispose();
      
            Image image = c.createImage(
                            new FilteredImageSource(bi.getSource(),
                            new RedGreenChannelSwapFilter()));
            g.drawImage(image, 0, 0, null);
          } else {
            super.paint(g, c);
          }
        }
      }
      class RedGreenChannelSwapFilter extends RGBImageFilter {
        @Override public int filterRGB(int x, int y, int argb) {
          int r = (int)((argb >> 16) & 0xff);
          int g = (int)((argb >>  8) & 0xff);
          int b = (int)((argb      ) & 0xff);
          return (argb & 0xff000000) | (g<<16) | (r<<8) | (b);
        }
      }
      

      这篇关于如何使 JProgressBar 匹配 Windows LaF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆