java swing get all editable jformattedtextfields and calculate? - java

I'm trying to make a calculator which is basicly like this: user enters about 18-19 values, then he presses a button and the result is equal to his input sum divided by the number of fields.
However, it's far more complex than that. The user can specify some options which add more input fields (Basicly make an option where he makes a jformattedtextfield editable, when by default it's non-editable), this can be a huge timewaster since I have to write a huge IF statement, which I'd hate doing. Basicly the user can activate some jSpinners which make more jFormattedTExtFields editable than the default options, significantly. What I'm asking is, how can you check which jformattedtextfields are editable, which aren't, and then perform operations with the ones which are editable?

add DocumentListener to all JFormattedTextFields and take value from Number instance, for eample for Float
if (someTextField.isEditable()){
float newValue = (((Number) resistorValue.getValue()).floatValue());
}

First of all, determine container where jformattedtextfield is placed, then just use JContainer API to traverse all child components and filter all jformattedtextfield components using instanceof.
For example:
public static int calcIfEnabled(Container container) {
int finalResult = 0;
for (Component c : container.getComponents()) {
if (c instanceof JFormattedTextField && c.isEnabled() && ((JFormattedTextField) c).isEditable()) {
finalResult += Integer.parseInt(((JFormattedTextField) c).getText());
}
}
return finalResult;
}
UPD: Of course you can include all child component using recursion and pass main Container (JFrame), but it will be not so good from performance point.
public static int calcIfEnabled(Container container) {
int finalResult = 0;
for (Component c : container.getComponents()) {
if (c instanceof JFormattedTextField && c.isEnabled() && ((JFormattedTextField) c).isEditable()) {
finalResult += Integer.parseInt(((JFormattedTextField) c).getText());
} else if (c instanceof Container) {
finalResult += calcIfEnabled((Container) c);
}
}
return finalResult;
}

Simplest would be to add the JFormattedTextField to an array, whenever you create a new one.
And then when required, iterator over the array and check whether it is editable.

It sounds like your model may be sufficiently complex to warrant using the Model View Controller pattern. Your model would specify which fields make sense for the view to display for a given controller state. It would also ensure that the displayed answer was similarly consistent. This example may offer additional guidance.

Related

How to write formatted text in JTextField dynamically, like Bold, Italic or with bullets and numbering?

How can i set formatted text in JTextFiled , as like when posting answer in this website we can change style of font and adding numbering etc.
Google is your best help. Steps to construct this will follow something similar.
1: Create identifier, some character combination/symbol to define what's what(bold, italicized, underlined).
2: When text is passed into your program have something that checks to see if your identifiers were used.
3: If you find and identifier, then use an if statement, switch or something to change the font to what you want and remove the identifier from your string.
4. Then display the string where you want it.
Cheers.
I don't really get your question . You need to explain in detail so that other viewers are able to help you out.
Are you making your TextField as bold inputs?
Are you trying to make your textfield accept only numbers ?
Elaborate more on
Bullets and numebering .
if you are trying to create your own inbuild function like textField accept only numbers.
You have to create a few java classes.
For an example
template.java
private JTextField createText(boolean acceptOnlyNumbers){
JTextField userInput;
if(acceptOnlyNumbers != false){
userInput.addKeyListener(new acceptNumberOnly(userInput))
}
return userInput;
}
You can create this within the same java class, but the best way is to asign your listener to a different class so that whenever you want to modify dynamically, you could just make changes to that file instead of searching it .
class acceptNumberOnly implements addKeyListener{
JTextField textField ;
public acceptNumberOnly(JTextField textField){
this.textField = textField
}
textField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (!(Character.isDigit(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE))) {
e.consume();
}
}
});
}
I feel this is one of the best practice to use, categorised your components as class. so you can reuse this components over and over again and codes will be much neater.

how to remove JMenu.addSeparator() after it is being called

