Avatar billede fredand Forsker
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;
    }

}
Avatar billede arne_v Ekspert
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);
            }
        });
    }
}
Avatar billede arne_v Ekspert
23. december 2014 - 04:14 #2
Yes - it is very slow!
Avatar billede fredand Forsker
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]
Avatar billede arne_v Ekspert
24. december 2014 - 01:57 #4
svar
Avatar billede fredand Forsker
06. marts 2015 - 06:56 #5
Thanks amigo
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester