Skip to content

Commit

Permalink
feat: AbstractMnemonicsAction class (#8)
Browse files Browse the repository at this point in the history
* feat: AbstractMnemonicsAction class

- Introduce MnemonicsAction interface
- Give Action with mnemonics processing

Signed-off-by: Hiroshi Miura <miurahr@linux.com>

* feat: add constructor and method that take a bundle or omitting locale

* style: imports

* refactor: weaken visibility

---------

Signed-off-by: Hiroshi Miura <miurahr@linux.com>
  • Loading branch information
miurahr committed Mar 16, 2024
1 parent 7546a49 commit 6f1fb17
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 23 deletions.
48 changes: 48 additions & 0 deletions src/org/openide/awt/AbstractMnemonicsAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.openide.awt;

import javax.swing.*;
import java.util.Locale;
import java.util.ResourceBundle;

/**
* @author Hiroshi Miura
*/
public abstract class AbstractMnemonicsAction extends AbstractAction {
public AbstractMnemonicsAction() {
super();
}

public AbstractMnemonicsAction(String key, ResourceBundle bundle) {
super();
setText(key, bundle);
}

public AbstractMnemonicsAction(String text, Locale locale) {
super();
setText(text, locale);
}

public AbstractMnemonicsAction(String text) {
super();
setText(text);
}

public void setText(String key, ResourceBundle bundle) {
setText(bundle.getString(key), bundle.getLocale());
}

public void setText(String text) {
setText(text, new Locale("en"));
}

public void setText(String text, Locale locale) {
int i = Mnemonics.findMnemonicAmpersand(text);
if (i < 0) {
putValue(Action.NAME, text);
putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, -1);
} else {
putValue(Action.NAME, text.substring(0, i) + text.substring(i + 1));
Mnemonics.setMnemonicAndIndex(this, text.charAt(i + 1), i, locale);
}
}
}
57 changes: 35 additions & 22 deletions src/org/openide/awt/Mnemonics.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.regex.Pattern;

import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.JLabel;

