Google Tag Manager

Showing posts with label JLabel. Show all posts
Showing posts with label JLabel. Show all posts

2018/12/27

aterai

Fade out JTabbedPane tab title on overflow instead of ellipsis

Code

class TextOverflowFadeTabbedPane extends ClippedTitleTabbedPane {
  protected TextOverflowFadeTabbedPane() {
    super();
  }

  protected TextOverflowFadeTabbedPane(int tabPlacement) {
    super(tabPlacement);
  }

  @Override public void insertTab(
        String title, Icon icon, Component component, String tip, int index) {
    super.insertTab(title, icon, component, Objects.toString(tip, title), index);
    JPanel p = new JPanel(new BorderLayout(2, 0));
    p.setOpaque(false);
    p.add(new JLabel(icon), BorderLayout.WEST);
    p.add(new TextOverflowFadeLabel(title));
    setTabComponentAt(index, p);
  }
}

class TextOverflowFadeLabel extends JLabel {
  private static final int LENGTH = 20;
  private static final float DIFF = .05f;

  protected TextOverflowFadeLabel(String text) {
    super(text);
  }

  @Override public void paintComponent(Graphics g) {
    Insets i = getInsets();
    int w = getWidth() - i.left - i.right;
    int h = getHeight() - i.top - i.bottom;
    Rectangle rect = new Rectangle(i.left, i.top, w - LENGTH, h);

    Graphics2D g2 = (Graphics2D) g.create();
    g2.setFont(g.getFont());
    g2.setPaint(getForeground());

    FontRenderContext frc = g2.getFontRenderContext();
    TextLayout tl = new TextLayout(getText(), getFont(), frc);
    int baseline = getBaseline(w, h);

    g2.setClip(rect);
    tl.draw(g2, getInsets().left, baseline);

    rect.width = 1;
    float alpha = 1f;
    for (int x = w - LENGTH; x < w; x++) {
      rect.x = x;
      alpha = Math.max(0f, alpha - DIFF);
      g2.setComposite(AlphaComposite.SrcOver.derive(alpha));
      g2.setClip(rect);
      tl.draw(g2, getInsets().left, baseline);
    }
    g2.dispose();
  }
}

References

2017/12/26

aterai

Automatically extend its height when JTextArea gains focus

Code

textArea.addFocusListener(new FocusAdapter() {
  @Override public void focusLost(FocusEvent e) {
    String text = textArea.getText();
    label.setText(text.isEmpty() ? " " : text);
    cardLayout.show(cp, "TextField");
  }
});
label.addFocusListener(new FocusAdapter() {
  @Override public void focusGained(FocusEvent e) {
    cardLayout.show(cp, "TextArea");
    textArea.requestFocusInWindow();
  }
});

References

2017/03/30

aterai

Make a condensed Font and use it with JTextArea

Code

Font font = new Font(Font.MONOSPACED, Font.PLAIN, 18).deriveFont(
    AffineTransform.getScaleInstance(.9, 1d));
textArea.setFont(font);

References

2016/06/27

aterai

Change the color of the label represents the current value of a JSlider

Code

slider.getModel().addChangeListener(new ChangeListener() {
  private int prev = -1;
  private void resetForeground(Object o, Color c) {
    if (o instanceof Component) {
      ((Component) o).setForeground(c);
    }
  }
  @Override public void stateChanged(ChangeEvent e) {
    BoundedRangeModel m = (BoundedRangeModel) e.getSource();
    int i = m.getValue();
    if ((slider.getMajorTickSpacing() == 0 ||
         i % slider.getMajorTickSpacing() == 0) && i != prev) {
      Dictionary dictionary = slider.getLabelTable();
      resetForeground(dictionary.get(i), Color.RED);
      resetForeground(dictionary.get(prev), Color.BLACK);
      slider.repaint();
      prev = i;
    }
  }
});

References

2014/02/26

aterai

Translucent JFrame repaint

Code

private final SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
private final JLabel label = new JLabel(df.format(new Date()), SwingConstants.CENTER);
private final TexturePanel tp;
private final Timer timer = new Timer(1000, new ActionListener() {
  @Override public void actionPerformed(ActionEvent e) {
    label.setText(df.format(new Date()));
    Container parent = SwingUtilities.getUnwrappedParent(label);
    if (parent != null && parent.isOpaque()) {
      repaintWindowAncestor(label);
    }
  }
});
private final JToggleButton button = new JToggleButton(new AbstractAction("timer") {
  private JFrame digitalClock;
  @Override public void actionPerformed(ActionEvent e) {
    if (digitalClock == null) {
      digitalClock = new JFrame();
      digitalClock.setUndecorated(true);
      digitalClock.setBackground(new Color(0, 0, 0, 0));
      digitalClock.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
      digitalClock.getContentPane().add(tp);
      digitalClock.pack();
      digitalClock.setLocationRelativeTo(null);
    }
    if (((AbstractButton) e.getSource()).isSelected()) {
      TexturePaints t = (TexturePaints) combo.getSelectedItem();
      tp.setTexturePaint(t.getTexturePaint());
      timer.start();
      digitalClock.setVisible(true);
    } else {
      timer.stop();
      digitalClock.setVisible(false);
    }
  }
});
private void repaintWindowAncestor(JComponent c) {
  JRootPane root = c.getRootPane();
  if (root == null) {
    return;
  }
  Rectangle r = SwingUtilities.convertRectangle(c, c.getBounds(), root);
  root.repaint(r.x, r.y, r.width, r.height);
}

