How to rendering fraction in Swing JComponents - java

Basically Swing JComponents are able to display numbers in fractions in this form 2 2/3. How can I paint fraction in the nicest form, for example 2⅔?
.
EDIT
.
as see I have only one way JTable inside JSpinner with one TableColumn and TableRow (that could simulated plain JtextField too), where TableRenderer could be some of JTextComponent formatted by using Html and on TableCellEdit event the TableEditor to swith to the plain JFormattedTextField,
is there another way, could it be possible with plain J(Formatted)TextField too ???

On reflection, Unicode fractions among the Latin-1 Supplement and Number Forms offer limited coverage, and fancy equations may be overkill. This example uses HTML in Swing Components.
Addendum: The approach shown lends itself fairly well to rendering mixed numbers. For editing, key bindings to + and / could be added for calculator-style input in a text component. I've used org.jscience.mathematics.number.Rational to model rational numbers, and this parser could be adapted to evaluating rational expressions.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** #see https://stackoverflow.com/questions/7448216 */
public class HTMLFractions extends JPanel {
private static int N = 8;
public HTMLFractions() {
this.setLayout(new GridLayout(N, N, N, N));
this.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
this.add(create(r + N, r + 1, c + 2));
}
}
}
private JLabel create(int w, int n, int d) {
StringBuilder sb = new StringBuilder();
sb.append("<html><body>");
sb.append(w);
sb.append("<sup>");
sb.append(n);
sb.append("</sup>");
sb.append("<font size=+1>/<font size=-1>");
sb.append("<sub>");
sb.append(d);
sb.append("</sub>");
sb.append("</html></body>");
JLabel label = new JLabel(sb.toString(), JLabel.CENTER);
label.setBorder(BorderFactory.createLineBorder(Color.lightGray));
return label;
}
private void display() {
JFrame f = new JFrame("HTMLFractions");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new HTMLFractions().display();
}
});
}
}

Use the Java2D API. The is an excellent book on it from O'Reilly.
1- Use the font you like.
2- Convert the Glyphs you need (e.g. "2" "/" and "3") into Java2D shapes.
3- Use the Java#d method to scales and place the shapes together
4- This part depends on the component. I think a lot of components take some kind of image instead of text. Convert your shapes into whatever fits into the components you w ant.
5- This should look really professional if you do a good job :)
Come on give me 50!!!
=============
Thanks so much for the points. Here is an example of how to do the first step. It'll show how to get an instance of enter code here Shape from a character in the font of your choice.
Once you have your Shape You can use Graphics2D to create the image you want (scale, compose, etc). All the swing components are different but all have a graphics context. Using the graphics content you can draw on any Swing Component. You can also make transparent layers and stick a transport JPanel over anything you want. If you just want to display a fraction on a label that's easy. If you had some sort of word processor in mind that's hard.
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
public class Utils {
public static Shape generateShapeFromText(Font font, char ch) {
return generateShapeFromText(font, String.valueOf(ch));
}
public static Shape generateShapeFromText(Font font, String string) {
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
try {
GlyphVector vect = font.createGlyphVector(g2.getFontRenderContext(), string);
Shape shape = vect.getOutline(0f, (float) -vect.getVisualBounds().getY());
return shape;
} finally {
g2.dispose();
}
}
}

You can use the approach based on this
http://java-sl.com/fraction_view.html
The only difference is positioning subviews for numerator and denominator.