/**
Expand All @@ -54,7 +55,7 @@
* @since 3.37
* @see <a href="http://www.netbeans.org/issues/show_bug.cgi?id=26640">Issue #26640</a>
*/
public final class Mnemonics extends Object {
public final class Mnemonics {

private static final Pattern RE_MNEMONIC_END = Pattern.compile("\\s*\\(&[A-Za-z0-9]\\)(?=[.\\uFF1A]*$)");
private static final Pattern RE_MNEMONIC_INSIDE = Pattern.compile("&(\\p{L})");
Expand Down Expand Up @@ -194,39 +195,44 @@ public static int findMnemonicAmpersand(String text) {
* @param item AbstractButton/JLabel or subclasses
* @param ch Mnemonic char to set, may be a char in some locale
* @param locale locale of the text.
* @param index Index of the Character to underline under JDK1.4
*/
private static void setMnemonicAndIndex (Object item, char ch, int index, Locale locale) {
static void setMnemonicAndIndex(Object item, char ch, int index, Locale locale) {

// OmegaT tweak
// if we're running on non-MacOSX, we don't set any mnemonics
if (isMacOS()) {
setMnemonic(item, 0);
if (isMacOS() || ch == 0) {
setMnemonic(item, 0);
setMnemonicIndex(item, -1);
} else {
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
|| (ch >= '0' && ch <= '9')) {
// it's latin character or arabic digit,
// it's a latin character or arabic digit,
// setting it as mnemonics
setMnemonic(item, ch);
// If it's something like "Save &As", we need to set another
// mnemonic index (at least under 1.4 or later)
// see #29676
setMnemonicIndex(item, index);
} else {
// it's non-latin, getting the latin correspondance
// it's non-latin, getting the latin correspondence
int latinCode = getLatinKeycode(ch, locale);
setMnemonic(item, latinCode);
if( latinCode!=0 )
if (latinCode == 0) {
setMnemonicIndex(item, -1);
} else {
setMnemonicIndex(item, index);
}
}
}
}

/**
* Gets the Latin symbol which corresponds
* Gets the Latin symbol, which corresponds
* to some non-Latin symbol on the localized keyboard.
* The search is done via lookup of Resource bundle
* for pairs having the form (e.g.) <code>MNEMONIC_\u0424=A</code>.
* The search is done via lookup of a Resource bundle
* for pairs having the form (e.g.) <code>MNEMONIC_Ф=A</code>.
*
* @param localeChar non-Latin character or a punctuator to be used as mnemonic
* @return character on latin keyboard, corresponding to the locale character,
Expand Down Expand Up @@ -256,27 +262,31 @@ private static int getLatinKeycode(char localeChar, Locale locale) {
* <li>Under JDK1.4 calls the method on item
* <li>Under JDK1.3 adds " (&lt;latin character&gt;)" (if needed)
* to label and sets the latin character as mnemonics.
* @param item AbstractButton/JLabel or subclasses
* @param item AbstractButton/JLabel/Action or subclasses
* @param index Index of the Character to underline under JDK1.4
*/
private static void setMnemonicIndex (Object item, int index) {
if (item instanceof AbstractButton) {
if (item instanceof Action) {
((Action) item).putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, index);
} else if (item instanceof AbstractButton) {
((AbstractButton)item).setDisplayedMnemonicIndex(index);
} else if (item instanceof JLabel) {
((JLabel)item).setDisplayedMnemonicIndex(index);
}
}

/**
* Wrapper for AbstractButton/JLabel.setText
* @param item AbstractButton/JLabel
* Wrapper for AbstractButton/JLabel.setText and Action.putValue.
* @param item AbstractButton/JLabel/Action
* @param text the text to set
*/
private static void setText(Object item, String text) {
if (item instanceof AbstractButton) {
((AbstractButton)item).setText(text);
} else {
((JLabel)item).setText(text);
if (item instanceof Action) {
((Action) item).putValue(Action.NAME, text);
} else if (item instanceof AbstractButton) {
((AbstractButton) item).setText(text);
} else if (item instanceof JLabel) {
((JLabel) item).setText(text);
}
}

Expand All @@ -286,12 +296,15 @@ private static void setText(Object item, String text) {
* @param mnem Mnemonic char to set, latin [a-z,A-Z], digit [0-9], or any VK_ code
*/
private static void setMnemonic(Object item, int mnem) {
if(mnem>='a' && mnem<='z')
if (mnem>='a' && mnem<='z') {
mnem=mnem+('A'-'a');
if (item instanceof AbstractButton) {
((AbstractButton)item).setMnemonic(mnem);
}
if (item instanceof Action) {
((Action) item).putValue(Action.MNEMONIC_KEY, mnem);
} else if (item instanceof AbstractButton) {
((AbstractButton) item).setMnemonic(mnem);
} else {
((JLabel)item).setDisplayedMnemonic(mnem);
((JLabel) item).setDisplayedMnemonic(mnem);
}
}

Expand Down
34 changes: 34 additions & 0 deletions test/src/org/openide/awt/MnemonicsActionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.openide.awt;

import org.junit.Assert;
import org.junit.Test;

import javax.swing.Action;
import java.awt.event.ActionEvent;
import java.util.Locale;

import static org.openide.awt.Mnemonics.isMacOS;

public class MnemonicsActionTest {

@Test
public void testSetLocalizedTextAction() {
AbstractMnemonicsAction item = new AbstractMnemonicsAction() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
}
};
item.setText("&Simple Text");
Assert.assertEquals("Simple Text", item.getValue(Action.NAME));
Assert.assertEquals(isMacOS()? -1: 0, item.getValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY));
//
item.setText("Rock & Roll");
Assert.assertEquals("Rock & Roll", item.getValue(Action.NAME));
Assert.assertEquals(-1, item.getValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY));
//
item.setText("&\u041F\u043E\u0438\u0441\u043A", new Locale("ru"));
Assert.assertEquals("\u041F\u043E\u0438\u0441\u043A", item.getValue(Action.NAME));
Assert.assertEquals(isMacOS()? -1: 0, item.getValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY));
Assert.assertEquals(isMacOS()? 0: 71, item.getValue(Action.MNEMONIC_KEY));
}
}
2 changes: 1 addition & 1 deletion test/src/org/openide/awt/MnemonicsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public final class MnemonicsTest {

@Test
public void testRemoveMnemonics() throws Exception {
public void testRemoveMnemonics() {
Assert.assertEquals("Simple test", Mnemonics.removeMnemonics("&Simple test"));
Assert.assertEquals("Rock & Roll", Mnemonics.removeMnemonics("Rock & Roll"));
// Parenthesis at the end, but with latin characters
Expand Down

0 comments on commit 6f1fb17

Please sign in to comment.