References

2013/11/11

aterai

Using drop caps on a JLabel

Code

@Override protected void paintComponent(Graphics g) {
  Graphics2D g2 = (Graphics2D)g.create();
  g2.setPaint(getBackground());
  g2.fillRect(0, 0, getWidth(), getHeight());

  Insets i = getInsets();
  float x0 = i.left;
  float y0 = i.top;

  Font font = getFont();
  String txt = getText();

  AttributedString as = new AttributedString(txt.substring(1));
  as.addAttribute(TextAttribute.FONT, font);
  AttributedCharacterIterator aci = as.getIterator();
  FontRenderContext frc = g2.getFontRenderContext();

  Shape shape = new TextLayout(txt.substring(0, 1), font, frc).getOutline(null);

  AffineTransform at1 = AffineTransform.getScaleInstance(5d, 5d);
  Shape s1 = at1.createTransformedShape(shape);
  Rectangle r = s1.getBounds();
  r.grow(6, 2);
  int rw = r.width;
  int rh = r.height;

  AffineTransform at2 = AffineTransform.getTranslateInstance(x0, y0+rh);
  Shape s2 = at2.createTransformedShape(s1);
  g2.setPaint(getForeground());
  g2.fill(s2);

  float x = x0 + rw;
  float y = y0;
  int w0 = getWidth() - i.left - i.right;
  int w = w0 - rw;
  LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
  while(lbm.getPosition() < aci.getEndIndex()) {
    TextLayout tl = lbm.nextLayout(w);
    tl.draw(g2, x, y + tl.getAscent());
    y += tl.getDescent() + tl.getLeading() + tl.getAscent();
    if(y0+rh < y) {
      x = x0;
      w = w0;
    }
  }
  g2.dispose();
}

References

2013/04/25

aterai

Rearrange JToolBar icon by drag and drop

Code

class DragHandler extends MouseAdapter{
  private final JWindow window = new JWindow();
  private Component draggingComonent = null;
  private int index = -1;
  private Component gap = Box.createHorizontalStrut(24);
  private Point startPt = null;
  private int gestureMotionThreshold = DragSource.getDragThreshold();
  public DragHandler() {
    window.setBackground(new Color(0, true));
  }
  @Override public void mousePressed(MouseEvent e) {
    JComponent parent = (JComponent)e.getComponent();
    if(parent.getComponentCount()<=1) {
      startPt = null;
      return;
    }
    startPt = e.getPoint();
  }
  @Override
  public void mouseDragged(MouseEvent e) {
    Point pt = e.getPoint();
    JComponent parent = (JComponent)e.getComponent();
    int t = Math.sqrt(Math.pow(pt.x-startPt.x, 2)+Math.pow(pt.y-startPt.y, 2))
    if(startPt != null && t>gestureMotionThreshold) {
      startPt = null;
      Component c = parent.getComponentAt(pt);
      index = parent.getComponentZOrder(c);
      if(c == parent || index < 0) {
        return;
      }
      draggingComonent = c;

      parent.remove(draggingComonent);
      parent.add(gap, index);
      parent.revalidate();
      parent.repaint();

      window.add(draggingComonent);
      window.pack();

      Dimension d = draggingComonent.getPreferredSize();
      Point p = new Point(pt.x - d.width/2, pt.y - d.height/2);
      SwingUtilities.convertPointToScreen(p, parent);
      window.setLocation(p);
      window.setVisible(true);

      return;
    }
    if(!window.isVisible() || draggingComonent==null) {
      return;
    }

    Dimension d = draggingComonent.getPreferredSize();
    Point p = new Point(pt.x - d.width/2, pt.y - d.height/2);
    SwingUtilities.convertPointToScreen(p, parent);
    window.setLocation(p);

    for(int i=0; i=0 ? i : 0;
        parent.remove(gap);
        parent.add(gap, n);
        parent.revalidate();
        parent.repaint();
        return;
      }else if(r2.contains(pt)) {
        if(c==gap) {
          return;
        }
        parent.remove(gap);
        parent.add(gap, i);
        parent.revalidate();
        parent.repaint();
        return;
      }
    }
    parent.remove(gap);
    parent.revalidate();
    parent.repaint();
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    startPt = null;
    if(!window.isVisible() || draggingComonent==null) {
      return;
    }
    Point pt = e.getPoint();
    JComponent parent = (JComponent)e.getComponent();

    Component cmp = draggingComonent;
    draggingComonent = null;
    window.setVisible(false);