Unicode has a set of characters that will let you produce fractions without having to do special formatting, e.g., ⁴⁄₉ or ⁵⁶⁄₁₀₀.
You could set up an array of superscript digits, and an array of subscript digits, and convert your numbers to strings of these digits, and then combine them with the fraction slash in between.
Advantages are that it's more general (you can use the code in other contexts), and the result will tend to look better than if you tried to reproduce it using HTML formatting. Of course, you need to have Unicode fonts on your system, but most systems do these days.
A possible implementation in code:
public String diagonalFraction(int numerator, int denominator) {
char numeratorDigits[] = new char[]{
'\u2070','\u00B9','\u00B2','\u00B3','\u2074',
'\u2075','\u2076','\u2077','\u2078','\u2079'};
char denominatorDigits[] = new char[]{
'\u2080','\u2081','\u2082','\u2083','\u2084',
'\u2085','\u2086','\u2087','\u2088','\u2089'};
char fractionSlash = '\u2044';
String numeratorStr = new String();
while(numerator > 0){
numeratorStr = numeratorDigits[numerator % 10] + numeratorStr;
numerator = numerator / 10;
}
String denominatorStr = new String();
while(denominator > 0){
denominatorStr = denominatorDigits[denominator % 10] + denominatorStr;
denominator = denominator / 10;
}
return numeratorStr + fractionSlash + denominatorStr;
}

You would have to find a font that prints fractions in what you're calling nicest form, then write a method to convert the character string of your fraction into the character code of the corresponding nicest form fraction.

Special fonts method:
The special fonts method might be a really good solution too.
You are going to need a good font editor.
Create ten numbers just for the top number of the fraction, a special slash or line symbol for the middle, and ten numbers just for bottom digits.
The only problem is that it's got to look good and that requires that the spacing of the top/slash/and button all close to together, actually overlapping horizontally. The good news is fonts support this, and a good font editor will. The swing text components probably don't. You need to write your own text component of find a component that already lets you fine position the fonts. This is the different between test editing/ word processing and text typography.
But I also have another idea :)
You could do fractions with a horizontal bar instead of a diagonal slash.
123
---
456
This way font need not overlap and can be laid out by the editor in the standard way. The trick is to have the above be three characters next to each other.
1 2 3
- - -
4 5 6
So that's one hundred different characters you need for all combinations.
The only problem with this (in addition to having to create 100 characters) is if you have and odd number of digits in the top and even in the bottom or vise verse it will look like this:
12
---
456

Related

Prevent JLabel with html from breaking line

Wondering if anyone knows how to disable line break when using html in JLabel.
Here is the code:
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.awt.GridLayout;
public class Main
{
private static final int[] TEXT =
{ 0x05D0, 0x05B2, 0x05DC,
0x05B5, 0x05D9, 0x05DB,
0x05B6, 0x05DD
};
public static void main(String[] args)
{
String text = "";
for(int cp : TEXT)
text += Character.toString(cp);
String html = "<html>" + text + "</html>";
JLabel label = new JLabel(html);
JLabel msg = new JLabel("The text should at least go out to here.");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,1));
panel.add(label);
panel.add(msg);
JOptionPane.showMessageDialog(null, panel);
}
}
The bidi text breaks into two lines. I am trying to write html to a JTree node so it will support multiple font families. I can't get it to work with a JLabel. I'm thinking I might need to paint it in a cell renderer. I was hoping to get the html to work. It would make things a lot easier.
Any suggestions?
=== Edit ===
When my display setting in Windows is at 125% it breaks the line; however, when I change my display setting in Windows to 100% it does not break the line. Running 1920 x 1080 display. Anyone have any ideas? Or, is anyone able to repeat the breaking of the line?
=== Edit ===
Interestingly when I pass -Dsun.java2d.uiScale= with 1.0 or 2.0 it works. When I use 3.0, 4.0, 1.25 or 1.5 or 0.8 it does not work.
Well, I submitted a bug report. I managed to find a workaround that seems to work for all Windows Display Scale's but it is quite a hacky workaround. But it will be sufficient until the bug is fixed.
Here it is:
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.GridLayout;
import java.awt.font.FontRenderContext;
public class Main
{
private static final String TEXT =
"\u05D0\u05B2\u05DC\u05B5\u05D9\u05DB\u05B6\u05DD";
public static void main(String[] args)
{
JLabel label = new JLabel();
Graphics2D g2 = (Graphics2D)new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getGraphics();
FontRenderContext frc = g2.getFontRenderContext();
String[] split = TEXT.split("");
double width = 0;
for(String chr : split)
width += label.getFont().getStringBounds(chr, frc).getWidth();
double scale = Toolkit.getDefaultToolkit().getScreenResolution()/96.0;
String html = "<html><p style=\"width:"+Math.ceil(width/scale)+"px;\">" + TEXT + "</p></html>";
label.setText(html);
JLabel msg = new JLabel("The text should at least go out to here.");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,1));
panel.add(label);
panel.add(msg);
JOptionPane.showMessageDialog(null, panel);
}
}
Note: If I don't get the individual character lengths then the width doesn't come out right in a JTree node. Also, for some reason when I use bidi text the resultant width of the nodes JLabel is about twice the width of the text. Any shorter and it does not display correctly. However, the width is correct with Non-Bidirectional text. Also, width: does not work with span tag, it only works with p tag

