When I do something like fileText.setText(path) in a JTextField, it works well unless the text is in Hebrew (or combines English and Hebrew). Then I get something like this:
I tried different fonts (even fonts that "Hebrew" is mentioned in them), but it didn't help. How do I fix it?
By the way, it is working properly with the ToolTipText (fileText.setToolTipText(path))
Here's my code:
// browse files or folders
public void browse(JTextField txtField) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedDir = fileChooser.getSelectedFile();
String path = selectedDir.getAbsolutePath();
if (txtField == srcText) {
srcText.setText(path);
srcText.setToolTipText(path);
}
else {
if (txtField == dstText) {
dstText.setText(path);
dstText.setToolTipText(path);
}
}}
}
Not an answer, since your code works well as it is. Please try to your environment.
For me it works flawlessly out of the box with the default font on Windows 7. Java JDK1.8.0_31
public class JTextFieldExample extends JFrame {
private static final long serialVersionUID = 1L;
public JTextFieldExample() {
super("TextField Test Demo");
final Container container = getContentPane();
final JTextField textField=new JTextField("hello \u05DD\u05D5\u05DC\u05E9 Hello \u05DD\u05D5\u05DC\u05E9");
// optionally set RTL
textField.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
container.add(textField);
setSize(300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(final String args[]) {
new JTextFieldExample();
}
}
Makes a window with a JTextField containing:
hello םולש Hello םולש
(I am sorry if I am using something strange or offensive in Hebrew. I just copied the unicode chars from another page, they claim it means "hello").
I've also tried you code in a test app and that is worked well, too.
Also Hebrew-only, English-Hebrew mixtures work well.
However you may prefer to set the RTL orientation to better match to Hebrew, and I guess in my example, the Hebrew letters are displayed in reverse order disregarding to the actual orientation.
Do the following:
check if the JTextField work well in Hebrew? If so, then there is something odd in the path returned by the file selector
check the path by priting it to the console. Locate chars which can cause problems, e.g. \-es, or broken unicode code points
dump the bytes of the string in hexa. This can reveal e.g. unicode byte ordering marks or broken unicode code points.
Related
I have here a simple, complete, self-contained, pure-Java program that displays a frame containing a button with a Unicode emoji character as its text. This program runs correctly and displays the emoji on Windows, but not on Mac OS (Catalina, AdoptOpenJDK15).
Here is the source code; filename is EmojiTest.java:
import java.awt.*;
import javax.swing.*;
public class EmojiTest {
public static void main(String[] args) {
// listFonts(); // Uncomment if you want to see all registered fonts.
JFrame frame = new JFrame();
frame.setTitle("Emoji Demo: " + System.getProperty("os.name"));
frame.setSize(400, 300);
JButton button = new JButton();
String emoji = "\ud83d\udc36"; // dog face
button.setText(emoji);
button.setFont(getFont(emoji));
JPanel holder = new JPanel(); // Let button be natural size
holder.add(button);
frame.getContentPane().add(holder);
frame.setVisible(true);
}
static Font getFont(String emoji) {
String os = System.getProperty("os.name");
String fontFamily = os.equals("Mac OS X") ? "Apple Color Emoji" : "Segoe UI Emoji";
Font font = new Font(fontFamily, Font.PLAIN, 20);
System.out.println("Font: " + font);
System.out.println("can display result: " + font.canDisplayUpTo(emoji));
return font;
}
static void listFonts() {
String fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getAvailableFontFamilyNames();
for (int i = 0; i < fonts.length; i++) {
System.out.println(fonts[i]);
}
}
}
A few things to observe here:
The getFont() helper method prints out whether the font thinks it can display the text. On MacOS, it always prints -1, meaning it thinks it can display the text.
All 279 fonts on my Apple system claim (via canDisplayUpTo) that they can display it, but they fail to display it. Yes, I tested all of them visually, and no, none worked.
As you can see from the picture, this program works correctly on Windows. So the code is "correct", in the sense that it should work on Macs.
I'm fairly convinced that this is a JDK bug. However, if you debug the EmojiTest program in IntelliJ, it actually shows you in the debug pane that the text is in fact the correct emoji:
So IntelliJ, a Java program running on Mac OS Catalina, is able to render the emoji correctly in its font—admittedly, not in a JButton. But I have also tried rendering emoji in JTextPanes and other Swing widgets on MacOS, to no avail.
This question has been asked several times over the past few years, often indirectly, but the answer is always "You need to make sure your font can display the emoji".
I think this program pretty clearly demonstrates that the font being able to display the emoji is not the issue. The Apple Color Emoji font can absolutely display emoji, including this one. It just doesn't seem to be able to do it in Java.
Here's my question: How can I modify this EmojiTest.java program to show the emoji on MacOS?
I have a simple program just need to set the character whose Unicode value larger the character data type (supplementary character) on JTextField when the button is click .Tell me i am really fed up and how i will do it .This problem have already taken my 4 days.
//importing the packages
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
//My own custom class
public class UnicodeTest implements ActionListener
{
JFrame jf;
JLabel jl;
JTextField jtf;
JButton jb;
UnicodeTest()
{
jf=new JFrame();// making a frame
jf.setLayout(null); //seting the layout null of this frame container
jl=new JLabel("enter text"); //making the label
jtf=new JTextField();// making a textfied onto which a character will be shown
jb=new JButton("enter");
//setting the bounds
jl.setBounds(50,50,100,50);
jtf.setBounds(50,120,400,100);
jb.setBounds(50, 230, 100, 100);
jf.add(jl);jf.add(jtf);jf.add(jb);
jf.setSize(400,400);
jf.setVisible(true); //making frame visible
jb.addActionListener(this); // registering the listener object
}
public void actionPerformed(ActionEvent e) // event generated on the button click
{ try{
int x=66560; //to print the character of this code point
jtf.setText(""+(char)x);// i have to set the textfiled with a code point character which is supplementary in this case
}
catch(Exception ee)// caughting the exception if arrived
{ ee.printStackTrace(); // it will trace the stack frame where exception arrive
}
}
// making the main method the starting point of our program
public static void main(String[] args)
{
//creating and showing this application's GUI.
new UnicodeTest();
}
}
Since you are not giving enough information on what's wrong, I can only guess that either or both:
You are not using a font that can display the character.
You are not giving the text field the correct string representation of the text.
Setting a font that can display the character
Not all fonts can display all characters. You have to find one (or more) that can and set the Swing component to use that font. The fonts available to you are system dependent, so what works for you might not work for others. You can bundle fonts when you deploy your application to ensure it works for everyone.
To find a font on your system that can display your character, I used
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font f : fonts) {
if (f.canDisplay(66560)) {
System.out.println(f);
textField.setFont(f.deriveFont(20f));
}
}
The output (for me) is a single font, so I allowed myself to set it in the loop:
java.awt.Font[family=Segoe UI Symbol,name=Segoe UI Symbol,style=plain,size=1]
as also noted in the comments to the question by Andrew Thompson.
Giving the text field the correct string representation
The text fields require UTF-16. Supplementary characters in UTF-16 are encoded in two code units (2 of these: \u12CD). Assuming you start from a codepoint, you can convert it to characters and then make a string from them:
int x = 66560;
char[] chars = Character.toChars(x); // chars [0] is \uD801 and chars[1] is \uDC00
textField.setText(new String(chars)); // The string is "\uD801\uDC00"
// or just
textField.setText(new String(Character.toChars(x)));
as notes by Andrew Thompson in the comments to this answer (previously I used a StringBuilder).
I'm trying to get locale in which user inputs text into JPasswordField.
For this I'm doing the next:
final JPasswordField passwdField = new JpasswordField();
final InputContext it = InputContext.getInstance();
final JTextArea localeLng = new JTextArea();
...
...(some code)
...
passwdField.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
localeLng.setText(it.getLocale().getLanguage().toUpperCase());
}
});
I have two keyboard layouts En and Ru. When I switch between them it doesn't affect on the localeLng value. This perhaps on Ubuntu with JRE 7up7.
But this perfectly works on Windows 7.
So, in what may resides my problem at all?
My temporal rough solution :)
public void keyReleased(KeyEvent e) {
int key = (int)e.getKeyChar();
if(key>122){
localeLng.setText("!");
localeLng.setBackground(Color.RED);
} else {
localeLng.setText("En");
localeLng.setBackground(Color.BLUE);
}
}
It's probably a good thing to remind that with Java you get a well defined set of methods and classes but different implementations, there are many JVM out there and many OS that offers support for Java, probably each one with its own implementation.
That said, this link will answer your question.
I also suggest to let the user decide what is the right locale, getting the right locale programmatically can be really tricky, especially under Linux.
I'm writing a Java app that needs to run on a device with a very high screen resolution. The only UI component that I need to display is a JFileChooser.
Since the screen resolution so high, the FileChooser appears too small. Is there a simple command I can use to make it bigger? Ideally, I'd like to keep the proportions of the components the same, so that the icons grow just as much as the text.
Also, it's important that any changes modify only my application. A global approach to changing the size of the graphics, like using a lower resolution, or changing a system-wide font size, isn't an option for me.
Any ideas?
This class works fine, both resizing JFileChooser window and fonts.
public class JFileChooserArqs {
private Font font = new Font("monospaced",Font.BOLD,16);
private String fileName;
public JFileChooserArqs(String title)
{
fileName = null;
JFileChooser fc = new JFileChooser(".");
fc.setPreferredSize(new Dimension(800,600));
fc.setDialogTitle(title);
setFileChooserFont(fc.getComponents());
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
fileName = fc.getSelectedFile().getAbsolutePath();
}
}
private void setFileChooserFont(Component[] comp)
{
for(int x = 0; x < comp.length; x++)
{
if(comp[x] instanceof Container) setFileChooserFont(((Container)comp[x]).getComponents());
try{comp[x].setFont(font);}
catch(Exception e){}//do nothing
}
}
public String obtemNomeArquivo() {
return fileName;
}
}
I know the answer. Just use chooser.setPreferredSize(new Dimension(int width,int height)); method where chooser is your JFileChooser .
Example:
public class MyFrame extends JFrame(){
JFileChooser chooser = new JFileChooser();
chooser.setPreferredSize(new Dimension(800,600));
//Here show your dialog and do the rest
}
You need to choose suitable layouts to design the user interface. Have a look at CodeRanch thread.
I was going to suggest adding the JFileChooser to a container having a suitable layout, as #AVD suggests. For example, ImageDisplay adds the chooser to BorderLayout.WEST where it's free to grow vertically while adopting the UI delegate's preferred width. Before you abandon that approach, verify that you are not inadvertently defeating that design feature.
If you really need control over the display characteristics of the chooser's subcomponents, you may want to look at these variations of FileBrowser.
G'day all,
I have an application which needs to display an ASCII file of 15 lines in a Swing component that cannot be edited by the user.
Below is my code which reads the ASCII file byte by byte. My thanks to the helpful commenters who explained that a JTextArea.setEditable(false) would be appropriate in Swing.
However, my code merely displays a string of numbers, when I personally made the ASCII file to be something quite different. Does anyone know what I am doing wrong and how to get the ASCII characters themselves to display?
import java.io.*;
import javax.swing.*;
public class LoadMap extends JFrame {
public LoadMap() throws IOException {
FileInputStream fIn = new FileInputStream("map.srn");
BufferedReader rd = new BufferedReader(new InputStreamReader(fIn, "US-ASCII"));
String map = "";
JTextArea mapArea = new JTextArea(15, 50);
try {
int c;
while ((c = rd.read()) != -1) {
map= map + c;
}
} finally {
if (rd != null) {
rd.close();
}
}
mapArea.setText(map);
mapArea.setEditable(false);
add(mapArea);
pack();
setVisible(true);
}
}
You could construct a String inside the loop, and then put the string into JLabel when you've finished.
This makes me feel like Captain Obvious, but still: just load the entire text first, and then build the label using the desired text. Or, as other posters rightly suggest, use a JTextArea since its more well-suited for multiline content.
Use a JTextArea and call
setEditable(false);
to stop the user being able to edit the data
I've just read your code through and realise that's not a comprehensive enough answer. You can't do "+" on a label. What you need to do is read the text in first and store it somewhere, then call
setText(yourTextAsString);
on your text component on screen (for which I'd still use the JTextArea), and you need to add the text area to the frame, so your code would look something like:
public LoadMap() {
String data = // read your data
JTextArea textArea = new JTextArea();
textArea.setText(data);
textArea.setEditable(false);
setLayout(new GridLayout());
add(textArea);
pack();
setVisible(true);
}
I would suggest reading the Swing tutorial to get some more info on using Swing components
A JLabel will not display line breaks (unless you use HTML). So as the others wrote, use a text area.
However, there's another hidden problem with your code: you don't specify the file's encoding, which means the file contents may be garbled if it contains non-ASCII characters and its encoding does not match Java's platform default. To fix this, do not use FileReader. Instead, use a FileInputStream and wrap it in an InputStreamReader, specifying the encoding in its constructor.
Use a JTextArea and call setEditable(false).
https://docs.oracle.com/javase/1.5.0/docs/api/javax/swing/text/JTextComponent.html#setEditable(boolean)
Here:
String map = "";
int c;
while ((c = rd.read()) != -1) {
map= map + c;
}
What you're doing it appending int's to the string.
You should cast them to char instead.
int c;
while ((c = rd.read()) != -1) {
map= map + ( char ) c;
}
You can see much better patterns in these questions.
How do I create a Java string from the contents of a file?
https://stackoverflow.com/questions/181634/simplest-efficient-ways-to-read-binary-and-ascii-files-to-string-or-similar-in-v/324792#324792 ( see java part )
You could use a JTextArea and set it to read only:
jtextarea.setEditable(false);