Swing/GradientTrackSlider のバックアップの現在との差分(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/GradientTrackSlider へ行く。
- 1 (2011-06-05 (日) 22:38:45)
- 2 (2012-12-21 (金) 19:11:06)
- 3 (2012-12-22 (土) 16:36:25)
- 4 (2012-12-26 (水) 06:00:35)
- 5 (2012-12-26 (水) 11:13:30)
- 6 (2014-12-02 (火) 01:29:07)
- 7 (2015-03-01 (日) 16:09:25)
- 8 (2015-03-20 (金) 15:30:21)
- 9 (2015-03-24 (火) 16:04:08)
- 10 (2015-07-08 (水) 16:58:41)
- 11 (2016-05-26 (木) 14:56:20)
- 12 (2017-08-10 (木) 14:40:29)
- 13 (2018-02-24 (土) 19:51:30)
- 14 (2018-08-15 (水) 20:30:15)
- 15 (2018-12-20 (木) 11:34:58)
- 16 (2020-11-15 (日) 01:58:30)
- 17 (2022-12-01 (木) 10:42:41)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JSliderのスタイルを変更する #navi(../) #tags(JSlider, LinearGradientPaint, Transparent, UIManager, Icon) RIGHT:Posted by &author(aterai); at 2011-05-23 *JSliderのスタイルを変更する [#idffa752] ``JSlider``のトラックとノブを透明にし、値を半透明の色で描画します。 --- category: swing folder: GradientTrackSlider title: JSliderのスタイルを変更する tags: [JSlider, LinearGradientPaint, Transparent, UIManager, Icon] author: aterai pubdate: 2011-05-23T15:19:26+09:00 description: JSliderのトラックとノブを透明にし、値を半透明の色で描画します。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TdnxSfPEQLI/AAAAAAAAA7k/vYTnJ_FPktg/s800/GradientTrackSlider.png hreflang: href: https://java-swing-tips.blogspot.com/2011/06/gradient-translucent-track-jslider.html lang: en --- * 概要 [#summary] `JSlider`のトラックとノブを透明にし、値を半透明の色で描画します。 -&jnlp; -&jar; -&zip; #download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TdnxSfPEQLI/AAAAAAAAA7k/vYTnJ_FPktg/s800/GradientTrackSlider.png) //#screenshot #ref(https://lh3.googleusercontent.com/_9Z4BYR88imo/TdnxSfPEQLI/AAAAAAAAA7k/vYTnJ_FPktg/s800/GradientTrackSlider.png) **サンプルコード [#wfa9a67f] * サンプルコード [#sourcecode] #code(link){{ UIManager.put("Slider.horizontalThumbIcon", new Icon() { @Override public void paintIcon(Component c, Graphics g, int x, int y) {} @Override public int getIconWidth() { return 15; } @Override public int getIconHeight() { return 64; } }); UIManager.put("Slider.trackWidth", 64); UIManager.put("Slider.majorTickLength", 6); JSlider slider = makeSlider(); slider.setUI(new MetalSliderUI() { int[] pallet = makeGradientPallet(); @Override public void paintTrack(Graphics g) { //Color trackColor = !slider.isEnabled() // ? MetalLookAndFeel.getControlShadow() : slider.getForeground(); // Color trackColor = !slider.isEnabled() // ? MetalLookAndFeel.getControlShadow() : slider.getForeground(); boolean leftToRight = true; //MetalUtils.isLeftToRight(slider); Color controlDarkShadow = Color.GRAY; Color controlHighlight = new Color(200,255,200); Color controlShadow = new Color(0,100,0); Color controlHighlight = new Color(200, 255, 200); Color controlShadow = new Color(0, 100, 0); g.translate( trackRect.x, trackRect.y ); g.translate(trackRect.x, trackRect.y); int trackLeft = 0; int trackTop = 0; int trackRight = 0; int trackBottom = 0; // Draw the track if(slider.getOrientation() == JSlider.HORIZONTAL) { if (slider.getOrientation() == SwingConstants.HORIZONTAL) { trackBottom = (trackRect.height - 1) - getThumbOverhang(); trackTop = trackBottom - (getTrackWidth() - 1); trackRight = trackRect.width - 1; }else{ if(leftToRight) { } else { if (leftToRight) { trackLeft = (trackRect.width - getThumbOverhang()) - getTrackWidth(); trackRight = (trackRect.width - getThumbOverhang()) - 1; }else{ } else { trackLeft = getThumbOverhang(); trackRight = getThumbOverhang() + getTrackWidth() - 1; } trackBottom = trackRect.height - 1; } if(slider.isEnabled()) { if (slider.isEnabled()) { g.setColor(controlDarkShadow); g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1, (trackBottom - trackTop) - 1); (trackRight - trackLeft) - 1, (trackBottom - trackTop) - 1); g.setColor(controlHighlight); g.drawLine(trackLeft + 1, trackBottom, trackRight, trackBottom); g.drawLine(trackRight, trackTop + 1, trackRight, trackBottom); g.setColor(controlShadow); g.drawLine(trackLeft + 1, trackTop + 1, trackRight - 2, trackTop + 1); g.drawLine(trackLeft + 1, trackTop + 1, trackLeft + 1, trackBottom - 2); } else { g.setColor(controlShadow); g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1, (trackBottom - trackTop) - 1); } // Draw the fill int middleOfThumb = 0; int fillTop = 0; int fillLeft = 0; int fillBottom = 0; int fillRight = 0; if(slider.getOrientation() == JSlider.HORIZONTAL) { if (slider.getOrientation() == SwingConstants.HORIZONTAL) { middleOfThumb = thumbRect.x + (thumbRect.width / 2); middleOfThumb -= trackRect.x; // To compensate for the g.translate() fillTop = !slider.isEnabled() ? trackTop : trackTop + 1; fillBottom = !slider.isEnabled() ? trackBottom - 1 : trackBottom - 2; if(!drawInverted()) { if (!drawInverted()) { fillLeft = !slider.isEnabled() ? trackLeft : trackLeft + 1; fillRight = middleOfThumb; }else{ } else { fillLeft = middleOfThumb; fillRight = !slider.isEnabled() ? trackRight - 1 : trackRight - 2; } }else{ } else { middleOfThumb = thumbRect.y + (thumbRect.height / 2); middleOfThumb -= trackRect.y; // To compensate for the g.translate() fillLeft = !slider.isEnabled() ? trackLeft : trackLeft + 1; fillRight = !slider.isEnabled() ? trackRight - 1 : trackRight - 2; if(!drawInverted()) { if (!drawInverted()) { fillTop = middleOfThumb; fillBottom = !slider.isEnabled() ? trackBottom - 1 : trackBottom - 2; }else{ } else { fillTop = !slider.isEnabled() ? trackTop : trackTop + 1; fillBottom = middleOfThumb; } } if(slider.isEnabled()) { if (slider.isEnabled()) { g.setColor(slider.getBackground()); g.drawLine(fillLeft, fillTop, fillRight, fillTop ); g.drawLine(fillLeft, fillTop, fillLeft, fillBottom ); double x = (fillRight - fillLeft) / (double)(trackRight - trackLeft); double x = (fillRight - fillLeft) / (double) (trackRight - trackLeft); g.setColor(getColorFromPallet(pallet, x)); g.fillRect(fillLeft+1,fillTop+1,fillRight-fillLeft,fillBottom-fillTop); }else{ g.fillRect(fillLeft + 1, fillTop + 1, fillRight - fillLeft, fillBottom - fillTop); } else { g.setColor(controlShadow); g.fillRect(fillLeft,fillTop,fillRight-fillLeft,trackBottom-trackTop); g.fillRect(fillLeft, fillTop, fillRight - fillLeft, trackBottom - trackTop); } int yy = trackTop + (trackBottom - trackTop) /2; for(int i=10;i>=0;i--) { g.setColor( new Color(1f,1f,1f,i*0.07f) ); g.drawLine( trackLeft+2, yy, (trackRight - trackLeft), yy ); int yy = trackTop + (trackBottom - trackTop) / 2; for (int i = 10; i >= 0; i--) { g.setColor(new Color(1f, 1f, 1f, i * .07f)); g.drawLine(trackLeft + 2, yy, (trackRight - trackLeft), yy); yy--; } g.translate(-trackRect.x, -trackRect.y); } }); }} **解説 [#yc3103a1] 上記のサンプルでは、MetalSliderUI#paintTrack(...)メソッドをオーバーライドしたSliderUIを設定するなどして、JSliderの各スタイルを変更しています。 * 解説 [#explanation] 上記のサンプルでは、`MetalSliderUI#paintTrack(...)`メソッドをオーバーライドした`SliderUI`を設定するなどして、`JSlider`の各スタイルを変更しています。 - ``Track`` -- ``JSlider#setOpaque(false)``で透明化 -- ``MetalSliderUI#paintTrack(...)``内で、``Fill``の後でハイライトを描画 - ``Thumb`` -- ``UIManager.put("Slider.horizontalThumbIcon", emptyIcon)``で、空のアイコンを設定して非表示 - ``Fill`` -- ``MetalSliderUI#paintTrack(...)``内で、値に応じて``LinearGradientPaint``から作成した色で描画 - `Track` -- `JSlider#setOpaque(false)`で透明化 -- `MetalSliderUI#paintTrack(...)`内で`Fill`の後でハイライトを描画 - `Thumb` -- `UIManager.put("Slider.horizontalThumbIcon", emptyIcon)`で透明なアイコンを設定して非表示化 - `Fill` -- `MetalSliderUI#paintTrack(...)`内で値に応じて`LinearGradientPaint`から作成した色で描画 #code{{ private static int[] makeGradientPallet() { BufferedImage image = new BufferedImage(100, 1, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = image.createGraphics(); Point2D start = new Point2D.Float(0f, 0f); Point2D end = new Point2D.Float(99f, 0f); float[] dist = {0.0f, 0.5f, 1.0f}; Color[] colors = { Color.RED, Color.YELLOW, Color.GREEN }; Point2D end = new Point2D.Float(99f, 0f); float[] dist = {0f, .5f, 1f}; Color[] colors = {Color.RED, Color.YELLOW, Color.GREEN}; g2.setPaint(new LinearGradientPaint(start, end, dist, colors)); g2.fillRect(0, 0, 100, 1); int width = image.getWidth(null); int[] pallet = new int[width]; PixelGrabber pg = new PixelGrabber(image, 0, 0, width, 1, pallet, 0, width); try{ try { pg.grabPixels(); }catch(Exception e) { } catch (Exception e) { e.printStackTrace(); } return pallet; } private static Color getColorFromPallet(int[] pallet, float x) { int i = (int)(pallet.length * x); int i = (int) (pallet.length * x); int max = pallet.length-1; int index = i<0?0:i>max?max:i; int pix = pallet[index] & 0x00ffffff | (0x64 << 24); int index = i < 0 ? 0 : i > max ? max : i; int pix = pallet[index] & 0x00_FF_FF_FF | (0x64 << 24); return new Color(pix, true); } }} ---- メモ: - 例えば``WindowsLnF``では、``UIManager.get("Slider.trackWidth")``は``null``なので、``MetalSliderUI#installUI()``中にある以下のコードでエラーになる。 - 例えば`WindowsLookAndFeel`では`UIManager.get("Slider.trackWidth")`は`null`なので`MetalSliderUI#installUI()`中にある以下のコードでエラーになる -- `trackWidth = ( (Integer) UIManager.get("Slider.trackWidth") ).intValue();` -- なぜ`UIManager.getInt(...)`を使用しないのかは不明 -- `UIManager.put("Slider.majorTickLength", 6);`などで適当な値を代入して回避 -- `MetalSliderUI`ではなく`BasicSliderUI`を継承するべき? #code{{ trackWidth = ((Integer)UIManager.get("Slider.trackWidth")).intValue(); }} * 参考リンク [#reference] - [https://harmoniccode.blogspot.com/2011/05/varying-gradients.html Harmonic Code: Varying gradients...] - なぜ``UIManager.getInt(...)``ではない? - ``UIManager.put("Slider.majorTickLength", 6);``などで回避 - ``MetalSliderUI``ではなく、``BasicSliderUI``を継承するぺき? **参考リンク [#c91e29bf] - [http://harmoniccode.blogspot.com/2011/05/varying-gradients.html Harmonic Code: Varying gradients...] **コメント [#ne8506fc] * コメント [#comment] #comment #comment }}