Swing/MenuItemAcceleratorAlignment のバックアップの現在との差分(No.6)
zx21Sp <a href="http://ascwdcbomjde.com/">ascwdcbomjde</a>, [url=http://rqeckskgtkih.com/]rqeckskgtkih[/url], [link=http://ksmugdtexxjr.com/]ksmugdtexxjr[/link], http://lygoyhrdzlnm.com/
-
category: swing
folder: MenuItemAcceleratorAlignment
title: JMenuItemのAccelerator表示を右揃えにする
tags: [JMenuItem, Locale, KeyEvent, ResourceBundle, Alignment, GridBagLayout]
author: aterai
pubdate: 2013-09-30T05:06:53+09:00
description: JMenuItemのAccelerator表示を右揃えに変更します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2014/10/jmenuitem-accelerator-text-alignment.html lang: en
概要
JMenuItem
のAccelerator
表示を右揃えに変更します。
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
public static void paintAccText(
#spanend
Graphics g, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr,
Color disabledForeground, Color acceleratorForeground,
Color acceleratorSelectionForeground) {
if (!lh.getAccText().equals("")) {
ButtonModel model = lh.getMenuItem().getModel();
g.setFont(lh.getAccFontMetrics().getFont());
if (!model.isEnabled()) {
// *** paint the accText disabled
if (disabledForeground != null) {
g.setColor(disabledForeground);
SwingUtilities2.drawString(
lh.getMenuItem(), g, lh.getAccText(),
lr.getAccRect().x,
lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
} else {
g.setColor(lh.getMenuItem().getBackground().brighter());
SwingUtilities2.drawString(
lh.getMenuItem(), g, lh.getAccText(),
lr.getAccRect().x,
lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
g.setColor(lh.getMenuItem().getBackground().darker());
SwingUtilities2.drawString(
lh.getMenuItem(), g, lh.getAccText(),
lr.getAccRect().x - 1,
lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1);
}
} else {
// *** paint the accText normally
if (model.isArmed() ||
(lh.getMenuItem() instanceof JMenu && model.isSelected())) {
g.setColor(acceleratorSelectionForeground);
} else {
g.setColor(acceleratorForeground);
}
SwingUtilities2.drawString(
lh.getMenuItem(), g, lh.getAccText(),
// lr.getAccRect().x, >>>
lh.getViewRect().x + lh.getViewRect().width
- lh.getMenuItem().getIconTextGap() - lr.getAccRect().width,
// <<<
lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
}
}
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin解説
-
Default
- デフォルトの
Windows
環境の場合Accelerator
は左寄せ - デフォルトの
Ubuntu
環境の場合Accelerator
は右寄せ
- デフォルトの
-
RightAcc
-
BasicMenuItemUI#paintMenuItem(...)
メソッドをオーバーライドして、JMenuItem
のAccelerator
を左寄せではなく右寄せで表示 -
Web Start
で実行するとjava.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.swing")
と例外が発生してメニューが表示されない -
sun.swing.MenuItemLayoutHelper
や、sun.swing.MenuItemLayoutHelper.LayoutResult
などの内部所有のAPI
を使用しているので、今後も使用できるか不明 -
paintText(...)
、paintCheckIcon(...)
、paintIcon(...)
、paintArrowIcon(...)
などのBasicMenuItemUI
のプライベートなメソッドをほぼそのままコピーして使用している -
ComponentOrientation.RIGHT_TO_LEFT
が設定されて、文字列が右から左に配置される場合は考慮していない
-
- -
-
EastAcc
-
Windows 7
環境のWindowsLookAndFeel
でのみ正常に動作? -
JMenuItem
にGridBagLayout
を設定し、c.anchor = GridBagConstraints.EAST;
で、Accelerator
文字列を設定したJLabel
を配置 - 本来の
Accelerator
文字列は、UIManager.put("MenuItem.acceleratorForeground", background);
などで背景色と同化して非表示 - 参考: JMenuItemの内部にJButtonを配置する
#spanend #spanadd private static JMenuItem makeMenuItem2(JMenuItem mi) { #spanend final JLabel label = new JLabel(MenuItemUIHelper.getAccText(mi, "+")); label.setOpaque(true); JMenuItem item = new JMenuItem(mi.getText()) { @Override public void updateUI() { super.updateUI(); if (getUI() instanceof WindowsMenuItemUI) { setUI(new WindowsMenuItemUI() { @Override protected void installDefaults() { super.installDefaults(); acceleratorForeground = UIManager.getColor("MenuItem.background"); acceleratorSelectionForeground = acceleratorForeground; } }); } } }; #spanadd #spanend GridBagConstraints c = new GridBagConstraints(); item.setLayout(new GridBagLayout()); c.gridheight = 1; c.gridwidth = 1; c.gridy = 0; c.gridx = 0; c.insets = new Insets(0, 0, 0, 4); #spanadd #spanend c.weightx = 1d; c.fill = GridBagConstraints.HORIZONTAL; item.add(Box.createHorizontalGlue(), c); c.gridx = 1; c.fill = GridBagConstraints.NONE; c.weightx = 0d; c.anchor = GridBagConstraints.EAST; item.add(label, c); #spanadd #spanend item.setMnemonic(mi.getMnemonic()); item.setAccelerator(mi.getAccelerator()); return item; #spanadd } #spanend #spanadd
-
- -
-
JMenuItem
のAccelerator
がJMenuItem#setLocale(Locale.ENGLISH)
としても変化しない -
JDK 1.7.0
からLocale.getLocale()
がLocale.JAPAN
などの場合、KeyEvent#getKeyText(...)
で取得できる文字列が翻訳されている- 例:
Space
が「スペース」
- 例:
- KeyEvent#getKeyText(int) (Java Platform SE 8)では、「これらの文字列は
awt.properties
ファイルを変更することによりローカライズが可能です。」となっているが、%JAVA_HOME%/jre/lib/rt.jar
内にsun/awt/resources/awt.class
などの優先順位が高いクラスがあるため、awt_ja.properties
などを作成しても読み込まれない-
-Xbootclasspath/p:
などで、rt.jar
より先に以下のようなsun.awt.resources.awt_ja.class
を読み込むよう指定#spanend #spanadd package sun.awt.resources; #spanend #spanadd import java.util.ListResourceBundle; #spanend #spanadd // ant package #spanend #spanadd // cd target #spanend #spanadd // "%JAVA_HOME%\bin\java" -Xbootclasspath/p:example.jar -jar example.jar #spanend #spanadd // Class names should begin with an uppercase character #spanend #spanadd @SuppressWarnings({"PMD.ClassNamingConventions", "checkstyle:typename"}) #spanend #spanadd public final class awt_ja extends ListResourceBundle { #spanend @Override protected Object[][] getContents() { System.out.println("awt_ja"); return new Object[][] { {"AWT.space", "XXXXX"} }; } #spanadd } #spanend #spanadd
-
参考リンク
コメント
-
JMenuItem
にGridBagLayout
を設定して右寄せする方法を追加。 -- aterai