I am able to display Japanese characters everywhere except for the title bar of the main window (JFrame) in Java. Is there a way to change the font of this title bar so it can display japanese characters? Thanks
I am using Windows XP. If this matters I am using the Java Substance look and feel too.
A window's title bar is managed by the system window manager, not by Swing. You don't say what OS/GUI you're using.
For Windows XP, open the Display control panel, select the "Appearance" tab, and click the "Advanced" button; you can change the title font there (although the fonts installed on your system may not have the glyphs you need).
Here's some code that checks whether the system default font supports the glyph that you want (I have no idea what the character is; it's a nice-looking glyph from the Katakana set):
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class GlyphCheck
{
public static void main(String[] argv) throws Exception {
final String title = "Testing: \u30CD";
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JLabel label = new JLabel(title);
label.setSize(200, 100);
frame.setContentPane(label);
frame.pack();
frame.setVisible(true);
}
});
}
}
JFrame.setDefaultLookAndFeelDecorated(true);
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
UIManager.put( "InternalFrame.titleFont", Resources.jaDefault.deriveFont(16.0f) );
Try it ;)
In order to override the font of the Frame you need to tell the look and feel to take care of its appearance. This may or may not be desirable, but you'll be at the mercy of the system otherwise. Some look and feels have quite good window decorations, others not so. Substance's are okay. Tell the UIManager what font to use also.
// Do this before you display any JFrame.
UIManager.put( "Frame.font", new Font( "Japanese", 12, Font.PLAIN ) );
JFrame.setDefaultLookAndFeelDecorated( true );
JFrame frame = new JFrame( title );
This approach (should it work - not tested it sorry!) will mean you'll be able to distribute your program without telling users that they need to change their Windows settings, as per the other answer.
I'm not familiar with Java Substance, but I experienced this when working on a webapp. Basically the Japanese, Chinese and Korean characters would show in the content in the page, but not in the browser title bar.
This is due to the fact that the windowing system controls this title bar, not the browser. Based on kdgregory's comment, it sounds like this is a similar situation to yours.
For the windowing system to understand the characters and not show the unsupported 'box' you have to ensure the proper character sets are installed. For Windows XP, the following steps resolved the problem with the browser title bar:
On the Windows Start menu, open the Control Panel.
Click the Regional and Language Options icon, and then click the Languages tab.
In the Supplemental languages support box, check the box for Install files for East Asian languages.
Click Apply and OK.
Related
I'm attempting to use the UIManager in java to make all my pop up GUIs and error GUIs use the same colors. The issue is I can't seem to change the button color when using the windows style, as well I can't manage to change the GUIs title bar.
Code: Its rather simple, I'm calling UIManager.getLookAndFeelDefaults().put("Button.background", buttonColor) anda few other UI changes. Nothing major...
UIManager.getLookAndFeelDefaults().put("Button.background", buttonColor)
For the color of the buttons from JOptionPane dialogs I don't understand why it doesn't work. It should. Maybe a side effect. We don't see all your code.
Try this simple code, you should see only green buttons.
package swing.uimanager;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
public class JFrameWithUIManger extends JFrame {
public static void main(String[] args) {
new JFrameWithUIManger();
}
public JFrameWithUIManger() {
final UIDefaults lookAndFeelDefaults = UIManager.getLookAndFeelDefaults();
lookAndFeelDefaults.put("Button.background", Color.GREEN);
add(new JButton("A button"));
pack();
setVisible(true);
JOptionPane.showMessageDialog(this, "hello I am a message dialog");
JOptionPane.showConfirmDialog(this, "hello I am a question dialog", "do you like me ?", JOptionPane.YES_NO_OPTION);
}
}
For the white background in the title, you have a color (white), so it seems to work. Maybe, a problem in a key-value.
Post it please if you want we understand better.
Edit
After seeing you code, I understood your problem. It's the look and feel used.
You don't use the default look and feel (metal).
Probably, you don't know but all the look and feels in Swing don't born equals.
In deed, some options and mix-options are supported by some look and feels but are not supported by other look and feels.
If you use the default look and feel, you should have less compatibility problem.
The best way to know if it correctly supported is to report to some official docs but it's true that a lot of information about it is dry, with errors, and not detailed
In the link you posted in your comment : http://nadeausoftware.com/articles/2008/11/all_ui_defaults_names_common_java_look_and_feels_windows_mac_os_x_and_linux#Button, the keys displayed in the tables don't mean that values are present or modifiable but that only the keys are present in the LAF.
Each LAF is responsible to take into consideration or not to the key and the possibility to change values associated to the keys.
I tried with the Windows LAF to set only the background color button, it doesn't work either. So, it doesn't seem to be a side effect but it looks like more a missing of support on this feature for the Windows LAF.
Anyway, you can interest to the Nimbus if you want an official, nice and more recent and more flexible look and feel than the classic metal look and feel.
Nimbus document
It's available since the Java SE 6 Update 10.
I agree with you, Metal is ugly. But why don't use nimbus instead of the windows LAF ? It's great. I tried your code which modifies some values of lAF with Nimbus, it seems working nicely. Maybe, you could have some minor modifications to adjust it but the basis should be nice.
If you are using JOptionPane,
You an change the title using this format to use your own title.
JOptionPane.showMessageDialog(null, "This is the message", "This is the title", JOptionPane.YES_NO_OPTION);
To set back ground color of dialog-
UIManager UI=new UIManager();
UI.put("OptionPane.background", Color.white);
UI.put("Panel.background", Color.white);
JOptionPane.showMessageDialog(null,"Text","SetColor",JOptionPane.YES_NO_OPTION);
For changing buttons in dialog or everything else, create your own JDialog and set the button characteristics which you want.
I found that when I show a JDialog or a new JFrame in my Java swing application will toggle my Chinese Input Method from half-byte mode to full-byte mode in Windows 7.
Why does calling the dialog or frame setVisible(true) method toggle my IME setting?
Does anyone knows what's wrong with the code, or it's a bug of Java?
Procedure to reproduce the problem:
run the application.
change your Language to one of Chinese Input methods eg. Chinese (Traditional) - Quick
click the button in the program
My language setting
I have found a similar question Automatic toggling of character width by Windows 7 input methods in Java
and after adding the default locale, it's still not working
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Locale;
public class MainWindow {
private JFrame frame;
private Locale l;
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
l = new Locale("zh", "zh_TW");
frame = new JFrame();
frame.setLocale(l);
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JDialog d = new JDialog(frame, "Run", true);
d.getContentPane().add(new JLabel("dsad"));
d.setMinimumSize(new Dimension(150, 100));
d.setLocationRelativeTo(null);
d.setLocale(l);
d.setVisible(true);
}
});
frame.getContentPane().add(btnNewButton, BorderLayout.CENTER);
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
According to the Oracle documentation, it seems as though this is behaving as I would expect, from how I understood the question:
The default locale of your application is determined in three ways. First, unless you have explicitly changed the default, the Locale.getDefault() method returns the locale that was initially determined by the Java Virtual Machine (JVM) when it first loaded. That is, the JVM determines the default locale from the host environment. The host environment's locale is determined by the host operating system and the user preferences established on that system.
In your question, the default was changed in Windows after the application was started, which means the JVM locale was already set. The locale for a specific frame was set, but the creation of a new frame sets the locale based on the default locale (which happens for both JDialog and JFrame):
protected void dialogInit() {
enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
setLocale( JComponent.getDefaultLocale() );
setRootPane(createRootPane());
setRootPaneCheckingEnabled(true);
if (JDialog.isDefaultLookAndFeelDecorated()) {
boolean supportsWindowDecorations =
UIManager.getLookAndFeel().getSupportsWindowDecorations();
if (supportsWindowDecorations) {
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
}
}
sun.awt.SunToolkit.checkAndSetPolicy(this, true);
}
Since you are setting the default locale in Windows, one would think that JComponent.getDefaultLocale() would return the Windows locale. getDefaultLocale() itself returns the locale of the current application context (the VM locale). Calling the below method will set the locale for the current context:
javax.swing.JComponent.setDefaultLocale(locale);
That sets the default locale for the VM (it actually calls through to
SwingUtilities.appContextPut(defaultLocale, l);
which makes it slightly more apparent what is happening).
If setting the defaultLocale fixes the problem, I imagine that somewhere else in the call chain the defaultLocale is getting called in a manner that causes Windows to change the setting.
If that doesn't give you the expected functionality, the only other property I can think to suggest that you look into is the InputContext class:
Provides methods to control text input facilities such as input methods and keyboard layouts. Two methods handle both input methods and keyboard layouts: selectInputMethod lets a client component select an input method or keyboard layout by locale, getLocale lets a client component obtain the locale of the current input method or keyboard layout.
I think it can be related to the fact that Windows 7 remembers the keyboard/language set for each running application:
I open my browser (in this case Chrome). I can see in my taskbar my keyboard set is ES (Spanish).
Then I open any other application. Nothing changes.
I set the focus in the browser again.
I press Alt+Shift, which is a shortcut to change the keyboard set. Now I can see is EN (English)
I click on the other app's window (or I use Alt+TAB). My keyboard set changes to ES
Every time I come back to the browser the keyboard set changes to EN, keeping the ES for rest of applications.
This works also for JVM applications, for example Eclipse, so I think it is not a JVM Locale issue.
First, there is a bug in the OP's code. Let me just type what is correct:
l = new Locale("zh", "TW");
And what OP meant is Half-Width/Full-Width (not half byte/full byte). In a full-width mode, an English letter will use more than one byte, such as A instead of A. This can be switched using Shift-Space.
Introduction to IME
In Region and Language, you can select a language, plus many keyboards. Simplified Chinese language for example, has least three commonly used keyboard:
US keyboard allows a user to type English, no way to type Chinese
Microsoft Pinyin keyboard allows a user to type the spelling and choose the correct character
ShuangPin allows user to type the spelling with less key strokes
There are more keyboards in Window 7 to be added just for Simplified Chinese.
Is that complicated enough? I have more to tell you: under one of the keyboard such as Microsoft Pinyin, there are modes, to allow you to select a Unicode symbol or a ASCII symbol for comma, period, and other punctuations, while you are typing Chinese. Yes, I can first type Chinese words with 。,、 for a while, then I can switch the mode and from then I can type Chinese with .,\
What? I am typing English in Chinese IME? Yes, besides the US Keyboard in Chinese IME, the Microsoft Pinyin keyboard also has mode to just type English. So if I want to type English, I can use US English language
, or Chinese language US Keyboard
, or Chinese language Microsoft Pinyin Keyboard with English mode
.
My Answer
What OP explicitly wants is to switch the keyboard, or even the mode under one keyboard, instead of switching the language. The Locale can be set in a lot of ways in Java to change the language, but not the Keyboard, no the modes. What if I want my Java Swing application to switch to the mode with Chinese ShuangPin keyboard, for Chinese input but with English punctuation?
Correct me if I am wrong but there is NO way for Java to select a native keyboard for a certain IME, or a mode. Here is an article about IME development in Windows and even Mac. I hope that can explain a lot
http://blog.gatunka.com/2009/09/20/ime-basics-for-developers/
But if the OP just wants to the user to type English for a password field, then he has a lot of solutions. But this is not what he said.
I did a simple test:
I opened IE, selected a tab, and at the address bar, set Chinese IME to be half width. Then click another tab, the IME change to full width automatically.
So I don't think it had anything to do with Java. It's a Windows/IME behavior.
It looks like the OS is controlling the whole JFrame title bar.
I tried using:
UIManager.setLookAndFeel()
To change the Look and Feel, but it doesn't seem to affect the
title bar.
On my Windows machine the default is left aligned, but on my Linux
machine it's centered, and somehow, I'd like to try to always show
the title text left aligned.
I saw one example where they basically built every element
of the title bar from scratch, and I'd rather not go there.
Is there any other way to do it?
Thanks!
If the L&F supports window decorations, you can use setWindowDecorationStyle(). A complete example is cited here in UIManager Defaults.
I like the convenience of a JOptionPane, but don't like the fact that it doesn't wrap text. So I decided to implement the answer from this question as follows:
public static void main(String[] args)
{
String text = "one two three four five six seven eight nine ten ";
text = text + text + text + text + text
JTextArea textArea = new JTextArea(text);
textArea.setColumns(30);
textArea.setLineWrap( true );
textArea.setWrapStyleWord( true );
textArea.append(text);
textArea.setSize(textArea.getPreferredSize().width, 1); //Explanation for this line in the comments of the linked thread
JOptionPane.showMessageDialog(
null, textArea, "Not Truncated!", JOptionPane.WARNING_MESSAGE);
}
This works just fine on Mac OS X:
But does not work on Windows 8 because the window does not resize as the JTextArea increases in height with more multi-lines, thus pushing the buttons out of the way:
Is there something I'm doing wrong? Does Java Swing on the two platforms behave differently? How can I fix this problem?
I discovered that the problem isn't actually the JTextArea, but the fact that I had set the default look and feel for Windows 8 using the following command elsewhere in the program
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Removing that line and defaulting to the Metal Look and Feel (as was the case in the snippet I posted at top) makes everything look right. It hadn't even occurred to me that it might be the issue until I realized that the dialog boxes from the main method above didn't look the same as it did in my screenshot.
A friend of mine using Windows 7 tried the program with that line of code included and the same thing happened. So it appears that this is a bug in Java with at least Windows 7 and Windows 8 (running Java 7u10 for me, either 6 or 7 for her).
Per the alternatives provided, I've since switched over to using a JLabel with CSS for the moment because it's quick and dirty for my plain text purposes (and I KNOW it will work cross-platform), but I may migrate to JEditorPanes in the future.
I have a problem with JTextField.requestFocus() behavior that appears to be different on Mac OS X.
Here is my situation: I have a dialog with a JList and a JTextField. The user is supposed to write a boolean expression in the text field, and the list contains the names of all the variables that might be entered in the expression. Because the user is expected to continue entering the expression after clicking on a variable from the list, the program helpfully calls JTextField.requestFocus(). This way you can e.g click "pvalue" from the list and then type " < 0.05" without the need to click on the textfield in between.
This all works fine on my development machine (Linux), but I got a bug report from a Mac user that clicking on the list actually selects all text in the text field, making it easy to accidentally overwrite what was entered before.
I suspected this is a problem with the Mac look-and-feel, after some searching it seems that indeed there is a "Quaqua.TextComponent.autoSelect" property for the mac look-and-feel that seems to be related to this problem: http://www.randelshofer.ch/quaqua/guide/jtextcomponent.html
My general question is:
Can you suggest a workaround for this problem?
In case that is too broad, an answer to these subquestions would already be a big help:
A possible solution could be to change the property "Quaqua.TextComponent.autoSelect". How do I do that?
I'm not even sure what "Quaqua" is. It looks like it is a customized look and feel. What is the default look and feel for Mac OS X? Does it have a property similar to Quaqua.TextComponent.autoSelect?
Is there a possibility to tweak look and feel for a single component instance only? If so, how?
Is it possible to set the Mac look and feel on my Linux development machine so that I can actually confirm this bug (all the above is really based on hunches and suspicions)? If so, how?
Seems this is a bug of Mac OS. JTextFields select their contents when they gain focus though keyboard tab cycling. If the insertion point is in the middle of the text, the insertion point will remain and the entire text will not be selected.
As a workaround you can override this behavior with the following, it works fine for me:
textfield.setCaret(new DefaultCaret()).
More details you can refer to this and this.
To modify the default behaviour, you can set the system property to false before initializing the UI components: System.setProperty("Quaqua.TextComponent.autoSelect", "false"); To modify a single component, you can use JTextField#putClientProperty("Quaqua.TextComponent.autoSelect", Boolean.FALSE);.
You can find other MacOS L&F specific properties here:
Quaqua Look & Feel - User Guide
A workaround might be (and I haven't tested this) to make the JList that inserts the variable names unfocusable. That way the focus will remain in the text field when you click on an item in the list. I'd recommend to use setRequestEnabled(false) on the JList, so that they are still focusable if you tab to them, but clicking them with the mouse will not focus them.
Sorry to add to an old question, but I just came across this problem and used the following code, which seems a little more complete than the previous example:
// JTextField linkedText
final int
startBefore = linkedText.getSelectionStart(),
endBefore = linkedText.getSelectionEnd();
linkedText.requestFocus(); // this was the original code line!
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
linkedText.setSelectionStart(startBefore);
linkedText.setSelectionEnd(endBefore);
}
});
This appears to protect the current cursor position or selection. (Note: This code must already run in the event dispatch thread, but you need invokeLater anyway or it doesn't work.)
I have an 'is Mac' function, so I did this inside a test for that, but it probably doesn't do any harm to do it on all platforms.
I noticed when looking through the JavaDocs that requestFocus() "is discouraged because its behavior is platform dependent." You should use requestFocusInWindow() instead and see if the same problem occurs with it.
requestFocusInWindow is part of the Focus subsystem, introduced in Java 1.4.
On a side note, the default Apple Look and Feel has at least one property in the apple.laf namespace: apple.laf.useScreenMenuBar
Edit: According to Sun, the Macintosh look and feel is only available on Macs.
While using requestFocusInWindow() is indeed encouraged over requestFocus(), it still produces the same problematic behavior on Macs (e.g., highlighting of full text field).
One workaround I got to work was to explicitly set the cursor position after requesting focus:
JTextField.requestFocusInWindow();
JTextField.setCaretPosition(JTextField.getDocument().getLength() - 1);
Note the "-1" is necessary, otherwise it will continue to highlight the entire field.
I'm curious to know if this solution is platform independent. Does this screw up the desired Linux or Windows behavior?
Mac will select the contents of the text field when the field gains focus. You can restore the state of the text field if you listen for the focus change event.
// JTextField linkedText
// Cache the state of the JTextField prior to requesting focus
final int
startBefore = linkedText.getSelectionStart(),
endBefore = linkedText.getSelectionEnd();
linkedText.requestFocus(); // this was the original code line!
// Use a focus listener to listen for the focus change and then
// reset the selected text to protect the cursor position
linkedText.addFocusListener ( new FocusListener()
{
public void focusGained( FocusEvent event ) {
linkedText.setSelectionStart( startBefore );
linkedText.setSelectionEnd( endBefore );
}
public void focusLost( FocusEvent event ) {
// do nothing
}
} );
Thank you for sharing your ideas. I had the same problem on my java application where on my windows system there wasn't a problem, but on my Mac OS X Yosemite I couldn't change the input. The focus wouldn't stay on the JTextField. Thanks to this thread I was able to fix my problem.
If you change the look and feel of the buttons and input boxes you maintain the focus and you can type again. The reset of the frame stays in the standard Mac OS look.
This is my code that I use in my java main methode. If you want to fix the problem past the try-catch code in your main methode.
public class Venster extends JFrame {
public static void main(String[] args) {
//Change L&F for mac
//Mac JTextField Bug Fix
try {
// Set cross-platform Java L&F (also called "Metal")
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException e) {
System.out.println("L&F not supported" + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("Fout: " + e.getMessage());
} catch (InstantiationException e) {
System.out.println("Fout: " + e.getMessage());
} catch (IllegalAccessException e) {
System.out.println("Fout: " + e.getMessage());
}
//The app
JFrame frame = new JFrame();
frame.setSize(1000, 520);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("10 More Bullets by Frank Peters");
frame.setContentPane(new SpeelVeld());
frame.setVisible(true);
frame.setLocationRelativeTo(null); //start app in center
}
}
Soure:
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html