Purely theoretically when adding new components like that
JButton buttonAdd= new JButton("Add More");
buttonAdd.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel.add(new JComboBox<String>(data);
panel.add(new JTextField();
}
});
Is there way to getSelectedIndex() or getText() when u don't declare it in normal way?
there are several ways to reach dynamicaly added components to swing tree:
1st approach:
panel.getComponent(n);
returns n'th component in the panel (Container). (n is the order, that component added to its parent (parent is panel here) ) (you need to know component's index) this way you can use ((JComboBox)panel.getComponent(3)).getSelectedIndex()
2nd approach
directly add some listeners when dynamically adding your components;
JButton b1 = new JButton("add");
b1.addActionListener(e -> {
JComboBox<String> color = new JComboBox<String>();
color.addActionListener(x -> { myFormBean.setColor(color.getSelectedItem();) });
panel.add(color);
JTextField name = new JTextField();
name.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
myFormBean.setName(name.getText());
}
#Override
public void insertUpdate(DocumentEvent e) {
myFormBean.setName(name.getText());
}
#Override
public void changedUpdate(DocumentEvent e) {
myFormBean.setName(name.getText());
}
});
panel.add(name);
panel.revalidate();
panel.repaint();
});
this way you do not need to reach your dynamically added components.
3rd approach may be using a framework for data binding,
4rd approach ...
Yes, you can add Swing components to the container this way. However you need to call revalidate on the panel, otherwise they may not appear instantly.
If you need to access these components after they are created, assign the value returned by constructor to the field of your object, declared inside your class. You cannot assign to the variable in the calling method as the constructors are called from the inner class.
Related
How we can use same method (same paramater and return type) with different implementation
in other word , in java Gui i want to use mouseClick method in many different way in one class , how this could be possible ?
You would implement different MouseListeners and add these to each component you want different mouseClick behavior in.
Edit: I added an example below.
public void example() {
JPanel panel1 = new JPanel();
panel1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
/* your code here, what should happen when the mouse clicked the panel */
}
});
JTable table1 = new JTable();
table1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
/* your code here, what should happen when the mouse clicked the table */
}
});
}
Here I used new MouseAdapter() more here instead of new MouseListener(), which implements MouseListener because this allows you to only implement a single method of the MouseListener interface.
I need some help to figure out how can i make one text field observable to many frames .. it's like a messaging app all frames can send to that text field and all of them must get updates when it changes
I would follow the JavaFX approach, as a JTextField does not have a model (as JTextPane does). (Adding listeners to a view component is not entirely MVC.)
Instead of updating the JTextField have a model: a StringProperty and update that. Have one Observable listener to update the JTextField, and all others to update all the frames, using addListener.
A JTextField has an underlying document that is a kind of model. To observe the text, you would do:
jTextField.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
}
#Override
public void removeUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent e) {
}
});
Try this as a test and you will see you just need to set the same model on all the text fields that need to have the same information.
JTextField t1 = new JTextField();
JTextField t2 = new JTextField();
PlainDocument doc = new PlainDocument();
t1.setDocument(doc);
t2.setDocument(doc);
setLayout(new GridLayout(0, 1));
add(t1);
add(t2);
I have 16 JTextarea's placed on my panel (in gridlayout). I didn't use the design tools netbeans for this. The code generates them for me:
for (int i = 0; i < 16; i++) {
JTextArea vak = maakVak(gridLayoutPanel); //make new JTextArea and add them to gridlayout.
tekstvakken.add(vak); //save Jtextarea to ArrayList.
}
This is the method for generating a new JTextArea and adding them to the GUI.
public JTextArea maakVak(JPanel p) {
JTextArea vak = new JTextArea(80, 120);
vak.setEditable(false);
p.add(vak);
return vak; //return JTextarea to save in the ArrayList
}
I have an ArrayList that contains objects from a class that I made for the software. The Objects contain multiple Strings. I need to "print" all the strings from one object to one JTextArea, and I do that for the first 16 objects in my ArrayList (hence I've only 16 JTextArea's).
This works fine, I have 16 JTextArea's on my GUI and they contain the correct Strings.
Now I want to add more functionality to my software, and I need in some way to make these JTextArea's clickable (when this event occurs, a screen should pop-up where I can change/delete the object).
How is this possible (with minor changes)?
JTextArea is a java.awt.Component, so it has access to the addMouseListener method.
textArea.addMouseListener(new MouseListener(MouseEvent e) {
//implemented methods go here
});
This will create an anonymous inner class which implements MouseListener, and I found it to be the simplest way to do this.
Otherwise, you can just have your class implement MouseListener. This accomplishes the same thing as you still have to override the methods, but it affects the whole class rather than an anonymous class that is only used once.
If the Strings that will be placed in the JTextAreas aren't very lengthy, I would suggest using JButtons instead, so you could use the addActionListener method instead of having to also override four other methods that you won't use.
add a mouseListener to JTextArea in maakVak
public JTextArea maakVak(JPanel p) {
JTextArea vak = new JTextArea(80, 120);
vak.setEditable(false);
vak.addMouseListener(textAreaMouseListener());
p.add(vak);
return vak; //return JTextarea to save in the ArrayList
}
private MouseListener textAreaMouseListener() {
return new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
JTextArea vak = (JTextArea) e.getComponent();
//display popup to make changes
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
};
}
I am making an applet and as part of my applet, I want this to happen: When the user presses "OK", the old components (some radio buttons) are removed, and a new JPanel is added, with a bunch of textfields.
However, I cannot figure out how to add a new component to the applet after it has started. I made the problem simpler by ignoring the removal part (Which I know how to do) and just adding a simple JLabel instead, but even that won't add!
Here is my code so far:
// imports omitted
public class Class extends Applet implements ActionListener
{
Button okButton;
CheckboxGroup radioGroup;
Checkbox radio1;
Checkbox radio2;
Checkbox radio3;
JLabel j;
public void init()
{
setLayout(new FlowLayout());
okButton = new Button("OK");
j = new JLabel("hello");
radioGroup = new CheckboxGroup();
radio1 = new Checkbox("Red", radioGroup,false);
radio2 = new Checkbox("Blue", radioGroup,true);
radio3 = new Checkbox("Green", radioGroup,false);
add(okButton);
add(radio1);
add(radio2);
add(radio3);
okButton.addActionListener(this);
}
public void repaint(Graphics g)
{
if (radio1.getState()) add(j);
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == okButton) repaint();
}
}
What am I doing wrong?
You shouldn't override the repaint method, and certainly not add a component in this method. Just remove the radio buttons from the applet (using its remove method) and add the label in the applet in your actionPerformed method, the same way you add them in the init method.
You might have to call validate after.
Add components and then call validate() of your container. In this case yourApplet.validate(). This will trigger repainting and rearranging of all elements.
you could do something like
JFrame fr= new JFrame(); // global variables
JPanel panelToBeAdded = new JPanel();
JPanel initialPanel = new JPanel();
JTextField fieldToBeAdded = new JTextField();
panelToBeAdded.setPreferredSize( new Dimension(400,400));
initialPanel.setPreferredSize( new Dimension(400,400));
initialPanel.setVisible(true);
fr.add(initialPanel);
fr.setVisible(true);
fr.pack();
public void actionPerformed(ActionEvent ae) {
initialPanel.setVisible(false);
//radiobuttons.setVisible(false);---> hide the radio buttons
panelToBeAddedd.add(fieldToBeAddedd);
panelToBeAddedd.setVisible(true);
fr.add(panelToBeAddedd);
}
public void repaint( Graphics g ) {
// do something
}
What am I doing wrong?
Your repaint(Graphics) method is not the same method you are calling in your actionPerformed method.
Also, repaint is a pretty bad name for a method which is adding a new component.
public void swapComponents()
{
if (radio1.getState()) {
remove(radio1);
remove(radio2);
remove(radio3);
add(j);
validate();
}
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == okButton) {
swapComponents();
}
}
When the user presses "OK", the old components (some radio buttons) are removed, and a new JPanel is added, with a bunch of textfields.
Use a CardLayout, as shown here. It is perfect for situations like this.
I have a screen in which one of its components is made invisible depending on a boolean value. If the boolean changes after the screen has been created, how do I refresh the screen to take this into account?
I think revalidate() is more appropriate here if you are dealing with JComponents.
From the JavaDoc:
Supports deferred automatic layout.
Calls invalidate and then adds this component's validateRoot to a list of components that need to be validated. Validation will occur after all currently pending events have been dispatched. In other words after this method is called, the first validateRoot (if any) found when walking up the containment hierarchy of this component will be validated. By default, JRootPane, JScrollPane, and JTextField return true from isValidateRoot.
This method will automatically be called on this component when a property value changes such that size, location, or internal layout of this component has been affected. This automatic updating differs from the AWT because programs generally no longer need to invoke validate to get the contents of the GUI to update.
Call the validate() method on the container that needs to be laid out -- probably your window's content pane.
Try calling repaint() which in turn will call paintComponent().
I thought that (with Java 6?) you need not do anything... This should happen automatically - no?
With the following example, it does happen automatically...
public class TT extends JFrame
{
public TT()
{
setLayout(new FlowLayout());
JLabel label = new JLabel();
label.setText("Label:");
add(label);
final JTextField textField = new JTextField();
add(textField);
JButton button = new JButton();
button.setText("Button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (textField.isVisible())
{
textField.setVisible(false);
}
else
{
textField.setVisible(true);
}
}
});
add(button);
setSize(100,100);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
TT frame = new TT();
frame.setDefaultCloseOperation(TT.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
[Add] And using a layout manager like GridBagLayout would also solve the problem of "Re-Laying out" the page.