    for(int i=0; i=0 ? i : 0;
        parent.remove(gap);
        parent.add(cmp, n);
        parent.revalidate();
        parent.repaint();
        return;
      }else if(r2.contains(pt)) {
        parent.remove(gap);
        parent.add(cmp, i);
        parent.revalidate();
        parent.repaint();
        return;
      }
    }
    if(parent.getBounds().contains(pt)) {
      parent.remove(gap);
      parent.add(cmp);
    }else{
      parent.remove(gap);
      parent.add(cmp, index);
    }
    parent.revalidate();
    parent.repaint();
  }
}

References

2013/01/08

aterai

make a translucent JButton

Code

class TranslucentButton extends JButton{
  private static final Color TL = new Color(1f,1f,1f,.2f);
  private static final Color BR = new Color(0f,0f,0f,.4f);
  private static final Color ST = new Color(1f,1f,1f,.2f);
  private static final Color SB = new Color(1f,1f,1f,.1f);
  private Color ssc;
  private Color bgc;
  private int r = 8;
  public TranslucentButton(String text) {
    super(text);
  }
  public TranslucentButton(String text, Icon icon) {
    super(text, icon);
  }
  @Override public void updateUI() {
    super.updateUI();
    setContentAreaFilled(false);
    setFocusPainted(false);
    setOpaque(false);
    setForeground(Color.WHITE);
  }
  @Override protected void paintComponent(Graphics g) {
    int x = 0;
    int y = 0;
    int w = getWidth();
    int h = getHeight();
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON);
    Shape area = new RoundRectangle2D.Float(x, y, w-1, h-1, r, r);
    ssc = TL;
    bgc = BR;
    ButtonModel m = getModel();
    if(m.isPressed()) {
      ssc = SB;
      bgc = ST;
    }else if(m.isRollover()) {
      ssc = ST;
      bgc = SB;
    }
    g2.setPaint(new GradientPaint(x, y, ssc, x, y+h, bgc, true));
    g2.fill(area);
    g2.setPaint(BR);
    g2.draw(area);
    g2.dispose();
    super.paintComponent(g);
  }
}
private static String makeTitleWithIcon(URL u, String t, String a) {
  return String.format(
    "<html><p align='%s'><img src='%s' align='%s' />&nbsp;%s", a, u, a, t);
}
private static AbstractButton makeButton(String title) {
  return new JButton(title) {
    @Override public void updateUI() {
      super.updateUI();
      setVerticalAlignment(SwingConstants.CENTER);
      setVerticalTextPosition(SwingConstants.CENTER);
      setHorizontalAlignment(SwingConstants.CENTER);
      setHorizontalTextPosition(SwingConstants.CENTER);
      setBorder(BorderFactory.createEmptyBorder());
      //setBorderPainted(false);
      setContentAreaFilled(false);
      setFocusPainted(false);
      setOpaque(false);
      setForeground(Color.WHITE);
      setIcon(new TranslucentButtonIcon());
    }
  };
}
JLabel label = new JLabel("JLabel", icon, SwingConstants.CENTER);
label.setForeground(Color.WHITE);
label.setAlignmentX(.5f);
b = makeButton("");
b.setAlignmentX(.5f);
JPanel p = new JPanel();
p.setLayout(new OverlayLayout(p));
p.setOpaque(false);
p.add(label);
p.add(b);
add(p);

References

2012/09/24

aterai

create a gradient titled separator

Code

class TitledSeparator extends JLabel{
  private Color color;
  private final String title;
  private final Color target;
  private final int height;
  private final int titlePosition;
  public TitledSeparator(String title, int height, int titlePosition) {
    this(title, null, height, titlePosition);
  }
  public TitledSeparator(
      String _title, Color _target, int _height, int _titlePosition) {
    super();
    this.title = _title;
    this.target = _target;
    this.height = _height;
    this.titlePosition = _titlePosition;
    Icon icon = new Icon() {
      private int width = -1;
      private Paint painter1, painter2;
      @Override public void paintIcon(Component c, Graphics g, int x, int y) {
        int w = c.getWidth();
        if(w!=width || painter1==null || painter2==null || color==null) {
          width = w;
          Point2D start = new Point2D.Float(0f, 0f);
          Point2D end   = new Point2D.Float((float)width, 0f);
          float[] dist  = {0.0f, 1.0f};
          color = getBackground();
          color = color==null ? UIManager.getColor("Panel.background"):color;
          Color tc = target==null ? color : target;
          painter1 = new LinearGradientPaint(
              start, end, dist, new Color[] {tc.darker(),   color});
          painter2 = new LinearGradientPaint(
              start, end, dist, new Color[] {tc.brighter(), color});
        }
        int h = getIconHeight()/2;
        Graphics2D g2  = (Graphics2D)g.create();
        g2.setPaint(painter1);
        g2.fillRect(x, y,   width, getIconHeight());
        g2.setPaint(painter2);
        g2.fillRect(x, y+h, width, getIconHeight()-h);
        g2.dispose();
      }
      @Override public int getIconWidth()  { return 200; } //dummy width
      @Override public int getIconHeight() { return height; }
    };
    this.setBorder(BorderFactory.createTitledBorder(
      BorderFactory.createMatteBorder(height, 0, 0, 0, icon), title,
      TitledBorder.DEFAULT_JUSTIFICATION, titlePosition));
    //System.out.println(getInsets());
  }
  @Override public Dimension getMaximumSize() {
    Dimension d = super.getPreferredSize();
    d.width = Short.MAX_VALUE;
    return d;
  }
  @Override public void updateUI() {
    super.updateUI();
    color = null;
  }
}

