Swing/OverlapBorderPaintLayer の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/OverlapBorderPaintLayer へ行く。
- Swing/OverlapBorderPaintLayer の差分を削除
--- category: swing folder: OverlapBorderPaintLayer title: JLayerで隣接する別コンポーネント上に縁を描画 tags: [JLayer, JRadioButton, JPanel, Icon] author: aterai pubdate: 2013-12-16T00:12:50+09:00 description: JLayerを使用して隣接する別コンポーネント上にも縁や影を描画します。 image: https://lh5.googleusercontent.com/-VshDpoewqBc/Uq2wDsedThI/AAAAAAAAB8g/TFMskJO7jys/s800/OverlapBorderPaintLayer.png --- * 概要 [#summary] `JLayer`を使用して隣接する別コンポーネント上にも縁や影を描画します。 #download(https://lh5.googleusercontent.com/-VshDpoewqBc/Uq2wDsedThI/AAAAAAAAB8g/TFMskJO7jys/s800/OverlapBorderPaintLayer.png) * サンプルコード [#sourcecode] #code(link){{ class BreadcrumbLayerUI extends LayerUI<JPanel> { private Shape shape; @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); if (shape != null) { Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Rectangle r = new Rectangle(c.getWidth(), c.getHeight()); Area area = new Area(r); area.subtract(new Area(shape)); g2.setClip(area); g2.setPaint(new Color(0x55_66_66_66, true)); g2.setStroke(new BasicStroke(3f)); g2.draw(shape); g2.setStroke(new BasicStroke(2f)); g2.draw(shape); g2.setStroke(new BasicStroke(1f)); g2.setClip(r); g2.setPaint(Color.WHITE); g2.draw(shape); g2.dispose(); } } @Override public void installUI(JComponent c) { super.installUI(c); if (c instanceof JLayer) { ((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); } } @Override public void uninstallUI(JComponent c) { if (c instanceof JLayer) { ((JLayer) c).setLayerEventMask(0); } super.uninstallUI(c); } private void update(MouseEvent e, JLayer<? extends JPanel> l) { int id = e.getID(); Shape s = null; if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_MOVED) { Component c = e.getComponent(); if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton) c; if (b.getIcon() instanceof ToggleButtonBarCellIcon) { ToggleButtonBarCellIcon icon = (ToggleButtonBarCellIcon) b.getIcon(); Rectangle r = c.getBounds(); AffineTransform at = AffineTransform.getTranslateInstance(r.x, r.y); s = at.createTransformedShape(icon.area); } } } if (!Objects.equals(s, shape)) { shape = s; l.getView().repaint(); } } @Override protected void processMouseEvent( MouseEvent e, JLayer<? extends JPanel> l) { update(e, l); } @Override protected void processMouseMotionEvent( MouseEvent e, JLayer<? extends JPanel> l) { update(e, l); } } }} * 解説 [#explanation] 上記のサンプルでは、`JLayer#processMouseEvent(...)`と`JLayer#processMouseMotionEvent(...)`メソッドをオーバーライドして、カーソルの下にある`JRadioButton`を取得し、その周辺に`JLayer#paint(...)`メソッドを使って影と縁を描画しています。 - `JLayer`を使用しているのでこれらの影と縁は各コンポーネントより一番手前の別レイヤーに上書き可能 - `JLayer#processMouseEvent(...)`と`JLayer#processMouseMotionEvent(...)`メソッドをオーバーライドしてカーソルの下にある`JRadioButton`を取得し、その周辺に`JLayer#paint(...)`メソッドを使って影と縁を描画 -- `JLayer`を使用しているのでこれらの影と縁は各コンポーネントより一番手前の別レイヤーに上書き可能 -- 隣接したり奥に重なったりしているコンポーネントなどの上に描画が可能 * 参考リンク [#reference] - [[FlowLayoutでボタンを重ねてパンくずリストを作成する>Swing/BreadcrumbList]] - [[JMenuItemの内部にJButtonを配置する>Swing/ButtonsInMenuItem]] * コメント [#comment] #comment #comment