How do you make variables made inside a method available to all other methods in a class?

I'm a coding newb and want to learn some more java. I'm currently taking an introductory programming course in high school and am just trying to play around outside of class. This program I'm creating is supposed to print out a few instructions and questions in the console, to which I want to retrieve user input using a scanner and variable. The goal of the program is for the user to be able to create a 'drawing' based on pure instinct, then this drawing is displayed after the fact.
Here's my problem. I'm asking the user and storing the information in variables that are native to the main method, but I need to use this information in the paintComponent method.
I tried adding static in front of the variable such as:
static int emptyRectW1 = kboard.nextInt(); but this just shows the error "Illegal modifier for parametic emptyRectW1; only final is permitted."
I knew it was a long shot trying that out, but that's the best I've got.
I'm using Java Eclipse as my IDE.
Thanks for any help, looks like the only way to learn is to mess up and have somebody else point out my mistake! :)
Here's the code:
import java.util.Scanner;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BlindDrawing extends JPanel {
public static void main (String[] args) {
Scanner kboard = new Scanner(System.in);
System.out.println("Welcome to the Blind Drawing Game!");
System.out.println("In this game, you will be asked questions about how to construct an image using rectangles and ovals. You will be asked the shape's dimensions and position. The origin (0,0) is the top left corner.");
System.out.println("First you're making an empty rectangle, how wide do you want it to be?");
int emptyRectW1 = kboard.nextInt();
System.out.println("What about the height?");
int emptyRectH1 = kboard.nextInt();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0,0,emptyRectW1, emptyRectH1);
}
}
Update: In the comments an example was requested, so here's a simple one. This is just a simple demonstration of the ideas I talk about; it does not build on the above code. The reason is that, as others have noted, there are additional things you'd want to correct about the structure of that code. Rather than try to address them in detail, or give an example that encourages them, I'll just focus on the points I was making in my original answer:
public class SampleObject {
private int aValue;
protected void getVAlue() {
Scanner kboard = new Scanner(System.in);
System.out.println("Enter a value:");
aValue = kboard.nextInt();
}
protected void printValue() {
System.out.println("The value is " + aValue);
}
public void processValue() {
System.out.println("Welcome");
getValue();
printValue();
}
public static void main(String[] args) {
SampleObject sampleObject = new SampleObject();
sampleObject.processValue();
}
}
Some styles would have the main method in a separate "application class"; some frameworks have such a thing, wich might have responsibilities like handling outside messages requesting the app shut down, or whatver.
And generally as your applications get beyond simple exercises, you'll want to have more than just one class/object - each with distinct responsibilities that make up your application's functionality.
But for now, this should show how instance data woriks, and how to bootstrap a collection of objects rather than doing lots of processing in a static main method.
Good luck!
As a general answer to the question: variables defined inside a method are not available to other methods, and this is by design of the language. (Some advanced features twist this rule a little, but not in the way you want; and those things are a bit down the road from where you are anyway.)
To share state among methods, you add data members (sometimes called fields) to the class itself. Then values can be assigned in one method and read in another, or whatever, throughout the class.
However, as soon as you try to use that advice you're going to run into another problem, because main() is (and must be) static and your other method isn't (and probably shouldn't be). So you're going to do one of two things to fix that - the easy thing, or the right thing.
The easy thing would be to add static data members - making the data belong to the class rather than an instance of the object. The non-static methods could still see those. But this is leading you in the wrong direction.
The right thing is to do nothing more than bootstrap your application in the main method. What this means is, create object instances that can collaborate to carry out your program's function, and then set those objects in motion. Then all the actual work - like prompting for user input, etc. - should happen in (generally non-static) methods of those objects.
It's a very surface explanation, but really this isn't the place for an in-depth programming lesson. If your curiosity is getting ahead of the coursework, there certainly are good tutorials for OO programming and Java online (or at your local book store... though I may be dating myself with that suggestion).
Good luck.
The simple answer: pass the information obtained in the main method into the BlindDrawing object via either a method or a constructor's parameters.
But having said that you really don't want to mix a linear console type application with an event driven GUI app. Choose one or the other and stick with it. Here you can get the information you need via JOptionPanes if you need to get them before launching the main GUI application, and then again pass them into the main GUI application as described above -- via constructor parameters.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.*;
public class BlindDrawing extends JPanel {
private Rectangle rectangle;
public BlindDrawing(Rectangle rectangle) {
setPreferredSize(new Dimension(1000, 800));
this.rectangle = rectangle;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (rectangle != null) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
g2.draw(rectangle);
}
}
private static void createAndShowGui(Rectangle rect) {
BlindDrawing mainPanel = new BlindDrawing(rect);
JFrame frame = new JFrame("BlindDrawing");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
String message = "Enter 4 numbers for X, Y, Width, and Height, separated by a space";
String title = "Get Rectangle Coordinates";
int messageType = JOptionPane.PLAIN_MESSAGE;
String input = JOptionPane.showInputDialog(null, message, title, messageType);
String[] tokens = input.split("\\s+");
if (tokens.length == 4) {
int x = Integer.parseInt(tokens[0]);
int y = Integer.parseInt(tokens[1]);
int width = Integer.parseInt(tokens[2]);
int height = Integer.parseInt(tokens[3]);
Rectangle rect = new Rectangle(x, y, width, height);
SwingUtilities.invokeLater(() -> createAndShowGui(rect));
}
}
}
EDIT
You asked in comments:
What I don't understand are the ones towards the bottom that have tokens. I don't really understand what these tokens do, if you could clarify, that would be great!
The question for me is: how can we most easily allow the user to enter for ints to use in a Swing application, but to sub-divide this even further we can ask for solutions that are most easy for the coder and solutions that are most easy for the user. In general you will want to prefer going after the latter.
The easiest for the coder is to create a simple console application and have the user enter the numbers using String prompts and a Scanner object that has been initialized to the standard input or System.in. As I've mentioned, while this is easy for the coder, it does not work well for the user since console applications and GUI applications don't play nice together as one is structured in a linear fashion while the other is much more free-flowing and event driven. If you want to get data later on while the program runs, and you again have the user enter information through the console, you risk either freezing the Swing application, rendering it useless, or updating the Swing application inappropriately in a background thread.
My solution above is a compromise where we prompt the user for a single String by using a JOptionPane.showInputDialog(...). This will give the user a prompt, and allow him to enter a single String into a text field. Here I ask the user to enter four numbrers separated, each separated by a space, and I think that you understand this part, but one problem with it is, once you get that String, which I call input, how do you extract the four numbers out of it.
One way is to split the String into an array of Strings (which I call tokens) using String's split(...) method. A simple way to do this is like so:
String[] tokens = input.split(" ");
This will split the input String into an array of sub-strings by splitting on a single space. It doesn't work so well if the user accidentally uses more than one space between his numbers, or if he uses different "white-space" to separate the numbers. I instead used:
String[] tokens = input.split("\\s+");
This uses something called regular expressions or "regex" for short to split the String. \\s represents any white-space character, and the + means that we'll split on one or more white-space characters. So if the user puts 2 or 3 spaces between his numbers, this still will work.
Another possible way to split this String is to put it into a Scanner and then "scan" for ints. Here we don't Scan with the standard input, with System.in, but rather we scan the entered String, here input. For example:
// get our line of input same as we did before
String input = JOptionPane.showInputDialog(null, message, title, messageType);
// create a Scanner object that scans through the line
Scanner inputScanner = new Scanner(input);
// extract the four numbers from the line
int x = inputScanner.nextInt();
int y = inputScanner.nextInt();
int width = inputScanner.nextInt();
int height = inputScanner.nextInt();
// close the Scanner so we don't waste resources
inputScanner.close();
There are still problems with this since all these solutions fail if the user enters 2 or 3 numbers and not 4, or if the user enters non-numeric input, and there are other ways of checking for this and correcting, such as using a JSpinner or JComboBox that limits the user's selections to allowed numbers, or by using try/catch blocks to catch invalid input and then prompt the user for more correct input.
You can initialize them as instance variables so they can be used by various other methods, like so:
public class BlindDrawing extends JPanel {
private int emptyRectW1;
private int emptyRectH1;
public static void main (String[] args) {
new BlindDrawing().run();
}
private void run() {
Scanner kboard = new Scanner(System.in);
System.out.println("Welcome to the Blind Drawing Game!");
System.out.println("In this game, you will be asked questions about how to construct an image using rectangles and ovals. You will be asked the shape's dimensions and position. The origin (0,0) is the top left corner.");
System.out.println("First you're making an empty rectangle, how wide do you want it to be?");
emptyRectW1 = kboard.nextInt();
System.out.println("What about the height?");
emptyRectH1 = kboard.nextInt();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, emptyRectW1, emptyRectH1);
}
}
Actually, a variable declared inside a method is a local variable.
Please extend the scope of the the two variables just before your main method. See code below.
static int emptyRectW1, emptyRectH1;
public static void main (String[] args) {
Then manipulate the latter code to avoid duplicate variable declaration as shown below.
emptyRectW1 = kboard.nextInt();
System.out.println("What about the height?");
emptyRectH1 = kboard.nextInt();
I hope this helps.

Scaling a button's text automatically with the button in JavaFX

I made a grid of buttons in JavaFX.
When I resize the window with the grid inside, the buttons resize within the grid as well.
The problem is that the text on those buttons doesn't resize along with them: it stays the same size all the time, so when the buttons grow big, there's a lot of empty space on a button and then a tiny little text in the middle, which looks terrible.
I would rather like the text to automatically resize along with these buttons to fit the empty space, so that when the entire user interface gets bigger, the text on the buttons gets bigger as well.
How can I accomplish that?
I tried setting the -fx-font-size in the CSS stylesheet to percentage values, but it doesn't seem to work the same way as for websites: the text doesn't scale as a percentage of its container, but as a percentage of some predefined text size.
Edit
This is not a duplicate! Stop marking each question out there as duplicate! If it has been answered, I wouldn't have asked it in the first place!
From what I see, the first of those threads was about a situation where someone wanted to set the size/style of the text for newly-created buttons to account for the current size of their container etc. This is not what I need, because I want the buttons which has been already created as well to automatically resize their texts when these buttons resize inside their container in some way.
The other thread was about scaling the text along with the root container / window with a preset font size. This is also different from what I need, because I don't want the text to be scaled with the window, but with the sizes of the buttons themselves. And it has to be scaled in a certain way: to always fit the size of the button. You know: the text stays the same, but stretches so that it always fits the inside of the button (with a little padding, not a huge empty area around the text).
It is the button's size which is to determine the size of the text on it, not the window or container or something else, and it needs to be done automatically by the button itself (either the built-in one or a subclassed one), not manually by its encompassing container iterating over all these buttons and updating their text's sizes (which would be dumb way to do it).
This is, liked the linked questions, something of a hack: but consider scaling the text node inside the button instead of changing the font size. This seems to work ok:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
public class ScaledButtons extends Application {
#Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
root.setHgap(5);
root.setVgap(5);
for (int i = 1; i <= 9 ; i++) {
root.add(createScaledButton(Integer.toString(i)), (i-1) % 3, (i-1) / 3);
}
root.add(createScaledButton("#"), 0, 3);
root.add(createScaledButton("0"), 1, 3);
root.add(createScaledButton("*"), 2, 3);
primaryStage.setScene(new Scene(root, 250, 400));
primaryStage.show();
}
private Button createScaledButton(String text) {
Button button = new Button(text);
GridPane.setFillHeight(button, true);
GridPane.setFillWidth(button, true);
GridPane.setHgrow(button, Priority.ALWAYS);
GridPane.setVgrow(button, Priority.ALWAYS);
button.layoutBoundsProperty().addListener((obs, oldBounds, newBounds) ->
scaleButton(button));
button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
return button ;
}
private void scaleButton(Button button) {
double w = button.getWidth();
double h = button.getHeight();
double bw = button.prefWidth(-1);
double bh = button.prefHeight(-1);
if (w == 0 || h == 0 || bw == 0 || bh == 0) return ;
double hScale = w / bw ;
double vScale = h / bw ;
double scale = Math.min(hScale, vScale);
button.lookup(".text").setScaleX(scale);
button.lookup(".text").setScaleY(scale);
}
public static void main(String[] args) {
launch(args);
}
}
An alternate approach to get a similar effect could be to subclass com.sun.javafx.scene.control.skin.ButtonSkin and override the layoutLabelInArea(double x, double y, double w, double h, Pos alignment) method from the skin's parent (LabeledSkinBase). You can then explicitly assign the updated skin to your button (either via CSS or via Java API calls).
Doing so would requires the subclassing of com.sun APIs which could change without notice in subsequent JavaFX releases. Also layoutLabelInArea is reasonably complex in its operation so changing the layout logic could be a little tricky. Certainly, James's suggestion of applying a text rescaling operation based upon a listener to the layout bounds property is simpler in this particular case.
I'm not necessarily advocating this approach, just providing a route to something that you could create that would satisfy your goal of: "It is the button's size which is to determine the size of the text on it, not the window or container or something else, and it needs to be done automatically by the button itself".