References

2012/01/25

aterai

Sharing tabs between 2 JFrames

Code

//Display "DropLocation" using JLayer 
class DropLocationLayerUI extends LayerUI {
  private static final int LINEWIDTH = 3;
  private final Rectangle lineRect = new Rectangle();
  @Override public void paint(Graphics g, JComponent c) {
    super.paint (g, c);
    JLayer layer = (JLayer)c;
    DnDTabbedPane tabbedPane = (DnDTabbedPane)layer.getView();
    DnDTabbedPane.DropLocation loc = tabbedPane.getDropLocation();
    if(loc != null && loc.isDropable() && loc.getIndex()>=0) {
      int index = loc.getIndex();
      boolean isZero = index==0;
      Rectangle r = tabbedPane.getBoundsAt(isZero?0:index-1);
      if(tabbedPane.getTabPlacement()==JTabbedPane.TOP ||
         tabbedPane.getTabPlacement()==JTabbedPane.BOTTOM) {
        lineRect.setRect(
            r.x-LINEWIDTH/2+r.width*(isZero?0:1), r.y,LINEWIDTH,r.height);
      }else{
        lineRect.setRect(
            r.x,r.y-LINEWIDTH/2+r.height*(isZero?0:1), r.width,LINEWIDTH);
      }
      Graphics2D g2 = (Graphics2D)g.create();
      g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
      g2.setColor(Color.RED);
      g2.fill(lineRect);
      g2.dispose();
    }
  }
}
private final JLabel label = new JLabel() {
// https://free-the-pixel.blogspot.com/2010/04/ghost-drag-and-drop-over-multiple.html
// Free the pixel: GHOST drag and drop, over multiple windows]
  @Override public boolean contains(int x, int y) {
    return false;
  }
};
private final JWindow dialog = new JWindow();
public TabTransferHandler() {
  dialog.add(label);
  //dialog.setAlwaysOnTop(true); // Web Start
  dialog.setOpacity(0.5f);
  //com.sun.awt.AWTUtilities.setWindowOpacity(dialog, 0.5f); // JDK 1.6.0
  DragSource.getDefaultDragSource().addDragSourceMotionListener(
      new DragSourceMotionListener() {
    @Override public void dragMouseMoved(DragSourceDragEvent dsde) {
      Point pt = dsde.getLocation();
      pt.translate(5, 5); // offset
      dialog.setLocation(pt);
    }
  });
//...

References

2011/05/30

aterai

Translucent image caption using JTextArea, OverlayLayout, EaseInOut

Code

class ImageCaptionLabel extends JLabel implements HierarchyListener {
  private float alpha = 0.0f;
  private javax.swing.Timer animator;
  private int yy = 0;
  private JTextArea textArea = new JTextArea() {
    @Override protected void paintComponent(Graphics g) {
      Graphics2D g2 = (Graphics2D)g;
      g2.setPaint(getBackground());
      g2.fillRect(0, 0, getWidth(), getHeight());
      super.paintComponent(g);
    }
    //@Override public boolean contains(int x, int y) {
    //  return false;
    //}
  };
  public ImageCaptionLabel(String caption, Icon icon) {
    setIcon(icon);
    textArea.setFont(textArea.getFont().deriveFont(11f));
    textArea.setText(caption);
    textArea.setOpaque(false);
    textArea.setEditable(false);
    //textArea.setFocusable(false);
    textArea.setBackground(new Color(0,0,0,0));
    textArea.setForeground(Color.WHITE);
    textArea.setBorder(BorderFactory.createEmptyBorder(2,4,4,4));

    MouseAdapter ma = new MouseAdapter() {
      @Override public void mouseEntered(MouseEvent e) {
        dispatchMouseEvent(e);
      }
      @Override public void mouseExited(MouseEvent e) {
        dispatchMouseEvent(e);
      }
      private void dispatchMouseEvent(MouseEvent e) {
        Component src = e.getComponent();
        Component tgt = ImageCaptionLabel.this;
        tgt.dispatchEvent(SwingUtilities.convertMouseEvent(src, e, tgt));
      }
    };
    textArea.addMouseListener(ma);

    setBorder(BorderFactory.createCompoundBorder(
      BorderFactory.createLineBorder(new Color(222,222,222)),
      BorderFactory.createLineBorder(Color.WHITE, 4)));
    setLayout(new OverlayLayout(this) {
      @Override public void layoutContainer(Container parent) {
        //Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        if(ncomponents == 0) return;
        int width = parent.getWidth(); // - (insets.left + insets.right);
        int height = parent.getHeight(); // - (insets.left + insets.right);
        int x = 0; //insets.left; int y = insets.top;
        //for(int i=0;i < ncomponents;i++) {
        Component c = parent.getComponent(0); //= textArea;
        c.setBounds(x, height-yy, width, c.getPreferredSize().height);
        //}
      }
    });
    add(textArea);

    addMouseListener(new MouseAdapter() {
      private int delay = 4;
      private int count = 0;
      @Override public void mouseEntered(MouseEvent e) {
        if(animator!=null && animator.isRunning() ||
           yy==textArea.getPreferredSize().height) return;
        final double h = (double)textArea.getPreferredSize().height;
        animator = new javax.swing.Timer(delay, new ActionListener() {
          @Override public void actionPerformed(ActionEvent e) {
            double a = easeInOut(++count/h);
            yy = (int)(.5d+a*h);
            textArea.setBackground(new Color(0f,0f,0f,(float)(0.6*a)));
            if(yy >= textArea.getPreferredSize().height) {
              yy = textArea.getPreferredSize().height;
              animator.stop();
            }
            revalidate();
            repaint();
          }
        });
        animator.start();
      }
      @Override public void mouseExited(MouseEvent e) {
        if(animator!=null && animator.isRunning() ||
           contains(e.getPoint()) && yy==textArea.getPreferredSize().height) {
            return;
        }
        final double h = (double)textArea.getPreferredSize().height;
        animator = new javax.swing.Timer(delay, new ActionListener() {
          @Override public void actionPerformed(ActionEvent e) {
            double a = easeInOut(--count/h);
            yy = (int)(.5d+a*h);
            textArea.setBackground(new Color(0f,0f,0f,(float)(0.6*a)));
            if(yy <= 0) {
              yy = 0;
              animator.stop();
            }
            revalidate();
            repaint();
          }
        });
        animator.start();
      }
    });
    addHierarchyListener(this);
  }
  @Override public void hierarchyChanged(HierarchyEvent e) {
    if((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED)!=0 &&
       animator!=null && !isDisplayable()) {
      animator.stop();
    }
  }
  //http://www.anima-entertainment.de/math-easein-easeout-easeinout-and-bezier-curves
  //coders≫ Blog Archive ≫ Math: EaseIn EaseOut, EaseInOut and Bezier Curves
  public double easeInOut(double t) {
    if(t < 0.5d) {
      return 0.5d*Math.pow(t*2d, 3d);
    }else{
      return 0.5d*(Math.pow(t*2d-2d, 3d) + 2d);
    }
  }
}

References

2010/05/10

aterai

Custom Decorated TitleBar JFrame

Code

class ResizeWindowListener extends MouseAdapter {
  private Rectangle startSide = null;
  private final JFrame frame;
  public ResizeWindowListener(JFrame frame) {
    this.frame = frame;
  }
  public void mousePressed(MouseEvent e) {
    startSide = frame.getBounds();
  }
  public void mouseDragged(MouseEvent e) {
    if(startSide==null) return;
    Component c = e.getComponent();
    if(c==topleft) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==top) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
    }else if(c==topright) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.width += e.getX();
    }else if(c==left) {
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==right) {
      startSide.width += e.getX();
    }else if(c==bottomleft) {
      startSide.height += e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==bottom) {
      startSide.height += e.getY();
    }else if(c==bottomright) {
      startSide.height += e.getY();
      startSide.width += e.getX();
    }
    frame.setBounds(startSide);
  }
}