Hello guys,
I just want to ask something if is it possible to remove JMenu.addSeparator() after it is being called? for example in my form there is a menu bar and inside the menu bar lets say there are three JmenuItems and each of it has JMenu.addSeparator(). What i want to do is, if a different user is log in I want to setVisible(false) one of JMenuItem because that particular user in not authorize to use that JMenuItem. The problem is when I setVisible(false) one of the JMenuItem the JMenu.addSeparator() still exist which kinda awkward to watch since there are no JMenuItem exist in the middle of two JMenu.addSeparator(). Hope you can help me with this problem.
Thanks in advance
You have two possible solutions...
You Could...
Remove the contents of the menu and rebuilt it based on what the user can do...
menu.removeAll();
// Add menu items back in...
// Personally, I'd have some method that could return back all
// the JMenuItems that could appear on this menu based on the
// the user...
This would be my preferred solution...
You Could...
Hide/show the menu items based on what the current user can actually do and then remove all the JSeparators that appear next to each other, for example...
Component last = null;
for (Component comp : menu.getComponents()) {
if (comp instanceof JSeparator && last instanceof JSeparator) {
menu.remove(comp);
} else {
last = comp;
}
}
Personally, I know which I would prefer and generally, which would produce consistent results...
I ran into a situation where I had to remove the separator from an existing menu. (Old code and wasn't allowed to refactor the whole mess.)
So I used the idea of MadProgrammer's 2nd solution - but rewrote it to actually work.
Component last = null;
for (int idx = 0; (idx < m_fileMenu.getMenuComponentCount()); idx++) {
Component comp = m_fileMenu.getMenuComponent(idx);
if (comp instanceof JPopupMenu.Separator && last instanceof JPopupMenu.Separator) {
m_fileMenu.remove(comp);
idx--;
} else {
last = comp;
}
}

Efficeint way to manipulate multiple Checkbox items

I have a 6 JCheckBoxes in the UI and based one some user operations, I have to change the state of the JCheckBoxes, like enabling,selecting and making it invisible. So, instead of having the code as separate for each JCheckBox, I have used the following code,
Object[] checkBoxCollection = null;
checkBoxCollection = new Object[]{qualityChkBox1, qualityChkBox2, qualityChkBox3, qualityChkBox4, qualityChkBox5, qualityChkBox6};
for (int i = 0; i < checkBoxCollection.length; i++) {
JCheckBox checkBox = (JCheckBox) checkBoxCollection[i];
if (checkBox.getText().equals("Name") || checkBox.getText().equals("RollNo")) {
checkBox.setSelected(true);
} else {
checkBox.setSelected(false);
}
}
Similarly, I have some places in code, where I am keep on changing the state like setSelected(false) and setSelected(true).
Is there any way that I can do more better than this ?
Thanks in advance.
As shown here, you may be able to use EnumSet to define sets that represent coherent states of your model. Then your check boxes can share a common Action that conditions each JCheckBox according to that defined state.

Dispatching event for specific component only in java

I would like to customize JTableHeader so it would offer serval actions (for example 2 buttons which one of them would sort column and second show properties of this column etc). Unfortunately it is not possible to set CellEditor for JTableHeader so i'm stuck with using mouse adapter. But maybe it is possible to dispatch event from this particular JTableHeader component so it will show up a popup menu which will contains all options i desire and it would dispatch event if option other than sorting would be chosen. This way standard JTable sorting operation will be available, along with my operations and it will maintain a decent visual apperance. So my question is - Is it possible and how it should be done.
In response to trashgod comment - i understand that you mean to treat defaultheader as an ordinary component and just use "add" function to add Components. It doesnt work well with JTableHeader. After reading trashgod example i wrote this:
private class mouseList extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
TableColumnModel thisColumnModel = thisTable.getColumnModel();
int xCor = e.getX();
//int Cols = thisColumnModel.getColumnCount();
int thisColNum = thisColumnModel.getColumnIndexAtX(xCor);
int prevWidth=0;
for(int i = 0 ;i<thisColNum;i++)
{
prevWidth+=thisColumnModel.getColumn(i).getWidth();
}
int width = xCor-prevWidth;
/////////////////////////////////////////////////////////////////////////////////////
customHeader thisHeader = (customHeader)((JTableHeader)e.getSource()).getDefaultRenderer();
System.out.println(thisHeader.mainB.getText() + " text of thisHeader");
//////////////////////////////////////////////////
test thisTest = new test(null,false,thisHeader);
thisTest.setVisible(true);
///////////////////////////////////////////////////////////////
//System.out.println(width + " width of the header");
Object thisComp = thisHeader.getComponentAt(width, e.getY());
System.out.println(thisComp + "\n" + width + " + " + e.getY() +"\n" + thisHeader.getMainButton().getText());
((JTableHeader)e.getSource()).repaint();
if(thisComp instanceof JButton)
{
//System.out.println("sdfdsf");
String name = ((JButton)thisComp).getName();
if(name.equals("mainB"))
{
System.out.println("its working on main");
((JButton)thisComp).doClick(1000);
}else{
System.out.println("its working on menu");
((JButton)thisComp).doClick(1000);
}
}
((JTableHeader)e.getSource()).repaint();
}
}
MouseListener is applied to JTableHeader. HeaderRender is an extension of JPanel that contains 2 JButtons. Strange thing happens in line
Object thisComp = thisHeader.getComponentAt(width, e.getY());
When i left lines
test thisTest = new test(null,false,thisHeader);
thisTest.setVisible(true);
(This dialog shows selected component)
uncommented, function "getComponentAt" seems to work allmost fine (allmost because it never goes for else condition even when mouse is targeting second button, and it does not repaint clicked buttons[Strangely its repainting buttons in test dialog window]),otherwise it allways returns null object.
I dont know if it is important but i set Header renderer globally by invoking "setDefaultRenderer" on JTableHeader.
Im pretty much running out of ideas so i would appreciate any help.
This example shows the basic infrastructure, while this answer offers several important caveats regarding usability. This example shows how to change the RowFilter dynamically, but changing the RowSorter is similar. Both examples use JToggleButton to manage two states, but a JComboBox could be used to select from among more alternatives.

