22. december 2014 - 22:53
Der er
4 kommentarer og
1 løsning
Why does my editor repalce chars?
Hello guys!
I got a editor that is supposed to show all characters thats in UTF-8.
But some gets replaced with a square.
I have tried both JTextArea and JditorPane, and the last one I have also tried to setContentType but I still gets the replacement char.
Do you guys understand why this is happening? Do I miss some charset or fonts at my computer? Or is this a limitation in the textcompnents? Perhaps this is impossible with these textcomponents?
Best regards
Fredrik
import java.awt.Color;
import java.awt.Container;
import java.nio.charset.Charset;
import java.util.SortedMap;
import javax.swing.BoxLayout;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.JTextComponent;
public class SimpleEditor extends JFrame {
private JTextComponent textComp1;
private JTextComponent textComp2;
public static void main(String[] args) {
SimpleEditor editor = new SimpleEditor();
editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
editor.setVisible(true);
}
// Create an editor.
public SimpleEditor() {
super("Swing Editor");
textComp1 = createTextComponent();
textComp2 = createEditorComponent();
SortedMap<String, Charset> availableCharsets = Charset
.availableCharsets();
Charset charset = availableCharsets.get("UTF-8");
StringBuffer charactersForSelectedCharset = getCharactersForSelectedCharset(charset);
textComp1.setText(charactersForSelectedCharset.toString());
textComp2.setText(charactersForSelectedCharset.toString());
Container content = getContentPane();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
content.add(new JScrollPane(textComp1,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
content.add(new JScrollPane(textComp2,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
setSize(320, 500);
}
// Create the JTextComponent subclass.
protected JTextComponent createTextComponent() {
JTextArea ta = new JTextArea();
ta.setLineWrap(true);
return ta;
}
// Create the JTextComponent subclass.
protected JTextComponent createEditorComponent() {
JEditorPane ta = new JEditorPane();
ta.setContentType("text/plain; charset=UTF-8");
ta.setBackground(Color.red);
return ta;
}
private StringBuffer getCharactersForSelectedCharset(Charset charset) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = Character.MIN_VALUE; i < Character.MAX_VALUE; i++) {
String charAsString = Character.toString((char) i);
byte[] encoded = charAsString.getBytes(charset);
String decoded = new String(encoded, charset);
if (charAsString.equals(decoded)) {
stringBuffer.append(i + ": " + decoded);
stringBuffer.append("\n");
if (i == 1000) {
break;
}
}
}
return stringBuffer;
}
}
23. december 2014 - 04:14
#1
Maybe you will find the following program illustrative:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class WhatCanIDisplay extends JFrame {
private static final long serialVersionUID = 1L;
public WhatCanIDisplay() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(200, 1000));
JTextArea res = new JTextArea();
Font fnt = res.getFont();
for(int i = 0; i < 65536; i++) {
char c = (char)i;
if(fnt.canDisplay(c)) {
res.append(i + " = " + c + "\r\n");
}
}
getContentPane().add(new JScrollPane(res), BorderLayout.CENTER);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new WhatCanIDisplay();
f.setVisible(true);
}
});
}
}
23. december 2014 - 16:52
#3
Hello Arne!
Many thanks for your help, amigo!
Now I understand that this is a font-issue.
I had some time today so I added some feature to your program, I now can choose between fonts and also use mixed fonts and reload the textpane and see what chars that will be found in different fonts.
Please leave a svar so we can close this!
Best regards amigo and Glædelig jul og e Godt Nytår!
/Fredrik
[code]import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class WhatCanIDisplay extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JTextPane textArea = new JTextPane();
private JComboBox comboBox = null;
private Font fnt;
private Font[] allFonts;
public WhatCanIDisplay() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(500, 500));
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
allFonts = graphicsEnvironment.getAllFonts();
textArea.setDoubleBuffered(true);
fnt = textArea.getFont();
Font clonedFont = new Font(fnt.getFamily(), fnt.getStyle(), 14);
fnt = clonedFont;
textArea.setFont(fnt);
setText();
comboBox = new JComboBox(initiateFonts());
comboBox.setEditable(false);
comboBox.setSelectedItem(fnt.getFontName());
comboBox.addActionListener(this);
getContentPane().add(comboBox, BorderLayout.NORTH);
getContentPane().add(new JScrollPane(textArea), BorderLayout.CENTER);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new WhatCanIDisplay();
f.setVisible(true);
}
});
}
private void setText() {
StringBuffer stringBuffer = new StringBuffer();
int displayCounter = 0;
int notDisplayCounter = 0;
textArea.setText("");
for (int i = 0; i < 65536; i++)
{
char c = (char) i;
if (fnt.canDisplay(c)) {
stringBuffer.append(i + " = " + c + "\r\n");
displayCounter++;
} else {
notDisplayCounter++;
}
}
stringBuffer.append("\nCAN DISPLAY: " + displayCounter);
stringBuffer.append("\nCAN NOT DISPLAY: " + notDisplayCounter);
String fontsCapacity = getFontsCapacity();
stringBuffer.append("\n\n" + fontsCapacity);
textArea.setText(stringBuffer.toString());
}
private void setTextWithMixedFonts() throws BadLocationException {
List<Object[]> fontListCapacity = getFontListCapacity();
Font bestFont = (Font) fontListCapacity.get(0)[0];
textArea.setText("");
StyledDocument styledDocument = textArea.getStyledDocument();
Style regularStyle = styledDocument.getStyle("regular");
Style bestfontStyle = styledDocument.addStyle("bestfont", regularStyle);
StyleConstants.setFontFamily(bestfontStyle, bestFont.getFamily());
StyleConstants.setFontSize(bestfontStyle, 14);
Style newfontStyle = styledDocument.addStyle("newfont", regularStyle);
StyleConstants.setForeground(newfontStyle, Color.red);
StyleConstants.setFontSize(newfontStyle, 14);
int displayCounter = 0;
int notDisplayCounter = 0;
int newfontDisplayCounter = 0;
for (int i = 0; i < 65536; i++) {
char c = (char) i;
if (bestFont.canDisplay(c)) {
styledDocument.insertString(styledDocument.getLength(), i
+ " = " + c + "\r\n", bestfontStyle);
displayCounter++;
} else {
Font suitableFont = getSuitableFont(c);
if (suitableFont != null) {
StyleConstants.setFontFamily(newfontStyle,
suitableFont.getFamily());
styledDocument.insertString(styledDocument.getLength(), i
+ " = (" + suitableFont.getFamily() + ")" + c
+ "\r\n", newfontStyle);
newfontDisplayCounter++;
} else {
notDisplayCounter++;
}
}
}
styledDocument.insertString(styledDocument.getLength(),
"\nCAN DISPLAY: " + displayCounter, bestfontStyle);
styledDocument.insertString(styledDocument.getLength(),
"\nCAN DISPLAY IN OTHER FONT: " + newfontDisplayCounter,
newfontStyle);
styledDocument.insertString(styledDocument.getLength(),
"\nCAN NOT DISPLAY: " + notDisplayCounter, bestfontStyle);
String fontsCapacity = getFontsCapacity();
styledDocument.insertString(styledDocument.getLength(), "\n\n"
+ fontsCapacity, bestfontStyle);
}
private String[] initiateFonts() {
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
Font[] allFonts = graphicsEnvironment.getAllFonts();
String[] envfonts = new String[allFonts.length + 1];
for (int i = 0; i < allFonts.length; i++) {
envfonts[i] = allFonts[i].getFontName();
}
envfonts[envfonts.length - 1] = "MIXED FONTS";
return envfonts;
}
private List<String> initiateEncodings() {
SortedMap<String, Charset> availableCharsets = Charset
.availableCharsets();
List<String> encodingNames = new ArrayList<String>();
Set<String> keySet = availableCharsets.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()) {
String canonicalName = (String) iterator.next();
encodingNames.add(canonicalName);
}
return encodingNames;
}
public void actionPerformed(ActionEvent arg0) {
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
Font[] allFonts = graphicsEnvironment.getAllFonts();
String selectedFontName = (String) comboBox.getSelectedItem();
if ("MIXED FONTS".equals(selectedFontName)) {
try {
setTextWithMixedFonts();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
for (int i = 0; i < allFonts.length; i++) {
if (selectedFontName.equals(allFonts[i].getFontName())) {
fnt = allFonts[i];
Font clonedFont = new Font(fnt.getFamily(), fnt.getStyle(),
14);
fnt = clonedFont;
break;
}
}
textArea.setFont(fnt);
setText();
}
}
private String getFontsCapacity() {
StringBuffer stringBuffer = new StringBuffer();
List<Object[]> fontListCapacity = getFontListCapacity();
for (Iterator iterator = fontListCapacity.iterator(); iterator
.hasNext();) {
Object[] objects = (Object[]) iterator.next();
stringBuffer
.append((((Font) objects[0]).getName() + ": "
+ ((Integer) objects[1]).intValue() + " <> " + ((Integer) objects[2])
.intValue()) + "\n");
}
return stringBuffer.toString();
}
private List<Object[]> getFontListCapacity() {
List<Object[]> sortedFonts = new ArrayList<Object[]>();
for (int i = 0; i < allFonts.length; i++) {
sortedFonts.add(getFontCapacity(allFonts[i]));
}
Collections.sort(sortedFonts, new Comparator<Object[]>() {
public int compare(Object[] font1, Object[] font2) {
Integer font1DisplayCounter = (Integer) font1[1];
Integer font2DisplayCounter = (Integer) font2[1];
return font2DisplayCounter.compareTo(font1DisplayCounter);
}
});
return sortedFonts;
}
private Object[] getFontCapacity(Font font) {
Object[] fontCapacity = new Object[3];
fontCapacity[0] = font;
int displayCounter = 0;
int notDisplayCounter = 0;
for (int i = 0; i < 65536; i++) {
char c = (char) i;
if (font.canDisplay(c)) {
displayCounter++;
} else {
notDisplayCounter++;
}
}
fontCapacity[1] = new Integer(displayCounter);
fontCapacity[2] = new Integer(notDisplayCounter);
return fontCapacity;
}
private Font getSuitableFont(char c) {
for (int i = 0; i < allFonts.length; i++) {
if (allFonts[i].canDisplay(c)) {
return allFonts[i];
}
}
return null;
}
}[/code]