I'm new here (I've read a lot, nut never posted before).
I'm encountering a weird problem on a JFormattedTextField. I'm trying to limit the input to numbers ranging from 9999.9 to -9999.9, but I can't seem to find a working solution. I tried using a DecimalFormat and a NumberFormatter, but it doesn't work as expected. I looked all over the net, but I can't seem to find an explanation of what I'm seeing (maybe I'm not searching for the right thing?).
Here is a small code that shows the problem:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.text.*;
public class testwindow extends JPanel
{
private JFormattedTextField field1;
private JFormattedTextField field2;
public testwindow()
{
try
{
//format text input fields (only numbers, dots and minus; overwrite; don't allow invalid chars)
DecimalFormat decimalFormat = new DecimalFormat("#0.0;-#0.0");
decimalFormat.setNegativePrefix("-");
decimalFormat.setMinimumIntegerDigits(1);
decimalFormat.setMaximumIntegerDigits(4);
decimalFormat.setMinimumFractionDigits(1);
decimalFormat.setMaximumFractionDigits(1);
NumberFormatter realFormatter = new NumberFormatter(decimalFormat);
realFormatter.setOverwriteMode(true);
realFormatter.setAllowsInvalid(false);
field1 = new JFormattedTextField(realFormatter);
field1.setValue(0F);
field2 = new JFormattedTextField(decimalFormat);
field2.setValue(0F);
setPreferredSize (new Dimension (215, 60));
setLayout(new GridLayout(2,1));
add (field1);
add (field2);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void main (String[] args)
{
JFrame frame = new JFrame ("MyPanel");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add (new testwindow());
frame.pack();
frame.setVisible (true);
}
}
Basically, I type 123456, and I'd expect the result to be 1234.5.
However:
field1, with NumberFormatter applied, shows 4050.6 immediately
field2 shows 1234560.0 while typing, and changes to 4560.0 after focus is moved
Also, when pressing minus on field1, the sign changes correctly between positive and negative. In field2, unless the minus is written as first character, it disappears.
Last but not least, typing 9 as last char on field1 multiple times just causes the number to increase of 0.1 each time, making all the behavior really puzzling.
I like much more the field1 behavior regarding the number of digits enforcement, but I wonder whether there is a correct/better way to obtain what I need, that is (as example) "1234.5" and the number not increasing by typing anything else as last char?
Related
This question already has answers here:
Java - checking if parseInt throws exception
(8 answers)
Closed 1 year ago.
So I tried to look a bit in forums and StackOverflow but nothing worked for me I need when enter is pressed to stop my code this is my code `
JFrame f;
JTextField I;
// JButton
JToggleButton b;
// label to display text
JLabel l;
f = new JFrame("AutoClicker");
i = new JTextField("100");
// create a label to display text
l = new JLabel("clicks/seconds");
// create a new buttons
b = new JToggleButton("Start");
// create a panel to add buttons
JPanel p = new JPanel();
// add buttons and textfield to panel
p.add(b);
p.add(i);
p.add(l);
// setbackground of panel
p.setBackground(Color.red);
// add panel to frame
f.add(p);
// set the size of frame
f.setSize(280, 80);
f.setVisible(true);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int jml = Integer.parseInt(i.getText());
if(jml < 50)
{
jml = 50;
}
AutoClicker(jml);
}
});
}
static void AutoClicker(int jml)
{
while(true)
{
try{
Robot r = new Robot();
int button = InputEvent.BUTTON1_DOWN_MASK;
r.mousePress(button);
Thread.sleep(jml);
r.mouseRelease(button);
Thread.sleep(jml);
}
catch(Exception e){
e.printStackTrace();
System.out.println("not good");
}
}
}
}`
I tried to add a KeyListener but it did not work.
I don't understand why it doesn't work so if you can just help me know why it doesn't work it would be much apreciated.
KeyListener isn't going to solve the problem of the fact that you are simply not handling the potential of Integer.parseInt to throw an exception - I mean, how can it convert "" or "This is not a number" to an int. In those cases it throws an exception
The JavaDocs clearly state
Throws:NumberFormatException - if the string does not contain a
parsable integer.
Go back and have a look at the original error you were getting from your previous question on this exact topic
java.lang.NumberFormatException: For input string: "Enter"
It's telling you exactly what the problem is - the text "Enter" can not be converted to an int value.
YOU have to handle this possibility. No offence, but this is honestly basic Java 101. See Catching and Handling Exceptions
Another option which "might" help is to use a formatted text field
You also don't seem to have a firm grip on the concept of what a "event driven environment" is or what the potential risk of what doing something like while (true) will do if executed within the context of the Event Dispatching Thread. This makes me think you've got yourself in over all head.
You're going to want to learn about Concurrency in Swing as AutoClicker should never be called within the context of the Event Dispatching Thread, which is going to lead you another area of complexity, concurrency and all the joys that brings.
Updated
Wow, you changed the title. Maybe a better description of the problem you're trying to solve would have a gotten a better answer. In short, you can't, not natively in Java anyway. The only way you can detect keyboard input out side of the app is using native integration, JNA/JNI. Plenty of examples about, for example
I have this applet that will add 2 numbers together and display their sum in a third text box.
https://pastebin.com/4ga1brD1
I want the text boxes to be arranged horizontally but more importantly I need the third text box to be uneditable.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Question extends Applet implements ActionListener
{
TextField firstNum, secondNum, resultNum;
public Question()
{
setLayout(new GridLayout(3, 2, 10, 15));
setBackground(Color.cyan);
firstNum = new TextField(15);
secondNum = new TextField(15);
resultNum = new TextField(15);
secondNum.addActionListener(this);
add(new Label("Enter First Number"));
add(firstNum);
add(new Label("Enter Second Number"));
add(secondNum);
add(new Label("S U M"));
add(resultNum);
}
public void actionPerformed(ActionEvent e)
{
String str1 = firstNum.getText();
double fn = Double.parseDouble(str1);
double sn = Double.parseDouble(secondNum.getText());
resultNum.setText("Sum is " + (fn+sn));
}
}
To arrange your TextField components horizontally, don't add them directly to the Applet. Instead, create a Panel, give it a FlowLayout and add your TextField components to the Panel. Then you can add the Panel directly to your Applet. Make sure your Applet is wide enough to fit all three boxes side by side or the layout will stack the third box under the first one.
Note: I would test this for you, but no browser has supported Applets for at least five years.
To make the third TextField uneditable, you want to use the setEnabled() method. setEditable() would be the way to accomplish the same thing if you were using JTextField, as opposed to the simple AWT TextField that you're using. You should get in the habit of looking at the official documentation, where the answer is readily found.
resultNum.setEnabled(false);
Bear in mind that a disabled box will appear greyed out, which may be visually unappealing. The solution is to convert to Java Swing, which will allow you to use setEditable, which simply prevents your user from clicking into the box without changing the appearance. Swing would also allow you to use layout managers with much more sophistication and flexibility.
This question already has answers here:
Enforce max characters on Swing JTextArea with a few curve balls
(3 answers)
Closed 5 years ago.
I have one question, which pops up during coding:
I want to make sure, about this question, so I hope you could help me!
So, I'm thinking about that, is the JTextArea length infinite?
Or how many chars can be used max?
I tried to write it manual, but I got bored, about 5000 lines, and 100 000 chars, so what's the limit on the JTextArea?
I'm working on a chat program, and this is important for me, but I've nowhere found the answer.
So, I'm thinking about that, is the JTextArea length infinite? Or how many chars can be used max?
No, JTextArea is not infinite.
We can imply the maximum length based on the fact that JTextArea only returns a String, which has a length which returns a int. This implies that the maximum length of a JTextArea is bound to Integer.MAX_VALUE, but, because of array overheads, is slightly smaller. But in practice, you'll probably find that it's much smaller, due to the need for arrays to be laid in memory in a continuous manner, so it will depend on how much memory the JVM has available and how fragmented it is.
We can further investigate this and have a look at PlainDocument, which is the default Document used by JTextArea, which uses a char[] as it's internal data structure, just like String.
This further concretes the reasoning that the limit of a JTextArea is limited to less then Integer.MAX_VALUE
You can have a look at Do Java arrays have a maximum size?, Why I can't create an array with large size? and Why the maximum array size of ArrayList is Integer.MAX_VALUE - 8? for discussions on why an array can't be declared as Integer.MAX_VALUE
Now, before someone suggests that you could write a linked list implementation of a Document, don't forget that both Document and JTextArea rely on String, which is a key limiting factor
I'm working on a chat program, and this is important for me
The text area supports at least several bibles worth of text (i.e. 'a lot'). Far more than could ever be read by a casual reader and immensely more than should appear in a 'chat program'.
Here is a small example that shows more than 1.1 million lines of output on the names of Unicode characters:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class HowLongTextArea {
private JComponent ui = null;
HowLongTextArea() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4,4));
JTextArea ta = new JTextArea(15, 40);
StringBuilder sb = new StringBuilder();
String eol = System.getProperty("line.separator");
for (int ii=0; ii<Character.MAX_CODE_POINT; ii++) {
sb.append((ii+1) + "\t" + Character.getName(ii) + eol);
if (ii%10000==0) {
System.out.println("ii: " + ii);
}
}
ta.setText(sb.toString());
ui.add(new JScrollPane(ta));
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
HowLongTextArea o = new HowLongTextArea();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
Thanks MadProgrammer for correcting me.
If you would like to set limit of JTextArea:
To implement a document filter, create a subclass of DocumentFilter and then attach it to a document using the setDocumentFilter method defined in the AbstractDocument class. Although it is possible to have documents that do not descend from AbstractDocument, by default Swing text components use AbstractDocument subclasses for their documents.
The TextComponentDemo application has a document filter, DocumentSizeFilter, that limits the number of characters that the text pane can contain. Here is the code that creates the filter and attaches it to the text pane's document:
JTextPane textPane;
AbstractDocument doc;
static final int MAX_CHARACTERS = 300;
...
textPane = new JTextPane();
...
StyledDocument styledDoc = textPane.getStyledDocument();
if (styledDoc instanceof AbstractDocument) {
doc = (AbstractDocument)styledDoc;
doc.setDocumentFilter(new DocumentSizeFilter(MAX_CHARACTERS));
}
source:http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html#filter
I am notdoing a school project, so please do not be alarmed. I am doing some private programming to brush up. My program, a program of type .java, creates a form that asks for the boundaries and quantities of a lottery-drawing activity and acts on the generating based on the input.
Here's my problem. On the WIndows 2000 computer where I coded the program, shows itself, perfectly. That's only half the story. When I tried to put it on another computer, the program shows a blank window; it compiles and runs, but it shows a blank window. Now, I do consider version numbers to be factors, so I will provide the versions and ask for confirmation if those are the root of the evil.
On my original computer, which is Windows 2000, the version is 1.6.0_31-b05. The other computer, which is Windows 7 dual-booted with Linux Mint 17.2, is running 1.8.0_60-b27 and 1.8.0_00 respectively.
My program is not finished yet, but I'll worry about that later. What I'm hoping to do now is to get the program, such as it is, to run on the platforms of all my computers. Since Java is known for its portability, I expect it to run on all my computers. Is that a misconception?
Anyways, here's the code:
//Import class libraries
import javax.swing.*;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.event.*;
public class Lotterygui //Begin class
{
//VARIABLES FOR DATA COLLECTION
private JTextField lowerRange; //Lowest number
private JTextField higherRange; //Highest number
private JTextField quantity; //How many numbers to generate
private JTextArea displayArea; //What to display when the program is in use
//ADD WARNING CONSTANT FOR INVALID INPUT
private final String WARNING = "Please fill out valid data "
+ "and not leave anything out. "
+ "Also,do not enter any "
+ "zeroes.";
public Lotterygui()
{
//GUI CONFIGURATION
//Frame settings
JFrame jfrFrame = new JFrame("Lottery Program");
jfrFrame.setSize(300,400);
jfrFrame.setLocationRelativeTo (null);
jfrFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrFrame.setVisible(true);
jfrFrame.setResizable(false);
//Panel to hold the user input controls in place
JPanel jplInputs = new JPanel();
jplInputs.setLayout(new GridLayout(4, 2));
//CREATE INPUT CONTROLS
//Lowest range
JLabel jlblLowerRange = new JLabel("Lowest");
lowerRange = new JTextField();
//Highest range
JLabel jlblHigherRange = new JLabel("Highest");
higherRange = new JTextField();
//Quantity
JLabel jlblQuantity = new JLabel("Quantity");
quantity = new JTextField();
//Buttons and their respective action associations
//Generate numbers button
JButton jbtnGenerate = new JButton("Generate");
ActionListener alGenerate = new listenGenerate();
jbtnGenerate.addActionListener(alGenerate);
//Reset all values button
JButton jbtnReset = new JButton("Reset");
ActionListener alReset = new listenReset();
jbtnReset.addActionListener(alReset);
//ADD CONTROLS TO FORM
jplInputs.add(jlblLowerRange);
jplInputs.add(lowerRange);
jplInputs.add(jlblHigherRange);
jplInputs.add(higherRange);
jplInputs.add(jlblQuantity);
jplInputs.add(quantity);
jplInputs.add(jbtnGenerate);
jplInputs.add(jbtnReset);
//CREATE DISPLAY AREA AND ADD
//The display area used for showing generated numbers
displayArea = new JTextArea();
displayArea.setLineWrap(true);
displayArea.setText(WARNING);
//The control that sets autoscrolling for the display area
JScrollPane jspDisplayArea = new JScrollPane(displayArea);
jfrFrame.add(jspDisplayArea);
//Add the JPanels to the window
jfrFrame.add(jplInputs, BorderLayout.NORTH);
jfrFrame.add(jspDisplayArea);
}//END lotteryGUI constructor
//MAIN Method
public static void main (String[] args)
{
//CALL UP lotteryGUI CLASS
new Lotterygui();
}//END Main method
//GENERATE BUTTONS ACTION
private class listenGenerate implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//DECLARE VARIABLES
int low; //Lowest number
int high; //Highest number
int qty; //How many numbers
try //Monitor the input of above variables in the form
{
low = Integer.parseInt(lowerRange.getText());
high = Integer.parseInt(higherRange.getText());
qty = Integer.parseInt(quantity.getText());
}
catch (NumberFormatException nfe)
{
//RESET ALL FORM VALUES
reset();
//RESET VARIABLE VALUES
low = 0;
high = 0;
qty = 0;
}//END format errors try-catch
//CHECK IF PROGRAM CAN CONTINUE
if (low != 0 || high != 0 || qty != 0) //If valid
{
//Action pending
displayArea.setText("Generate here - incomplete");
}
else //If there are more one or more errors in the input
{
//ISSUE WARNING
JOptionPane.showMessageDialog(null, WARNING);
}//END IF continue CHECK
}//END actionPerformed method
}//END listenGenerate class
I've been looking up and down at the code. Can this that I did not reference any of the layouts outlined in import? I know it's not JPanel as I did try that can still the problem existed. Anything that will help me will be appreciated. Thank you.
You're calling
jfrFrame.setVisible(true);
first and then adding a bunch of components to the JFrame, and that's backwards and can result in a GUI that does not render components until it is resized or minimized and restored. In fact try this -- run your program, then minimize the blank GUI and restore it, and I'll bet you'll see your components.
I suggest that you swap this order around -- call jfrFrame.setVisible(true); last after adding everything to the GUI.
I'm trying to produce a sigma-hat symbol (for sample standard deviation).
On a Windows 7 system, the following code produces a JLabel with a misaligned sigma hat:
JLabel sigmaHat = new JLabel("\u03C3\u0302");
And it looks like this:
http://i.imgur.com/z4Nowwm.jpg
Am I using the wrong combining character or is the Unicode for sigma-hat broken? Also, is it possible to produce a symbol for sample variance (sigma-hat-squared)?
Using U+0302 COMBINING CIRCUMFLEX ACCENT after the sigma character is the correct way. In Unicode, a combining mark appears after the base character in the data stream. And there is no other combining mark that could be conceivably used instead.
However, the result depends on the font(s) and on the rendering engine. Failures are common. Testing here: σ̂. (Does not look good.) Trying different fonts, when possible, may help. But in general, notations like this are usuall written using equation editors, LaTeX, or other tools that operate above the plain text level.
Out of curiosity I wrote up a test:
import javax.swing.*;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.EventQueue;
public class FontCheck{
final static String string = "\u03C3\u0302";
public static void main(String[] args){
EventQueue.invokeLater(()->{
JFrame frame = new JFrame("font check!");
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
content.add(new JLabel(string));
String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for(String font: fonts){
JLabel label = new JLabel(font + " : " + string);
label.setFont(new Font(font, Font.PLAIN, 12));
content.add(label);
}
frame.setContentPane(new JScrollPane(content));
frame.setSize(400, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
That shows all of the available fonts, and the first one is the default font. (Which works fine for me.)