References

2009/08/17

aterai

Add JButton and JLabel to the EditorComponent of JComboBox

Code

class SiteComboBoxLayout implements LayoutManager {
  private final JLabel favicon;
  private final JButton feedButton;
  protected SiteComboBoxLayout(JLabel favicon, JButton feedButton) {
    this.favicon = favicon;
    this.feedButton = feedButton;
  }
  @Override public void addLayoutComponent(String name, Component comp) {
    /* not needed */
  }
  @Override public void removeLayoutComponent(Component comp) {
    /* not needed */
  }
  @Override public Dimension preferredLayoutSize(Container parent) {
    return parent.getPreferredSize();
  }
  @Override public Dimension minimumLayoutSize(Container parent) {
    return parent.getMinimumSize();
  }
  @Override public void layoutContainer(Container parent) {
    if (!(parent instanceof JComboBox)) {
      return;
    }
    JComboBox<?> cb = (JComboBox<?>) parent;
    int width = cb.getWidth();
    int height = cb.getHeight();
    Insets insets = cb.getInsets();
    int arrowHeight = height - insets.top - insets.bottom;
    int arrowWidth = arrowHeight;
    int faviconWidth = arrowHeight;
    int feedWidth; // = arrowHeight;

    // Arrow Icon JButton
    JButton arrowButton = (JButton) cb.getComponent(0);
    if (Objects.nonNull(arrowButton)) {
      Insets arrowInsets = arrowButton.getInsets();
      arrowWidth = arrowButton.getPreferredSize().width
        + arrowInsets.left + arrowInsets.right;
      arrowButton.setBounds(width - insets.right - arrowWidth, insets.top,
                            arrowWidth, arrowHeight);
    }

    // Favicon JLabel
    if (Objects.nonNull(favicon)) {
      Insets faviconInsets = favicon.getInsets();
      faviconWidth = favicon.getPreferredSize().width
          + faviconInsets.left + faviconInsets.right;
      favicon.setBounds(insets.left, insets.top, faviconWidth, arrowHeight);
    }


    // Feed Icon JButton
    if (Objects.nonNull(feedButton) && feedButton.isVisible()) {
      Insets feedInsets = feedButton.getInsets();
      feedWidth = feedButton.getPreferredSize().width
          + feedInsets.left + feedInsets.right;
      feedButton.setBounds(width - insets.right - feedWidth - arrowWidth, insets.top,
                           feedWidth, arrowHeight);
    } else {
      feedWidth = 0;
    }

    // JComboBox Editor
    Component editor = cb.getEditor().getEditorComponent();
    if (Objects.nonNull(editor)) {
      editor.setBounds(insets.left + faviconWidth, insets.top,
          width  - insets.left - insets.right - arrowWidth - faviconWidth - feedWidth,
          height - insets.top  - insets.bottom);
    }
  }
}