how to print a glyph of supplementary characters in java onto my JTextField when i just click the button

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).

Sending information from one method into another method in a Java Applet

I have my code finished for the most part, but I'm stumped on figuring out this last bit so that it will be finished.
Here's what I'm trying to do:
I'm trying to make an applet that takes two floating numbers from the user via JOptionPanes, and gives the sum of those two numbers and the absolute value of the sum inside of a rectangle.
Like I said, I have the code finished, I'm just hung up on one part. I can't figure out how to get the user input into the panes because I have placed panes into the init method while the rectangle and the string for the output are in the paint method.
I tried having the panes and the rectangle both be in the paint method, but that caused the panes to prompt the user twice before giving output, and I don't want that. That's why I put the panes in the init method.
Is there any way to call the information from the init method and put it into the paint method?
Can anyone help me out?
Here is the code I have made for this applet:
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import java.text.DecimalFormat;
import java.awt.*;
public class MathApplet extends JApplet
{
public void init()
{
DecimalFormat fmt = new DecimalFormat ("0.##");
DecimalFormat fmt2 = new DecimalFormat ("0.###");
String intro, givenum1, givenum2;
float num1, num2, sum, absum;
intro = "Enter two floating point numbers, and their sum and the absolute
value of the sum will be calculated.";
JOptionPane.showMessageDialog(null, intro);
givenum1 = JOptionPane.showInputDialog(null, "Enter the 1st floating point
number now." );
num1 = Float.parseFloat(givenum1);
givenum2 = JOptionPane.showInputDialog(null, "Enter the second floating point
number now.");
num2 = Float.parseFloat(givenum2);
sum = num1+num2;
absum = Math.abs(sum);
}
public void paint (Graphics page)
{
page.drawRect (60, 80, 300, 140);
page.drawString("The absolute value of the numbers is.", 100, 100);
page.drawString ("The sum of the numbers is.", 100, 120);
}
}

Categories

Resources