Swing/JustifiedLabel のバックアップの現在との差分(No.2)
TITLE:JLabelの文字揃え
JLabelの文字揃え
Posted by terai at 2008-03-31- category: swing folder: JustifiedLabel title: JLabelの文字揃え tags: [JLabel, Alignment, GlyphVector] author: aterai pubdate: 2008-03-31T00:41:18+09:00 description: JLabelで、左右中央両端などの文字揃えをテストします。 image:
概要
JLabel
で、左右中央両端などの文字揃えをテストします。
Screenshot
Advertisement
概要
JLabelで、左右中央両端などの文字揃えをテストします。- &jnlp;
- &jar;
- &zip;
#screenshot
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
JLabel l0 = new JLabel("打率");
#spandel
JLabel l1 = new JLabel("打率", JLabel.RIGHT);
#spanend
#spanadd
JLabel l1 = new JLabel("打率", SwingConstants.RIGHT);
#spanend
JLabel l2 = new JustifiedLabel("打率");
#spandel
JLabel l3 = new JLabel("出塁率", JLabel.CENTER);
#spanend
#spanadd
JLabel l3 = new JLabel("出塁率", SwingConstants.CENTER);
#spanend
JLabel l4 = new JustifiedLabel("出塁率");
JLabel l5 = new JustifiedLabel("チーム出塁率");
#spandel
#spanend
#spanadd
// ...
#spanend
class JustifiedLabel extends JLabel {
private GlyphVector gvtext;
private boolean flg = true;
private int prevWidth = -1;
#spanadd
#spanend
public JustifiedLabel() {
this(null);
}
#spanadd
#spanend
public JustifiedLabel(String str) {
super(str);
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
flg = true;
repaint();
}
#spanadd
#spanend
@Override public void setText(String text) {
super.setText(text);
prevWidth = -1;
}
#spanadd
#spanend
@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();
}
#spanadd
#spanend
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;
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
if(flg) {
int WRAPPING_WIDTH = getWidth()-getInsets().left-getInsets().right;
FontRenderContext frc = g2.getFontRenderContext();
gvtext = getWrappedGlyphVector(getText(), WRAPPING_WIDTH, getFont(), frc);
flg = false;
#spanadd
}
#spanend
#spanadd
解説
-
JLabel
の文字揃えは左揃え(デフォルトはSwingConstants.LEADING
,ComponentOrientation.LEFT_TO_RIGHT
でSwingConstants.LEFT
)、右揃え(SwingConstants.TRAILING
,ComponentOrientation.LEFT_TO_RIGHT
でSwingConstants.RIGHT
)、中央揃え(SwingConstants.CENTER
)が設定可能 -
JLabel
の文字揃えに両端揃え(文字の均等割り付け)は存在しないので、上記のサンプルではJustifiedLabel
を独自に作成- 幅が足りない場合は通常の
JLabel
と同様に...
で省略
- 幅が足りない場合は通常の
- -
-
JTextPane
に挿入、一文字の場合などのテスト
#spanend
#spanadd
import java.awt.*;
#spanend
#spanadd
import java.awt.font.*;
#spanend
#spanadd
import java.awt.geom.*;
#spanend
#spanadd
import javax.swing.*;
#spanend
#spanadd
#spanend
#spanadd
public class JustifiedLabelDemo {
#spanend
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);
}
#spanadd
#spanend
public static void main(String[] args) {
EventQueue.invokeLater(JustifiedLabelDemo::createAndShowGui);
}
#spanadd
#spanend
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);
}
#spanadd
}
#spanend
#spanadd
#spanend
#spanadd
class JustifiedLabel extends JLabel {
#spanend
private GlyphVector gvText;
private int prevWidth = -1;
#spanadd
#spanend
public JustifiedLabel() {
this(null);
}
#spanadd
#spanend
public JustifiedLabel(String str) {
super(str);
Dimension d = getPreferredSize();
int baseline = getBaseline(d.width, d.height);
setAlignmentY(baseline / (float) d.height);
}
#spanadd
#spanend
@Override public Dimension getMinimumSize() {
return getPreferredSize();
}
#spanadd
#spanend
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = getWidth();
return d;
}
#spanadd
#spanend
@Override public int getWidth() {
return 120;
}
#spanadd
#spanend
@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.setPaint(Color.RED);
g2.drawGlyphVector(gvtext, getInsets().left,
getHeight()/2 + getFont().getSize()/2);
}else{
if (gvText != null) {
g2.drawGlyphVector(gvText, i.left, i.top + getFont().getSize2D());
} else {
super.paintComponent(g);
}
}
private GlyphVector getWrappedGlyphVector(String str, float wrapping,
Font font, FontRenderContext frc) {
GlyphVector gv = font.createGlyphVector(frc, str);
float ga = 0.0f;
for(int i=0;i<gv.getNumGlyphs();i++) {
ga = ga + gv.getGlyphMetrics(i).getAdvance();
}
if(wrapping<ga) return null;
float xx = (wrapping-ga) / (float)(gv.getNumGlyphs()-1);
float xpos = 0.0f;
Point2D gmPos = new Point2D.Double(0.0d, 0.0d);
for(int i=0;i<gv.getNumGlyphs();i++) {
#spanadd
#spanend
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 = xpos + gm.getAdvance() + xx;
xpos += gm.getAdvance() + xx;
}
return gv;
}
}
解説
JLabelの文字揃えは、デフォルトが左揃えで、その他に右揃え、中央揃えがあります。ただし、両端揃え(均等割り付け)は存在しないので、上記のサンプルでは、JustifiedLabel*1を作成して使用しています。参考リンク
- JTableのセル内文字列を両端揃えにする
- TextLayoutTextLayout#getJustifiedLayout(float) (Java Platform SE 8)メソッドを使用して
JTable
のセルで両端揃えを行うサンプル
- TextLayoutTextLayout#getJustifiedLayout(float) (Java Platform SE 8)メソッドを使用して