References

2009/03/23

aterai

Mouse Dragging ViewPort Scroll

Code

//*
MouseAdapter hsl1 = new HandScrollListener();
vport.addMouseMotionListener(hsl1);
vport.addMouseListener(hsl1);
/*/
MouseAdapter hsl2 = new DragScrollListener();
label.addMouseMotionListener(hsl2);
label.addMouseListener(hsl2);
//*/
class HandScrollListener extends MouseInputAdapter {
  private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  private final Point pp = new Point();
  @Override
  public void mouseDragged(final MouseEvent e) {
    Point cp = e.getPoint();
    Point vp = vport.getViewPosition();
    //= SwingUtilities.convertPoint(vport,0,0,label);
    vp.translate(pp.x-cp.x, pp.y-cp.y);
    if(r1.isSelected()) {
      label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
    }else{
      vport.setViewPosition(vp);
    }
    pp.setLocation(cp);
  }
  @Override
  public void mousePressed(MouseEvent e) {
    label.setCursor(hndCursor);
    pp.setLocation(e.getPoint());
  }
  @Override
  public void mouseReleased(MouseEvent e) {
    label.setCursor(defCursor);
    label.repaint();
  }
}
class DragScrollListener extends MouseAdapter {
  private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  private final Point pp = new Point();
  @Override public void mouseDragged(MouseEvent e) {
    final JComponent jc = (JComponent)e.getSource();
    Container c = jc.getParent();
    if(c instanceof JViewport) {
      JViewport vport = (JViewport)c;
      Point cp = SwingUtilities.convertPoint(jc,e.getPoint(),vport);
      Point vp = vport.getViewPosition();
      vp.translate(pp.x-cp.x, pp.y-cp.y);
      jc.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
      pp.setLocation(cp);
    }
  }
  @Override public void mousePressed(MouseEvent e) {
    JComponent jc = (JComponent)e.getSource();
    Container c = jc.getParent();
    if(c instanceof JViewport) {
      jc.setCursor(hndCursor);
      JViewport vport = (JViewport)c;
      Point cp = SwingUtilities.convertPoint(jc,e.getPoint(),vport);
      pp.setLocation(cp);
    }
  }
  @Override public void mouseReleased(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(defCursor);
  }
}

References

2009/02/16

aterai

JTableHeader CheckBox

Code

