Swing/JustifiedLabel の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/JustifiedLabel へ行く。
- Swing/JustifiedLabel の差分を削除
--- category: swing folder: JustifiedLabel title: JLabelの文字揃え tags: [JLabel, Alignment, GlyphVector] author: aterai pubdate: 2008-03-31T00:41:18+09:00 description: JLabelで、左右中央両端などの文字揃えをテストします。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTOwQzSk-I/AAAAAAAAAc4/bD-z_hTSHB8/s800/JustifiedLabel.png --- * 概要 [#summary] `JLabel`で、左右中央両端などの文字揃えをテストします。 #download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTOwQzSk-I/AAAAAAAAAc4/bD-z_hTSHB8/s800/JustifiedLabel.png) * サンプルコード [#sourcecode] #code(link){{ JLabel l0 = new JLabel("打率"); JLabel l1 = new JLabel("打率", SwingConstants.RIGHT); JLabel l2 = new JustifiedLabel("打率"); JLabel l3 = new JLabel("出塁率", SwingConstants.CENTER); JLabel l4 = new JustifiedLabel("出塁率"); JLabel l5 = new JustifiedLabel("チーム出塁率"); // ... class JustifiedLabel extends JLabel { private GlyphVector gvtext; private int prevWidth = -1; public JustifiedLabel() { this(null); } public JustifiedLabel(String str) { super(str); } @Override public void setText(String text) { super.setText(text); prevWidth = -1; } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g.create(); Insets ins = getInsets(); int w = getSize().width - ins.left - ins.right; if (w != prevWidth) { gvtext = getJustifiedGlyphVector( w, getText(), getFont(), g2.getFontRenderContext()); prevWidth = w; } if (Objects.nonNull(gvtext)) { g2.setPaint(getBackground()); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setPaint(getForeground()); g2.drawGlyphVector(gvtext, ins.left, ins.top + getFont().getSize()); } else { super.paintComponent(g); } g2.dispose(); } private GlyphVector getJustifiedGlyphVector( int width, String str, Font font, FontRenderContext frc) { GlyphVector gv = font.createGlyphVector(frc, str); Rectangle2D r = gv.getVisualBounds(); float jwidth = (float) width; float vwidth = (float) r.getWidth(); if (jwidth > vwidth) { int num = gv.getNumGlyphs(); float xx = (jwidth - vwidth) / (float) (num - 1); float xpos = num == 1 ? (jwidth - vwidth) * .5f : 0f; Point2D gmPos = new Point2D.Double(0d, 0d); for (int i = 0; i < num; i++) { GlyphMetrics gm = gv.getGlyphMetrics(i); gmPos.setLocation(xpos, 0); gv.setGlyphPosition(i, gmPos); xpos += gm.getAdvance() + xx; } return gv; } return null; } } }} * 解説 [#explanation] `JLabel`の文字揃えは、デフォルトが左揃えで、その他に右揃え、中央揃えがあります。両端揃え(文字の均等割り付け)は存在しないので、上記のサンプルでは`JustifiedLabel`(幅が足りない場合などは通常の`JLabel`と同様に`...`で省略)を作成して使用しています。 - `JLabel`の文字揃えは左揃え(デフォルトは`SwingConstants.LEADING`, `ComponentOrientation.LEFT_TO_RIGHT`で`SwingConstants.LEFT`)、右揃え(`SwingConstants.TRAILING`, `ComponentOrientation.LEFT_TO_RIGHT`で`SwingConstants.RIGHT`)、中央揃え(`SwingConstants.CENTER`)が設定可能 - `JLabel`の文字揃えに両端揃え(文字の均等割り付け)は存在しないので、上記のサンプルでは`JustifiedLabel`を独自に作成 -- 幅が足りない場合は通常の`JLabel`と同様に`...`で省略 ---- - `JTextPane`に挿入、一文字の場合などのテスト #code{{ import java.awt.*; import java.awt.font.*; import java.awt.geom.*; import javax.swing.*; public class JustifiedLabelDemo { public JComponent makeUI() { String s = "\u2605"; JTextPane textPane = new JTextPane(); textPane.insertComponent(new JustifiedLabel(s)); textPane.replaceSelection(": 111\n"); textPane.insertComponent(new JustifiedLabel(s + s)); textPane.replaceSelection(": 2222222\n"); textPane.insertComponent(new JustifiedLabel(s + s + s)); textPane.replaceSelection(": 3333\n"); textPane.insertComponent(new JustifiedLabel(s + s + s + s)); textPane.replaceSelection(": 4444444\n"); textPane.insertComponent(new JustifiedLabel(s + s + s + s + s)); textPane.replaceSelection(": 555\n"); return new JScrollPane(textPane); } public static void main(String[] args) { EventQueue.invokeLater(JustifiedLabelDemo::createAndShowGui); } public static void createAndShowGui() { UIManager.put("swing.boldMetal", Boolean.FALSE); JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new JustifiedLabelDemo().makeUI()); f.setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } } class JustifiedLabel extends JLabel { private GlyphVector gvText; private int prevWidth = -1; public JustifiedLabel() { this(null); } public JustifiedLabel(String str) { super(str); Dimension d = getPreferredSize(); int baseline = getBaseline(d.width, d.height); setAlignmentY(baseline / (float) d.height); } @Override public Dimension getMinimumSize() { return getPreferredSize(); } @Override public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.width = getWidth(); return d; } @Override public int getWidth() { return 120; } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; Insets i = getInsets(); int w = getWidth() - i.left - i.right; if (w != prevWidth) { gvText = getJustifiedGlyphVector(getText(), getFont(), g2.getFontRenderContext()); prevWidth = w; } if (gvText != null) { g2.drawGlyphVector(gvText, i.left, i.top + getFont().getSize2D()); } else { super.paintComponent(g); } } private GlyphVector getJustifiedGlyphVector(String str, Font font, FontRenderContext frc) { GlyphVector gv = font.createGlyphVector(frc, str); Rectangle2D r = gv.getVisualBounds(); float width = (float) getWidth(); float viewWidth = (float) r.getWidth(); if (width < viewWidth) return null; int num = gv.getNumGlyphs(); float xx = (width - viewWidth) / (float) (num - 1); float xpos = num == 1 ? (width - viewWidth) * .5f : 0f; Point2D gmPos = new Point2D.Double(0d, 0d); if (num == 1) System.out.println(gmPos); for (int i = 0; i < num; i++) { GlyphMetrics gm = gv.getGlyphMetrics(i); gmPos.setLocation(xpos, 0); gv.setGlyphPosition(i, gmPos); xpos += gm.getAdvance() + xx; } return gv; } } }} * 参考リンク [#reference] - [[JTableのセル内文字列を両端揃えにする>Swing/InterIdeographJustify]] -- [https://docs.oracle.com/javase/jp/8/docs/api/java/awt/font/TextLayout.html#getJustifiedLayout-float- TextLayoutTextLayout#getJustifiedLayout(float) (Java Platform SE 8)]メソッドを使用して`JTable`のセルで両端揃えを行うサンプル * コメント [#comment] #comment #comment