refactor Emoticon plugin

This commit is contained in:
Sergey Ponomarev
2026-07-26 16:00:20 +03:00
parent 89a904c008
commit ad4c86c036
7 changed files with 179 additions and 241 deletions

View File

@ -63,11 +63,8 @@ public class ButtonFactory {
public RolloverButton createEmoticonButton() { public RolloverButton createEmoticonButton() {
final EmoticonManager emoticonManager = EmoticonManager.getInstance(); final EmoticonManager emoticonManager = EmoticonManager.getInstance();
final String activeEmoticonSetName = emoticonManager.getActiveEmoticonSetName(); ImageIcon icon = emoticonManager.getEmoticonImage(":)");
final Emoticon smileEmoticon = emoticonManager.getEmoticon(activeEmoticonSetName, ":)"); if (icon != null) {
if (smileEmoticon != null) {
URL emotionURL = emoticonManager.getEmoticonURL(smileEmoticon);
ImageIcon icon = new ImageIcon(emotionURL);
return new RolloverButton(icon); return new RolloverButton(icon);
} }
return new RolloverButton(":)"); return new RolloverButton(":)");

View File

@ -52,6 +52,7 @@ import java.awt.Insets;
import java.awt.Window; import java.awt.Window;
import java.io.File; import java.io.File;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import static java.awt.GridBagConstraints.BOTH; import static java.awt.GridBagConstraints.BOTH;
import static java.awt.GridBagConstraints.CENTER; import static java.awt.GridBagConstraints.CENTER;
@ -101,7 +102,7 @@ public class ThemePanel extends JPanel {
private final JComboBox<String> _showReconnectBox; private final JComboBox<String> _showReconnectBox;
private final JScrollPane emoticonScrollPane; private final JScrollPane emoticonScrollPane;
private JPanel emoticonsPanel; private EmoticonPanel emoticonsPanel;
private final LocalPreferences pref = SettingsManager.getLocalPreferences(); private final LocalPreferences pref = SettingsManager.getLocalPreferences();
@ -185,7 +186,7 @@ public class ThemePanel extends JPanel {
TranscriptWindow emoticonPreviewTranscript = new TranscriptWindow(); TranscriptWindow emoticonPreviewTranscript = new TranscriptWindow();
emoticonPreviewTranscript.setForceEmoticons(true); emoticonPreviewTranscript.setForceEmoticons(true);
String[] sizeChoices = {"16", "24", "32", "48", "96", "120"}; String[] sizeChoices = {"16", "24", "32", "48", "64"};
avatarSizeField = new JComboBox<>(sizeChoices); avatarSizeField = new JComboBox<>(sizeChoices);
String[] r = { String[] r = {
@ -277,10 +278,8 @@ public class ThemePanel extends JPanel {
hideInTaskbar.setSelected(pref.isHideInTaskbar()); hideInTaskbar.setSelected(pref.isHideInTaskbar());
final EmoticonManager emoticonManager = EmoticonManager.getInstance(); final EmoticonManager emoticonManager = EmoticonManager.getInstance();
if (emoticonManager.getEmoticonPacks() != null) { for (String pack : emoticonManager.getEmoticonPacks()) {
for (String pack : emoticonManager.getEmoticonPacks()) { emoticonBox.addItem(pack);
emoticonBox.addItem(pack);
}
} }
final String activePack = pref.getEmoticonPack(); final String activePack = pref.getEmoticonPack();
@ -323,7 +322,8 @@ public class ThemePanel extends JPanel {
*/ */
protected void showSelectedEmoticon() { protected void showSelectedEmoticon() {
EmoticonManager emoticonManager = EmoticonManager.getInstance(); EmoticonManager emoticonManager = EmoticonManager.getInstance();
int i = emoticonManager.getActiveEmoticonSet().size(); Set<Emoticon> activeEmoticonSet = emoticonManager.getActiveEmoticonSet();
int i = activeEmoticonSet.size();
if (i == 0) { if (i == 0) {
emoticonsPanel = new EmoticonPanel(1); emoticonsPanel = new EmoticonPanel(1);
JLabel label = new JLabel(SparkRes.getImageIcon(SparkRes.Icon.SMALL_DELETE)); JLabel label = new JLabel(SparkRes.getImageIcon(SparkRes.Icon.SMALL_DELETE));
@ -333,13 +333,13 @@ public class ThemePanel extends JPanel {
} else { } else {
emoticonsPanel = new EmoticonPanel(10); emoticonsPanel = new EmoticonPanel(10);
} }
for (Emoticon emoticon : emoticonManager.getActiveEmoticonSet()) { for (Emoticon emoticon : activeEmoticonSet) {
ImageIcon ico = new ImageIcon(emoticonManager.getEmoticonURL(emoticon)); ImageIcon ico = new ImageIcon(emoticonManager.getEmoticonURL(emoticon));
JLabel label = new JLabel(ico); JLabel label = new JLabel(ico);
emoticonsPanel.add(label); emoticonsPanel.add(label);
} }
int rows = Math.min(((EmoticonPanel) emoticonsPanel).getNumRows() * 45, 300); int rows = Math.min(emoticonsPanel.getNumRows() * 45, 300);
emoticonScrollPane.setPreferredSize(new Dimension(300, rows)); emoticonScrollPane.setPreferredSize(new Dimension(300, rows));
emoticonScrollPane.setViewportView(emoticonsPanel); emoticonScrollPane.setViewportView(emoticonsPanel);
this.revalidate(); this.revalidate();

View File

@ -270,7 +270,11 @@ public class URLFileSystem {
*/ */
public static String getName(URL url) { public static String getName(URL url) {
final String fileName = getFileName(url); final String fileName = getFileName(url);
final int firstDot = fileName.lastIndexOf('.'); return getName(fileName);
}
public static String getName(String fileName) {
int firstDot = fileName.lastIndexOf('.');
return firstDot > 0 ? fileName.substring(0, firstDot) : fileName; return firstDot > 0 ? fileName.substring(0, firstDot) : fileName;
} }

View File

@ -24,62 +24,45 @@ import java.io.File;
* @author Derek DeMoro * @author Derek DeMoro
*/ */
public class Emoticon { public class Emoticon {
private final String imageName;
private String imageName; private final String emoticonName;
private String emoticonName;
private final File emoticonDirectory; private final File emoticonDirectory;
private final List<String> equivalants; private final List<String> equivalents;
/** /**
* Creates a single Emoticon entry. * Creates a single Emoticon entry.
* *
* @param nameOfImage the name of the image that represents this emoticon (ex. smile.gif) * @param nameOfImage the name of the image that represents this emoticon (ex. smile.gif)
* @param emoticonName the name of this emoticon * @param emoticonName the name of this emoticon
* @param equivalants all string representations of this emoticon. * @param equivalents all string representations of this emoticon.
* @param emoticonDirectory Directory that contains emoticons. * @param emoticonDirectory Directory that contains emoticons.
*/ */
public Emoticon(String nameOfImage, String emoticonName, List<String> equivalants, File emoticonDirectory) { public Emoticon(String nameOfImage, String emoticonName, List<String> equivalents, File emoticonDirectory) {
this.imageName = nameOfImage; this.imageName = nameOfImage;
this.emoticonName = emoticonName; this.emoticonName = emoticonName;
this.equivalents = equivalents;
this.equivalants = equivalants;
this.emoticonDirectory = emoticonDirectory; this.emoticonDirectory = emoticonDirectory;
} }
/** /**
* Return the name of the image. * Return the name of the image.
*
* @return image name.
*/ */
public String getImageName() { public String getImageName() {
return imageName; return imageName;
} }
public void setImageName(String imageName) {
this.imageName = imageName;
}
/** /**
* Returns the name of this emoticon. * Returns the name of this emoticon.
*
* @return name of emoticon.
*/ */
public String getEmoticonName() { public String getEmoticonName() {
return emoticonName; return emoticonName;
} }
public void setEmoticonName(String emoticonName) {
this.emoticonName = emoticonName;
}
/** /**
* Returns all text equivilants of this emoticon. * Returns all text equivalents of this emoticon.
*
* @return list of all text equivilants.
*/ */
public List<String> getEquivalants() { public List<String> getEquivalents() {
return equivalants; return equivalents;
} }
public File getEmoticonDirectory(){ public File getEmoticonDirectory(){

View File

@ -46,6 +46,7 @@ import java.util.jar.JarFile;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.apache.commons.lang3.Strings.CI;
/** /**
* Responsible for the handling of all Emoticon packs. Using the * Responsible for the handling of all Emoticon packs. Using the
@ -61,22 +62,22 @@ public class EmoticonManager {
// Mapped by pack name, then by 'equivalent' key. // Mapped by pack name, then by 'equivalent' key.
private final Map<String, Map<String, Emoticon>> emoticonMap = new HashMap<>(); private final Map<String, Map<String, Emoticon>> emoticonMap = new HashMap<>();
private final Map<String, ImageIcon> imageMap = new HashMap<>(); private final Map<String, ImageIcon> imageMap = new HashMap<>();
private Map<String, Emoticon> activeEmoticonMap;
/** /**
* The root emoticon directory. * The root emoticon directory.
*/ */
public File EMOTICON_DIRECTORY; private File EMOTICON_DIRECTORY;
private final LocalPreferences pref = SettingsManager.getLocalPreferences(); private final LocalPreferences pref = SettingsManager.getLocalPreferences();
public static EmoticonManager getInstance() { public static EmoticonManager getInstance() {
synchronized (LOCK) { if (singleton != null) {
if (null == singleton) { return singleton;
EmoticonManager controller = new EmoticonManager(); }
singleton = controller; synchronized (LOCK) {
return controller; singleton = new EmoticonManager();
} return singleton;
} }
return singleton;
} }
private EmoticonManager() { private EmoticonManager() {
@ -118,10 +119,10 @@ public class EmoticonManager {
// Check if File is Zip-File // Check if File is Zip-File
int endIndex = file.getName().indexOf(".zip"); int endIndex = file.getName().indexOf(".zip");
if (endIndex > 0) { if (endIndex > 0) {
String unzipURL = file.getName().substring(0, endIndex); String unzippedFolderName = file.getName().substring(0, endIndex);
File unzipFile = new File(profileEmoticonsFolder, unzipURL); File unzippedFolder = new File(profileEmoticonsFolder, unzippedFolderName);
if (!unzipFile.exists() || !checkIfSameFile(file, newFile)) { if (!unzippedFolder.exists() || !checkIfSameFile(file, newFile)) {
// Copy over and expand :) Log.debug("Copying " + file.getName() + " to " + profileEmoticonsFolder + " and unpack");
URLFileSystem.copy(file.toURI().toURL(), newFile); URLFileSystem.copy(file.toURI().toURL(), newFile);
expandNewPack(newFile, profileEmoticonsFolder); expandNewPack(newFile, profileEmoticonsFolder);
} }
@ -175,22 +176,15 @@ public class EmoticonManager {
/** /**
* Returns the active emoticon set within Spark. * Returns the active emoticon set within Spark.
*/ */
public Collection<Emoticon> getActiveEmoticonSet() { public Set<Emoticon> getActiveEmoticonSet() {
String emoticonPack = pref.getEmoticonPack(); String emoticonPack = pref.getEmoticonPack();
// If EmoticonPack is set // If EmoticonPack is set
//When no emoticon set is available, return an empty list
if (emoticonPack != null) { if (emoticonPack != null) {
Map<String, Emoticon> emoticons = emoticonMap.get(emoticonPack); Map<String, Emoticon> emoticons = emoticonMap.get(emoticonPack);
return emoticons != null ? new LinkedHashSet<>(emoticons.values()) : List.of(); // When no emoticon set is available, return an empty list
return emoticons != null ? new LinkedHashSet<>(emoticons.values()) : Set.of();
} }
return List.of(); return Set.of();
}
/**
* Returns the name of the active emoticon set.
*/
public String getActiveEmoticonSetName() {
return pref.getEmoticonPack();
} }
/** /**
@ -201,6 +195,7 @@ public class EmoticonManager {
public void setActivePack(String pack) { public void setActivePack(String pack) {
pref.setEmoticonPack(pack); pref.setEmoticonPack(pack);
imageMap.clear(); imageMap.clear();
activeEmoticonMap = null;
} }
/** /**
@ -213,21 +208,18 @@ public class EmoticonManager {
if (!containsEmoticonPList(pack)) { if (!containsEmoticonPList(pack)) {
return null; return null;
} }
String name;
// Copy to the emoticon area // Copy to the emoticon area
try { try {
File dst = new File(EMOTICON_DIRECTORY, pack.getName()); File dst = new File(EMOTICON_DIRECTORY, pack.getName());
URLFileSystem.copy(pack.toURI().toURL(), dst); URLFileSystem.copy(pack.toURI().toURL(), dst);
File rootDirectory = unzipPack(pack, EMOTICON_DIRECTORY); File rootDirectory = unzipPack(pack, EMOTICON_DIRECTORY);
name = URLFileSystem.getName(rootDirectory.toURI().toURL()); String name = URLFileSystem.getName(rootDirectory.toURI().toURL());
addEmoticonPack(name); addEmoticonPack(name);
} catch (IOException e) { return name;
Log.error(e); } catch (Exception e) {
Log.error("Unable to install emoticon pack: " + pack.getAbsolutePath(), e);
return null; return null;
} }
return name;
} }
/** /**
@ -240,11 +232,8 @@ public class EmoticonManager {
if (!emoticonSet.exists()) { if (!emoticonSet.exists()) {
emoticonSet = new File(EMOTICON_DIRECTORY, packName + ".AdiumEmoticonset"); emoticonSet = new File(EMOTICON_DIRECTORY, packName + ".AdiumEmoticonset");
} }
if (!emoticonSet.exists()) { if (!emoticonSet.exists()) {
emoticonSet = new File(EMOTICON_DIRECTORY, "Default.adiumemoticonset"); Log.error("The emoticons file not found in " + emoticonSet.getAbsolutePath());
packName = "Default";
setActivePack("Default");
} }
final File plist = new File(emoticonSet, "Emoticons.plist"); final File plist = new File(emoticonSet, "Emoticons.plist");
@ -252,7 +241,6 @@ public class EmoticonManager {
Log.error("Emoticons.plist not found in " + emoticonSet.getAbsolutePath()); Log.error("Emoticons.plist not found in " + emoticonSet.getAbsolutePath());
return; return;
} }
Map<String, Emoticon> emoticons = new LinkedHashMap<>();
// Create SaxReader and set to non-validating parser. // Create SaxReader and set to non-validating parser.
// This will allow for non-http problems to not break spark :) // This will allow for non-http problems to not break spark :)
@ -280,6 +268,7 @@ public class EmoticonManager {
return; return;
} }
Map<String, Emoticon> emoticons = new LinkedHashMap<>();
Node root = emoticonFile.selectSingleNode("/plist/dict/dict"); Node root = emoticonFile.selectSingleNode("/plist/dict/dict");
List<Node> keyList = root.selectNodes("key"); List<Node> keyList = root.selectNodes("key");
List<Node> dictonaryList = root.selectNodes("dict"); List<Node> dictonaryList = root.selectNodes("dict");
@ -295,7 +284,7 @@ public class EmoticonManager {
equivs.add(equivalent.getText()); equivs.add(equivalent.getText());
} }
final Emoticon emoticon = new Emoticon(key, name, equivs, emoticonSet); final Emoticon emoticon = new Emoticon(key, name, equivs, emoticonSet);
for (String equivalent : emoticon.getEquivalants()) { for (String equivalent : emoticon.getEquivalents()) {
emoticons.put(equivalent, emoticon); emoticons.put(equivalent, emoticon);
} }
} }
@ -318,21 +307,6 @@ public class EmoticonManager {
return null; return null;
} }
/**
* Retrieves the associated key emoticon.
*
* @param packName the name of the Archive Pack File.
* @param key the key.
* @return the emoticon.
*/
public Emoticon getEmoticon(String packName, String key) {
final Map<String, Emoticon> emoticons = emoticonMap.get(packName);
if (emoticons == null) {
return null;
}
return emoticons.get(key);
}
/** /**
* Returns the <code>Emoticon</code> associated with the given key. Note: * Returns the <code>Emoticon</code> associated with the given key. Note:
* This gets the emoticon from the active emoticon pack. * This gets the emoticon from the active emoticon pack.
@ -341,7 +315,14 @@ public class EmoticonManager {
* @return the Emoticon found. If no emoticon is found, null is returned. * @return the Emoticon found. If no emoticon is found, null is returned.
*/ */
public Emoticon getEmoticon(String key) { public Emoticon getEmoticon(String key) {
return getEmoticon(getActiveEmoticonSetName(), key); if (activeEmoticonMap == null) {
String packName = pref.getEmoticonPack();
activeEmoticonMap = emoticonMap.get(packName);
if (activeEmoticonMap == null) {
activeEmoticonMap = Map.of();
}
}
return activeEmoticonMap.get(key);
} }
/** /**
@ -352,39 +333,31 @@ public class EmoticonManager {
*/ */
public ImageIcon getEmoticonImage(String key) { public ImageIcon getEmoticonImage(String key) {
final Emoticon emoticon = getEmoticon(key); final Emoticon emoticon = getEmoticon(key);
if (emoticon != null) { if (emoticon == null) {
ImageIcon icon = imageMap.get(key); return null;
if (icon == null) {
URL url = getEmoticonURL(emoticon);
icon = new ImageIcon(url);
imageMap.put(key, icon);
}
return imageMap.get(key);
} }
return null; ImageIcon icon = imageMap.computeIfAbsent(key, it -> {
URL url = getEmoticonURL(emoticon);
return new ImageIcon(url);
});
return icon;
} }
/** /**
* Returns a list of all available emoticon packs. * Returns a list of all available emoticon packs.
*
* @return Collection of Emoticon Pack names.
*/ */
public Collection<String> getEmoticonPacks() { public Collection<String> getEmoticonPacks() {
final List<String> emoticonList = new ArrayList<>();
File[] dirs = EMOTICON_DIRECTORY.listFiles(File::isDirectory); File[] dirs = EMOTICON_DIRECTORY.listFiles(File::isDirectory);
// If no emoticons are available // If no emoticons are available
if (dirs == null) { if (dirs == null) {
return null; return List.of();
} }
List<String> emoticonList = new ArrayList<>(dirs.length);
for (File file : dirs) { for (File file : dirs) {
if (file.getName().toLowerCase().endsWith("adiumemoticonset")) { String fileName = file.getName();
try { if (CI.endsWith(fileName, ".adiumemoticonset")) {
String name = URLFileSystem.getName(file.toURI().toURL()); String name = URLFileSystem.getName(fileName);
name = name.replace("adiumemoticonset", ""); emoticonList.add(name);
name = name.replace("AdiumEmoticonset", "");
emoticonList.add(name);
} catch (MalformedURLException ignored) {
}
} }
} }
return emoticonList; return emoticonList;
@ -397,15 +370,8 @@ public class EmoticonManager {
* @param dist Dist file. * @param dist Dist file.
*/ */
private void expandNewPack(File file, File dist) { private void expandNewPack(File file, File dist) {
URL url; String name = URLFileSystem.getName(file.getName());
try {
url = file.toURI().toURL();
} catch (MalformedURLException ignored) {
return;
}
String name = URLFileSystem.getName(url);
File directory = new File(dist, name); File directory = new File(dist, name);
// Unzip contents into directory // Unzip contents into directory
unzipPack(file, directory.getParentFile()); unzipPack(file, directory.getParentFile());
} }
@ -489,7 +455,7 @@ public class EmoticonManager {
} }
/** /**
* Deletes Emoticons in pathToSearch that have a different md5-hash than its correspondant in install\spark\xtra\emoticons * Deletes Emoticons in pathToSearch that have a different md5-hash than its correspondent in install\spark\xtra\emoticons
*/ */
private void deleteOldEmoticons(File pathToSearch) { private void deleteOldEmoticons(File pathToSearch) {
final File installPath = new File(Spark.getXtraDirectory(), "emoticons"); final File installPath = new File(Spark.getXtraDirectory(), "emoticons");
@ -526,6 +492,7 @@ public class EmoticonManager {
} }
private void uninstall(File emoticonDir) { private void uninstall(File emoticonDir) {
Log.warning("Uninstall emoticons pack: " + emoticonDir.getAbsolutePath());
try { try {
Files.walkFileTree(emoticonDir.toPath(), new SimpleFileVisitor<>() { Files.walkFileTree(emoticonDir.toPath(), new SimpleFileVisitor<>() {
@Override @Override

View File

@ -43,11 +43,10 @@ import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
* @author Derek DeMoro * @author Derek DeMoro
*/ */
public class EmoticonPlugin implements Plugin, ChatRoomListener { public class EmoticonPlugin implements Plugin, ChatRoomListener {
private ChatManager chatManager;
@Override @Override
public void initialize() { public void initialize() {
chatManager = SparkManager.getChatManager(); ChatManager chatManager = SparkManager.getChatManager();
// Listen for rooms opening to add emoticon picker // Listen for rooms opening to add emoticon picker
chatManager.addChatRoomListener(this); chatManager.addChatRoomListener(this);
// Add Preferences // Add Preferences
@ -55,66 +54,60 @@ public class EmoticonPlugin implements Plugin, ChatRoomListener {
} }
@Override @Override
public void chatRoomOpened(final ChatRoom room) { public void chatRoomOpened(ChatRoom room) {
// Check to see if emoticons are enabled. // Check to see if emoticons are enabled.
if (!SettingsManager.getLocalPreferences().areEmoticonsEnabled()) { if (!SettingsManager.getLocalPreferences().areEmoticonsEnabled()) {
return; return;
} }
// Add Emoticon button // Add Emoticon button
final RolloverButton emoticonPicker = UIComponentRegistry.getButtonFactory().createEmoticonButton(); RolloverButton emoticonPicker = UIComponentRegistry.getButtonFactory().createEmoticonButton();
room.addEditorComponent(emoticonPicker); room.addEditorComponent(emoticonPicker);
emoticonPicker.addMouseListener(new MouseAdapter() { emoticonPicker.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
// Show popup // Show popup
final JPopupMenu popup = new JPopupMenu(); JPopupMenu popup = new JPopupMenu();
EmoticonUI emoticonUI = new EmoticonUI(); EmoticonUI emoticonUI = new EmoticonUI();
emoticonUI emoticonUI.setEmoticonPickListener(emoticon -> {
.setEmoticonPickListener( emoticon -> { popup.setVisible(false);
try { ChatInputEditor editor = room.getChatInputEditor();
popup.setVisible(false); String currentText = editor.getText();
final ChatInputEditor editor = room.getChatInputEditor(); String emoticonText = currentText.isEmpty() || currentText.endsWith(" ") ? emoticon + " " : " " + emoticon + " ";
String currentText = editor.getText(); try {
if (currentText.isEmpty() || currentText.endsWith(" ")) { room.getChatInputEditor().insertText(emoticonText);
room.getChatInputEditor().insertText(emoticon + " "); } catch (BadLocationException e1) {
} else { Log.error(e1);
room.getChatInputEditor()
.insertText(" " + emoticon + " ");
}
room.getChatInputEditor().requestFocus();
} catch (BadLocationException e1) {
Log.error(e1);
}
} );
popup.add(emoticonUI);
int actualX = e.getX()+10;
int actualY = e.getY();
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final ChatContainer chat = SparkManager.getChatManager().getChatContainer();
// if height Spark Chat Windows > height 0.9* screenSize we should put emoticon window above
if(chat.getHeight() > screenSize.getHeight()*0.90){
actualY = e.getY()-100;
} }
popup.show(emoticonPicker, actualX, actualY); room.getChatInputEditor().requestFocus();
} });
});
room.addClosingListener( () -> room.removeEditorComponent(emoticonPicker) ); popup.add(emoticonUI);
} int actualX = e.getX() + 10;
int actualY = e.getY();
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final ChatContainer chat = SparkManager.getChatManager().getChatContainer();
// if height Spark Chat Windows > height 0.9*screenSize, we should put emoticon window above
if (chat.getHeight() > screenSize.getHeight() * 0.90) {
actualY = e.getY() - 100;
}
popup.show(emoticonPicker, actualX, actualY);
}
});
@Override room.addClosingListener(() -> room.removeEditorComponent(emoticonPicker));
public void shutdown() { }
}
@Override @Override
public boolean canShutDown() { public void shutdown() {
return false; }
}
@Override @Override
public void uninstall() { public boolean canShutDown() {
} return false;
}
@Override
public void uninstall() {
}
} }

View File

@ -25,7 +25,7 @@ import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.net.URL; import java.net.URL;
import java.util.Collection; import java.util.Set;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -33,66 +33,60 @@ import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
public class EmoticonUI extends JPanel { public class EmoticonUI extends JPanel {
private EmoticonPickListener listener; private EmoticonPickListener listener;
public EmoticonUI() { public EmoticonUI() {
setBackground(Color.white); setBackground(Color.white);
final EmoticonManager manager = EmoticonManager.getInstance(); final EmoticonManager manager = EmoticonManager.getInstance();
Collection<Emoticon> emoticons = manager.getActiveEmoticonSet(); Set<Emoticon> emoticons = manager.getActiveEmoticonSet();
if (emoticons != null) { int no = emoticons.size();
int no = emoticons.size(); // Emoticons per row
// Emoticons per row int cntInRow = 6;
int cntInRow = 6; // Count rows of Emoticons
// Count rows of Emoticons int rows = no / cntInRow + ((no % cntInRow == 0) ? 0 : 1);
int rows = no / cntInRow + ((no % cntInRow == 0) ? 0 : 1); Container gridContainer = new Container();
Container gridContainer = new Container(); GridLayout grid = new GridLayout(0, cntInRow);
GridLayout grid = new GridLayout(0, cntInRow); JScrollPane scrollPane = new JScrollPane(gridContainer);
JScrollPane scrollPane = new JScrollPane(gridContainer); scrollPane.getViewport().setBackground(Color.WHITE);
scrollPane.getViewport().setBackground(Color.WHITE); scrollPane.setBorder(BorderFactory.createEmptyBorder());
scrollPane.setBorder(BorderFactory.createEmptyBorder()); gridContainer.setLayout(grid);
gridContainer.setLayout(grid); // Show only vertical scrollbar if it needed
// Show only vertical scrollbar if it needed scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); int scrollBarWidth = scrollPane.getVerticalScrollBar().getPreferredSize().width;
int scrollBarWidth = scrollPane.getVerticalScrollBar().getPreferredSize().width; // Add ScrollPane to Panel
// Add ScrollPane to Panel add(scrollPane);
add(scrollPane); // Add Emoticons
// setIgnoreRepaint(true); for (Emoticon emoticon : emoticons) {
// Add Emoticons String text = emoticon.getEquivalents().get(0);
for (Emoticon emoticon : emoticons) { URL smileURL = manager.getEmoticonURL(emoticon);
final String text = emoticon.getEquivalants().get(0); // Add Emoticon button
String name = manager.getActiveEmoticonSetName(); ImageIcon icon = new ImageIcon(smileURL);
final Emoticon smileEmoticon = manager.getEmoticon(name, text);
URL smileURL = manager.getEmoticonURL(smileEmoticon);
// Add Emoticon button
ImageIcon icon = new ImageIcon(smileURL);
RolloverButton emotButton = new RolloverButton(); RolloverButton emotButton = new RolloverButton();
emotButton.setIcon(icon); emotButton.setIcon(icon);
emotButton.addActionListener( e -> listener.emoticonPicked(text) ); emotButton.addActionListener(e -> listener.emoticonPicked(text));
emotButton.setToolTipText(emoticon.getEmoticonName() + " " + text);
gridContainer.add(emotButton); gridContainer.add(emotButton);
} }
// Set up parameters of vertical scrollbar
// Set up parameters of vertical scrollbar scrollPane.getVerticalScrollBar().setMaximum(rows);
scrollPane.getVerticalScrollBar().setMaximum(rows); scrollPane.getVerticalScrollBar().setUnitIncrement(55);
scrollPane.getVerticalScrollBar().setUnitIncrement(55); // Change width of ScrollPane if it needed
Dimension containerPreferredSize = gridContainer.getPreferredSize();
if (containerPreferredSize.getHeight() > containerPreferredSize.getWidth()) {
int width = (int) containerPreferredSize.getWidth() + 2 * scrollBarWidth;
int height = (int) containerPreferredSize.getWidth() * 2 / 3;
scrollPane.setPreferredSize(new Dimension(width, height));
}
}
// Change width of ScrollPane if it needed public void setEmoticonPickListener(EmoticonPickListener listener) {
if (gridContainer.getPreferredSize().getHeight() > gridContainer.getPreferredSize().getWidth()) { this.listener = listener;
scrollPane.setPreferredSize(new Dimension( }
(int) gridContainer.getPreferredSize().getWidth() + 2 * scrollBarWidth,
(int) gridContainer.getPreferredSize().getWidth() * 2 / 3
));
}
}
}
public void setEmoticonPickListener(EmoticonPickListener listener) { public interface EmoticonPickListener {
this.listener = listener; void emoticonPicked(String emoticon);
} }
public interface EmoticonPickListener {
void emoticonPicked(String emoticon);
}
} }