enum Status { SELECTED, DESELECTED, INDETERMINATE }
class HeaderRenderer extends JCheckBox implements TableCellRenderer {
  private final JLabel label = new JLabel("Check All");
  private int targetColumnIndex;
  public HeaderRenderer(JTableHeader header, int index) {
    super((String)null);
    this.targetColumnIndex = index;
    setOpaque(false);
    setFont(header.getFont());
    header.addMouseListener(new MouseAdapter() {
      @Override public void mouseClicked(MouseEvent e) {
        JTableHeader header = (JTableHeader)e.getSource();
        JTable table = header.getTable();
        TableColumnModel columnModel = table.getColumnModel();
        int vci = columnModel.getColumnIndexAtX(e.getX());
        int mci = table.convertColumnIndexToModel(vci);
        if(mci == targetColumnIndex) {
          TableColumn column = columnModel.getColumn(vci);
          Object v = column.getHeaderValue();
          boolean b = Status.DESELECTED.equals(v)?true:false;
          TableModel m = table.getModel();
          for(int i=0; i < m.getRowCount(); i++) m.setValueAt(b, i, mci);
          column.setHeaderValue(b?Status.SELECTED:Status.DESELECTED);
          //header.repaint();
        }
      }
    });
  }
  @Override public Component getTableCellRendererComponent(
      JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) {
    TableCellRenderer r = tbl.getTableHeader().getDefaultRenderer();
    JLabel l =(JLabel)r.getTableCellRendererComponent(tbl,val,isS,hasF,row,col);
    if(targetColumnIndex==tbl.convertColumnIndexToModel(col)) {
      if(val instanceof Status) {
        switch((Status)val) {
          case SELECTED:    setSelected(true);  setEnabled(true);  break;
          case DESELECTED:  setSelected(false); setEnabled(true);  break;
          case INDETERMINATE: setSelected(true);  setEnabled(false); break;
        }
      }else{
        setSelected(true); setEnabled(false);
      }
      label.setIcon(new ComponentIcon(this));
      l.setIcon(new ComponentIcon(label));
      l.setText(null); //XXX: Nimbus???
    }
    return l;
  }
}
class CheckBoxIcon implements Icon{
  private final JCheckBox check;
  public CheckBoxIcon(JCheckBox check) {
    this.check = check;
  }
  @Override public int getIconWidth() {
    return check.getPreferredSize().width;
  }
  @Override public int getIconHeight() {
    return check.getPreferredSize().height;
  }
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    SwingUtilities.paintComponent(
        g, check, (Container)c, x, y, getIconWidth(), getIconHeight());
  }
}
model.addTableModelListener(new TableModelListener() {
  @Override public void tableChanged(TableModelEvent e) {
    if(e.getType()==TableModelEvent.UPDATE && e.getColumn()==targetColumnIndex) {
      int vci = table.convertColumnIndexToView(targetColumnIndex);
      TableColumn column = table.getColumnModel().getColumn(vci);
      if(!Status.INDETERMINATE.equals(column.getHeaderValue())) {
        column.setHeaderValue(Status.INDETERMINATE);
      }else{
        boolean selected = true, deselected = true;
        TableModel m = table.getModel();
        for(int i=0; i < m.getRowCount(); i++) {
          Boolean b = (Boolean)m.getValueAt(i, targetColumnIndex);
          selected &= b; deselected &= !b;
          if(selected==deselected) return;
        }
        if(selected) {
          column.setHeaderValue(Status.SELECTED);
        }else if(deselected) {
          column.setHeaderValue(Status.DESELECTED);
        }else{
          return;
        }
      }
      JTableHeader h = table.getTableHeader();
      h.repaint(h.getHeaderRect(vci));
    }
  }
});

References

2008/12/02

aterai

JLabel Star Rating Bar

Code

class LevelBar extends JPanel implements MouseListener, MouseMotionListener{
  private final int gap;
  protected final List< ImageIcon > iconList;
  protected final List< JLabel > labelList = Arrays.asList(
    new JLabel(),new JLabel(),new JLabel(),new JLabel(),new JLabel()
  );
  protected final ImageIcon defaultIcon;
  private int clicked = -1;
  public LevelBar(ImageIcon defaultIcon, List< ImageIcon > list, int gap) {
    super(new GridLayout(1, 5, gap*2, gap*2));
    this.defaultIcon = defaultIcon;
    this.iconList = list;
    this.gap = gap;
    for(JLabel l:labelList) {
      l.setIcon(defaultIcon);
      add(l);
    }
    addMouseListener(this);
    addMouseMotionListener(this);
  }
  public void clear() {
    clicked = -1;
    repaintIcon(clicked);
  }
  public int getLevel() {
    return clicked;
  }
  public void setLevel(int l) {
    clicked = l;
    repaintIcon(clicked);
  }
  private int getSelectedIconIndex(Point p) {
    for(int i=0;i < labelList.size();i++) {
      Rectangle r = labelList.get(i).getBounds();
      r.grow(gap, gap);
      if(r.contains(p)) return i;
    }
    return -1;
  }
  protected void repaintIcon(int index) {
    for(int i=0;i < labelList.size();i++) {
      labelList.get(i).setIcon(i <= index?iconList.get(i):defaultIcon);
    }
    repaint();
  }
  public void mouseMoved(MouseEvent e) {
    repaintIcon(getSelectedIconIndex(e.getPoint()));
  }
  public void mouseEntered(MouseEvent e) {
    repaintIcon(getSelectedIconIndex(e.getPoint()));
  }
  public void mouseClicked(MouseEvent e) {
    clicked = getSelectedIconIndex(e.getPoint());
  }
  public void mouseExited(MouseEvent e) {
    repaintIcon(clicked);
  }
  public void mouseDragged(MouseEvent e) {}
  public void mousePressed(MouseEvent e) {}
  public void mouseReleased(MouseEvent e) {}
}
class SelectedImageFilter extends RGBImageFilter {
  private final float[] filter;
  public SelectedImageFilter(float[] filter) {
    this.filter = filter;
    canFilterIndexColorModel = true;
  }
  public int filterRGB(int x, int y, int argb) {
    Color color = new Color(argb, true);
    float[] array = new float[4];
    color.getComponents(array);
    return new Color(array[0]*filter[0],
                     array[1]*filter[1],
                     array[2]*filter[2],
                     array[3]).getRGB();
  }
}

