I have a main frame : JFrame>contentFrame>ScrollPane>BigPanel>panel_1T
private JPanel contentPane;
private JPanel BigPanel;
private JPanel panel_1T;
In panel_1T, I have put a FOOD button WITH its actionListener:
JButton button_19 = new JButton("FOOD");
button_19.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
newFoodUI nf = new newFoodUI();//Open other class
nf.setVisible(true);
nf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
});
panel_1T.setLayout(new GridLayout(0, 2, 0, 0));
panel_1T.add(button_19);
When user click FOOD button, new JFrame in newFoodUI class will be shown.:
JFrame>contentPane>panel>tabbedPane>panel_3>panel_5
In panel_5, I put a JTextField:
public static JTextField textField_3;
textField_3 = new JTextField();
panel_5.add(textField_3, "9, 4, fill, default");
textField_3.setColumns(10);
User will write some text into textField_3. Then user click SAVE button in panel_3, it will perform this:
JButton button_4 = new JButton("SAVE");
button_4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setContentPane(contentPane);
panel_3.revalidate();
panel_3.repaint();
panel_3.updateUI();
panel_5.revalidate();
panel_5.repaint();
panel_5.updateUI();
contentPane.revalidate();
contentPane.repaint();
JOptionPane.showMessageDialog(null, "Saved !");
}
});
button_4.setBounds(873, 396, 75, 33);
contentPane.add(button_4);
}
The result is, when I click SAVE button and close the Frame in newFoodUI, I will reopen back by click the FOOD button to check whether the text I wrote has been saved or not. But its not saving the text I wrote.
You have to save the value from the textfeld textField_3.getText() and set this value manually to textfeld when showing textField_3.setText(value). So you have to keep your value in your project or store persistent somewhere.
There are a couple of things to fix here and I will not give you complete code but I will point out some errors. First let's consider your button_19 listener
public void actionPerformed(ActionEvent ae) {
newFoodUI nf = new newFoodUI();//Open other class
nf.setVisible(true);
nf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
When this is performed, it creates a totally new object of newFoodUI and gives it no parameters. So how could this frame know about anything that happened before its creation if you give it nothing? Additionally, you explicitly say DISPOSE_ON_CLOSE, when you could use HIDE_ON_CLOSE if you wish to reuse it.
Then in your JButton button_4 = new JButton("SAVE"); listener you want to save the data in the text field, but your implementation does nothing to the text field. You should, for example, get the text from textField_3 and write it to a file or send back to the first JFrame.
Then there is the issue of using multiple JFrames in the first place.
Related
I have been wondering if it is possible to update JFrame or JDialogs based on the inputs inside jtextarea without button click. For an example, after i input some text in textarea. it should automatically update jlabel without the need of a button. I have search troughout but all the information i found is only based on button click . For an example ,
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(0, 1));
JTextArea input = new JTextArea();
JLabel output = new JLabel("test");
// Condition
// If user input "abc" inside textfield
// JLabel will automatically display "abc"
frame.add(input);
frame.add(output);
frame.setSize(300,400);
frame.setVisible(true);
Do i need to refresh the entire frame ? will it affect all the other textfield that user have already fill back to empty?
Thanks
Document object contained by JTextArea receives updates.
JTextArea input = new JTextArea();
input .getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {}
#Override
public void insertUpdate(DocumentEvent e) {}
#Override
public void changedUpdate(DocumentEvent arg0) {
//Add logic here to check if particular word is entered.
//if yes show label, else hide the label object
}
});
I have a JPanel which consists of a dropdown and a text field inside my JFrame. There is a button in my JFrame, when user clicks on that button, application adds new JPanel with the same components i.e. drop down and a text field. So, for this I have created a function which gets called on clicking on the button using ActionListener.
Everything works fine from GUI side but the problem is when user is done with adding JPanels and entering the values in these drop downs and text fields, it will click on Submit button. Upon clicking on Submit button, I should be able to fetch the values from all drop downs and text fields. This is a challenge, since I am using the same functions to create JPanels, I can't call its name to get the values since that will give me the last JPanel values.
Any suggestion how I should go about this? I have added the screenshot of my JFrame and the function to create the JPanel. Any help is appreciated. Thanks.
public static void AddPanel(final Container pane) {
panel1 = new JPanel();
String text = "<html><b>Property" + nooftimes + " :</b></html>";
JLabel label = new JLabel(text);
label.setPreferredSize(new Dimension(80, 30));
panel1.add(label);
panel1.add(new JLabel("Please enter the property"));
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
model.addElement("value1");
model.addElement("value2");
model.addElement("value3");
model.addElement("value4");
model.addElement("value5");
final JComboBox<String> comboBox1 = new JComboBox<String>(model);
AutoCompleteDecorator.decorate(comboBox1);
comboBox1.setPreferredSize(new Dimension(120, 22));
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField(
"Please enter your value here");
txtfield1.setPreferredSize(new Dimension(200, 22));
panel1.add(txtfield1);
txtfield1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
txtfield1.setText("");
}
public void focusLost(FocusEvent e) {
// nothing
}
});
container.add(panel1);
nooftimes++;
frame.revalidate();
frame.validate();
frame.repaint();
}
Screenshot:
}
You could return the JPanel and store it in a List<JPanel>. When you click your submit-Button you are able to iterate through the JPanels and its Components.
public class Application {
private static List<JPanel> panels = new ArrayList<>();
private static Container someContainer = new Container();
public static void main(String[] args) {
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
submit();
}
public static JPanel addPanel(final Container pane) {
JPanel panel1 = new JPanel();
// shortened code
final JComboBox<String> comboBox1 = new JComboBox<String>();
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField("Please enter your value here");
txtfield1.setText(String.valueOf(Math.random()));
panel1.add(txtfield1);
return panel1;
}
private static void submit() {
for (JPanel panel : panels) {
Component[] components = panel.getComponents();
for (Component comp : components) {
// Cast comp to JComboBox / JTextField to get the values
if (comp instanceof JTextField) {
JTextField textField = (JTextField) comp;
System.out.println(textField.getText());
}
}
}
}
}
You could simply have a class (extending JPanel) with specific methods to add your components , and to get inputs from user (i.e. get the combo box selected index and text from textfield ).
Every time you add a panel, you don't call a static method, but you create an instance of this class, keeping the reference somewhere (for example adding it to an arraylist).
But you could consider a different scenario: personally i don't like to add components "on fly", you could have a component (for example another JComboBox), where user can select the number of values he needs.
You decide a default value (for example 4), so at the beginning you create 4 panels of your class, and you can use a simple array containing them.
If the user changes the number of panels, you could dispose frame and create a new one.
Of course this solution does not woork good if you want to keep inputs inserted, or if the frame construction takes a lot of time.
Here there is a screenshot of a gui i created: user can select the number of partials, when the choice changes i just recreate the panels below,containing the textfields (which are memorized in a two-dimensional array).
I create some JButtons with a method, but I don't give them a variable i can call them with. i was wondering if it is possible to change the text somehow, after the button is created from another method. I am aware of that i can get the action command when the button is pressed but i want to change the button text, without it being pressed. I can give the buttons names like but would prefer not to. since I am only going to call half of them, and then I don't think its a good idea. or is it?
JButton button1 = buttons(0,0,0);
public JButton buttons(int coord, int coord1, int number) {
JButton box = new JButton("");
box.setFont(new Font("Tahoma", Font.PLAIN, 60));
box.setBounds(coord, coord1, 100, 100);
contentPane.add(box);
box.addActionListener(this);
box.setActionCommand(Integer.toString(number));
return box;
}
public static void main(String[] args) {
buttons(0,0,0);
buttons(98,0,1);
buttons(196,0,2);
buttons(0,98,3);
addText();
}
public void addText() {
//help me guys
button.setText("Please fix me");
}
You can get pressed button from actionEvent
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
}
Why not just have them in a public arraylist?
ArrayList<JButton> buttons = new ArrayList<JButton>();
public JButton buttons(int coord, int coord1, int number) {
JButton box = new JButton("");
box.setFont(new Font("Tahoma", Font.PLAIN, 60));
box.setBounds(coord, coord1, 100, 100);
contentPane.add(box);
box.addActionListener(this);
box.setActionCommand(Integer.toString(number));
buttons.add(box);//Add it here
return box;
}
This way you can loop through them later and change something if you want to,
for(JButton b : buttons){
if(/*Whatever*/){
b.setText("New name");
}
}
I can give the buttons names like but would prefer not to. since I am only going to call half of them, and then I don't think its a good idea. or is it?
You are creating problems for yourself. Even if you may only need the call a few/none of them, there is significant advantage for not keeping a reference for them.
If you have too many JButtons and you do not want to have a separate variable name for each of them, you can have an array/collection of JButtons.
JButton[] btns = new JButton[size];
//or
ArrayList<JButton> btns= new ArrayList<JButton>();
To change text for all buttons:
for(JButton b : btns)
btns.setText("whatever here");
To change text for a specific button:
btns[x].setText("whatever here"); //from array
btns.get(x).setText("whatever here"); //from list
Alternatively, if you do not keep a reference. You can get the list of buttons from the content pane:
Component[] components = myPanel.getComponents();
for(Component c : components)
if(c instanceof JButton)
((JButton)c).setText("whatever here");
I'm trying to get to panels to work with each other RECURSIVELY.
When I'm on the main GUI I have the first JPanel with a Button Add Client,
Once clicked it brings me to the JPanel with a Form and then I recuperate those values,
and send them away in a JTable in the first JPanel the Main GUI.
When I then try to insert a second record. I get a blank GUI. I'm not too sure what I am doing wrong. How can I implement multiple time the same action to repeat ? Which is Load up the form, enter the information, push it on the Table, and the process repeats as much as I need it.
This is the Add Client button declaration in the MAIN GUI
Button btn_AddClient = new Button("Add Client");
btn_AddClient.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panel.setVisible(false);
contentPane.setVisible(false);
setContentPane(contentPaneClient);
}
});
btn_AddClient.setBounds(259, 12, 70, 22);
contentPane.add(btn_AddClient);
This is the Add Button of the Form in the second Panel
JButton btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setContentPane(contentPaneClient);
panel.setVisible(true);
contentPane.setVisible(true);
contentPaneClient.setVisible(false);
LigneJTab l = new LigneJTab(textFieldPrenomClient.getText(),textFieldNomClient.getText(), textFieldAdresseClient.getText(), chckbxHomme.isSelected(), Sport.FOOTBALL);
myModel.addLine(l);
setContentPane(contentPane);
}
});
btnAdd.setBounds(263, 40, 117, 29);
contentPaneClient.add(btnAdd);
JButton btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//setContentPane(contentPaneClient);
//panel.setVisible(true);
//contentPane.setVisible(true);
//contentPaneClient.setVisible(false);
LigneJTab l = new LigneJTab(textFieldPrenomClient.getText(),textFieldNomClient.getText(), textFieldAdresseClient.getText(), chckbxHomme.isSelected(), Sport.FOOTBALL);
myModel.addLine(l);
panel.setVisible(true);
contentPane.setVisible(true);
setContentPane(contentPane);
}
});
btnAdd.setBounds(263, 40, 117, 29);
contentPaneClient.add(btnAdd);
Commented the top part and added the setContentPane(contentPane); and that worked !
Thanks !
Another idea: You don't need to swap out the content panes to ask for data. A much more elegant way is using a modal dialog box. To make one, first create a dialog class:
public class MyDialog extends JDialog {
public MyDialog(Frame parent) {
super(parent);
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
// add components to getContentPane()
// to close dialog, use setVisible(false) in listeners
}
public OutputData getData() {
OutputData data = new OutputData();
show();
// show only returns after a setVisible(false)
data.field = textField.getText();
// for example, repeat as many times as necessary
return data;
}
}
To invoke this dialog from the JFrame, use the following code:
MyDialog dialog = new MyDialog(this);
OutputData data = dialog.getData()
// now retrieve fields from data
My program is about a supermarket. When I compile the program, both the JFrame windows 'f1' and 'f2' appear on the screen. However I want JFrame window 'f1' to appear first and then after clicking on the JButton 'b1' of 'f1' window, I want the JFrame window 'f2' to come. Below is the delivery() method of my program:
public static void delivery()
{
final JFrame f1 = new JFrame("Name");
GridLayout grid = new GridLayout(20, 40, 10, 8);
f1.setLayout(grid);
f1.setVisible(true);
f1.setSize(600,200);
f1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f1.setLocation(700,450);
JPanel p1 = new JPanel();
final JLabel l1 = new JLabel("Enter your name: ");
final JTextField jt1 = new JTextField(20);
JButton b1 = new JButton("Ok");
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
input1 = jt1.getText();
f1.dispose();
}
});
p1.add(b1);
p1.add(l1);
p1.add(jt1);
f1.add(p1);
final JFrame f2 = new JFrame("Address");
f2.setVisible(true);
f2.setSize(600,200);
f2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f2.setLocation(700,450);
JPanel p2 = new JPanel();
final JLabel l2 = new JLabel("Enter your address: ");
final JTextField jt2 = new JTextField(20);
JButton b2 = new JButton("Ok");
b2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
input2 = jt2.getText();
f2.dispose();
}
});
p2.add(b1);
p2.add(l2);
p2.add(jt2);
f2.add(p2);
JOptionPane.showMessageDialog(null, "The ordered stuff will be delivered to " +input1+ " who lives in: " +input2 , "Delivery" , JOptionPane.PLAIN_MESSAGE);
JOptionPane.showMessageDialog(null, "Thank you for shopping at Paradise 24/7. Hope to see you again." , "Shopping Done!" , JOptionPane.PLAIN_MESSAGE);
}
The line of code that makes a frame appear is this
f1.setVisible(true);
You have this for both frames within your delivery method.
To make one appear after the other change this so that one gets set to visible and the other gets unset within the code for the button ie (you will obviously have to declare f2 before this though)
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
input1 = jt1.getText();
f1.dispose();
//f1.setVisible(false); // or dispose if you no longer need it
f2.setVisible(true);
}
});
Just a suggestion: A better approach maybe to use a JDialog. This would allow you to get the input form the user wait for response, and then prompt for the next input. Click here for tutorial on Dialogs
You may also want to look at some layouts when adding components your frames/panels. GridLayout, BorderLayout, FlowLayout
Simply add the code f2.setVisible(true); in actionPerformed() of the Button.
For e.g.
f1.setBounds(whatever);
f2.setBounds(whatever);
//add button in JFrame and actionListener
f1.setVisible(true);
f2.setVisible(false);
actionPerformed(ActionEvent e)
{
f2.setVisible(true);
}
Then you must read JavaDocs first and read some good ebooks for Java Beginner like Java 2 Complete Reference, O'Really - Java Swing will be helpful for you