InputVerifier and multiple fields

I am working on a form that provides "real-time" validation to the user and I have one problem.
The goal is to put a label near the field (in this case a JSpinner), to show the user if the data is accepted or denied, in the same way that javascript-based validators do.
The problem is that for archieving this, I need to set the value for the corresponding label and the only way I have found to do this is to create as many verifiers as fields, this way:
class MyVerifier extends InputVerifier{
static final double MAX_VALUE = 30;
#Override
public boolean verify(JComponent input) {
JTextField tf = (JTextField) input;
Double value = Double.parseDouble(tf.getText().replace(',', '.'));
return (value>1);
}
#Override
public boolean shouldYieldFocus(JComponent input) {
boolean isValid = super.shouldYieldFocus(input);
if (isValid) {
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("resources/accept.png")));
jLabel1.setText("");
} else {
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("resources/exclamation.png")));
jLabel1.setText("The number of items must be greater than 1");
}
return true;
}
}
Then, the same code for jLabel2... It must be another way to do this.
Thanks in advance.
You could have a Hashmap for the text field and its related label component. Then in the shouldYieldFocus method you retrieve the related label for the text field being validated. You can then set the text/icon of the label appropriately.
You would probably also need a secound Hashmap containg the label and the text message for the error.
You could also use a JDialog as a popup next to the JComponent you are validating. This popup JDialog will have a JLabel that will encapsulate the message you want to display next to the respective Jcomponent. All you have to do is to calculate the position of the popup relative to the Jcomponent you are validating.
You can find a good example here

Categories

Resources