References

2008/08/13

aterai

Multi Column JComboBox

Code

class MultiColumnCellRenderer extends JPanel implements ListCellRenderer{
  private final JLabel leftLabel = new JLabel();
  private final JLabel rightLabel;
  public MultiColumnCellRenderer(int rightWidth) {
    super(new BorderLayout());
    this.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));

    leftLabel.setOpaque(false);
    leftLabel.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));

    final Dimension dim = new Dimension(rightWidth, 0);
    rightLabel = new JLabel() {
      @Override public Dimension getPreferredSize() {
        return dim;
      }
    };
    rightLabel.setOpaque(false);
    rightLabel.setBorder(BorderFactory.createEmptyBorder(0,2,0,2));
    rightLabel.setForeground(Color.GRAY);
    rightLabel.setHorizontalAlignment(SwingConstants.RIGHT);

    this.add(leftLabel);
    this.add(rightLabel, BorderLayout.EAST);
  }
  @Override public Component getListCellRendererComponent(
      JList list, Object value, int index,
      boolean isSelected, boolean cellHasFocus) {
    LRItem item = (LRItem)value;
    leftLabel.setText(item.getLeftText());
    rightLabel.setText(item.getRightText());

    leftLabel.setFont(list.getFont());
    rightLabel.setFont(list.getFont());

    if(index<0) {
      leftLabel.setForeground(list.getForeground());
      this.setOpaque(false);
    }else{
      leftLabel.setForeground(
          isSelected?list.getSelectionForeground():list.getForeground());
      this.setBackground(
          isSelected?list.getSelectionBackground():list.getBackground());
      this.setOpaque(true);
    }
    return this;
  }
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    return new Dimension(0, d.height);
  }
  @Override public void updateUI() {
    super.updateUI();
    this.setName("List.cellRenderer");
  }
}

References

2008/03/21

aterai

Horizontally fill tabs of a JTabbedPane

Code

//horizontal filling, same width tabs
class ClippedTitleTabbedPane extends JTabbedPane {
  public ClippedTitleTabbedPane() {
    super();
  }
  public ClippedTitleTabbedPane(int tabPlacement) {
    super(tabPlacement);
  }
  private Insets getTabInsets() {
    Insets i = UIManager.getInsets("TabbedPane.tabInsets");
    if(i!=null) {
      return i;
    }else{
      SynthStyle style = SynthLookAndFeel.getStyle(
        this, Region.TABBED_PANE_TAB);
      SynthContext context = new SynthContext(
        this, Region.TABBED_PANE_TAB, style, SynthConstants.ENABLED);
      return style.getInsets(context, null);
    }
  }
  private Insets getTabAreaInsets() {
    Insets i = UIManager.getInsets("TabbedPane.tabAreaInsets");
    if(i!=null) {
      return i;
    }else{
      SynthStyle style = SynthLookAndFeel.getStyle(
        this, Region.TABBED_PANE_TAB_AREA);
      SynthContext context = new SynthContext(
        this, Region.TABBED_PANE_TAB_AREA, style, SynthConstants.ENABLED);
      return style.getInsets(context, null);
    }
  }
  @Override public void doLayout() {
    int tabCount  = getTabCount();
    if(tabCount==0) return;
    Insets tabInsets   = getTabInsets();
    Insets tabAreaInsets = getTabAreaInsets();
    Insets insets = getInsets();
    int areaWidth = getWidth() - tabAreaInsets.left - tabAreaInsets.right
                               - insets.left        - insets.right;
    int tabWidth  = 0; // = tabInsets.left + tabInsets.right + 3;
    int gap     = 0;

    switch(getTabPlacement()) {
      case LEFT: case RIGHT:
      tabWidth = areaWidth / 4;
      gap = 0;
      break;
      case BOTTOM: case TOP: default:
      tabWidth = areaWidth / tabCount;
      gap = areaWidth - (tabWidth * tabCount);
    }
    // "3" is magic number @see BasicTabbedPaneUI#calculateTabWidth
    tabWidth = tabWidth - tabInsets.left - tabInsets.right - 3;
    for(int i=0;i < tabCount;i++) {
      JLabel l = (JLabel)getTabComponentAt(i);
      if(l==null) break;
      l.setPreferredSize(new Dimension(
          tabWidth+(i < gap?1:0), l.getPreferredSize().height));
    }
    super.doLayout();
  }
  @Override
  public void insertTab(
      String title, Icon icon, Component component,
      String tip, int index) {
    super.insertTab(title, icon, component,
                    tip==null?title:tip, index);
    JLabel label = new JLabel(title, JLabel.CENTER);
    Dimension dim = label.getPreferredSize();
    Insets tabInsets = getTabInsets();
    label.setPreferredSize(new Dimension(
      0, dim.height+tabInsets.top+tabInsets.bottom));
    setTabComponentAt(index, label);
  }
}

References