I want to add a number of Buttons to my Java application based on an array. Say if there are 10 objects in an array, I want to create 10 buttons. If I delete 2 objects in the array the buttons should also get deleted. I thought about 3 things to go on about this problem.
A for loop - but I think the buttons would just exist inside the loop and also I would not know how to name the buttons (the variable name not the label).
A Thread
A seperate class
I have no idea how I would do that though.
Can I actually name variables through loops?
Are any of my ideas practicable?
If you add a button to a JPanel it will survive outside the for loop, so don't worry about it. Create a JPanel just for your buttons and keep track of those you add using an ArrayList<JButton>, so you'll be able to delete them as you need. To delete them from the panel, refer to this answer. Remember to repaint (=refresh) the JPanel.
JButton button1 = ...;
// Add it to the JPanel
// https://stackoverflow.com/questions/37635561/how-to-add-components-into-a-jpanel
ArrayList<JButton> buttons = new ArrayList<>();
buttons.add(button1);
// Other stuff...
// It's time to get rid of the button
JButton theButtonIWantToRemove = buttons.get(0);
buttons.remove(0);
//Get the components in the panel
Component[] componentList = panel.getComponents();
//Loop through the components
for(Component c : componentList){
//Find the components you want to remove
if(c == theButtonIWantToRemove){
//Remove it
panel.remove(c);
}
}
//IMPORTANT
panel.revalidate();
panel.repaint();
Related
I have a JFrame named MainGUI. Inside of MainGUI I have passed three LinkedList ll1, ll2, ll3.
These LinkedList are full of data and I'm trying to just print one of them on the screen into my JPanel. I'm use to just doing a for loop and using System.out.println to print things out onto the screen.
So right now I have MainGUI which hosts three buttons.
New Tasks In Progress Tasks Completed Tasks
Each button has a different LinkedList ll1, ll2, ll3 etc.
I want to be able to click the button and have the data elements listed below in the JPanelI created which rests under the buttons.
Any help is deeply appreciated.
Since you provided no code, I assume you are having trouble understanding how LinkedList can interact in programs that have a GUI.
First off, when using buttons you always need to instruct them to do something when they are clicked by adding an ActionListener, as explained in this answer.
Secondly, if you want to add the list data to the JPanel, there are a few ways you can do it. A JList, or if you'd like the user to be able to copy and paste the data (I find it to be very handy), a JTextArea, ... Just make sure to call setEditable(false) in order to stop the user from fiddling with the data you provide. Considering a JTextArea, here's what that would look like, if ll1 contained Strings:
Adding somewhere that our JPanel contains a JTextArea:
JTextArea txtArea = new JTextArea();
txtArea.setEditable(false);
panel.add(txtArea);
Now, we order the button to do something when clicked:
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
txtArea.setText(null); //clear out old text
for(String str: ll1) {
txtArea.append(str+"\n");
}
panel.revalidate(); //repaint JPanel
}
});
This way, you can click the button as many times as you want. Note that if you add more content to ll1 after it is displayed it won't get visually updated by itself, you will always need to click the button again or look further into Listeners.
You can try adding a JTextArea or whichever JComponent that suits what you want to display to the JPanel that you want to display the data from. Write the data from your linked list to that JComponent using its method e.g. append() if you're using JTextArea.
I made a calculator in Java, but some of the code is very repetitive. Here is what I used to add an ActionListener
one.addActionListener(handlerOne);
two.addActionListener(handlerOne);
three.addActionListener(handlerOne);
four.addActionListener(handlerOne);
five.addActionListener(handlerOne);
six.addActionListener(handlerOne);
seven.addActionListener(handlerOne);
eight.addActionListener(handlerOne);
nine.addActionListener(handlerOne);
zero.addActionListener(handlerOne);
add.addActionListener(handlerOne);
subtract.addActionListener(handlerOne);
multiply.addActionListener(handlerOne);
divide.addActionListener(handlerOne);
sqrt.addActionListener(handlerOne);
exp.addActionListener(handlerOne);
equals.addActionListener(handlerOne);
cls.addActionListener(handlerOne);
modulus.addActionListener(handlerOne);
Is there any way to shorten this up?
You could put all your components (buttons) in a List an attach the listener by some code like
for( Component c : componentsList ) {
c.addActionListener(yourListener);
}
Use a JButton[] for all or some (only digit buttons maybe) of your buttons. Then iterate over that array and add ActionListener to the buttons:
JButton[] buttons = new JButton[10]; // For digit buttons.
int i = 0;
for(JButton button: buttons)
buttons[i++].addActionListener(handlerOne);
Similarly you can use a JButton[] for the operator buttons. By using different arrays, you can avoid possible confusions, I think.
Create a method that will create buttons and assign a listener to it. You still end up with a bunch of calls, but at least all the button creation and initialization code will reside in the same method, so it will be easier for you to modify it for every button.
There may be another alternative - add all your button to a single container and add your listener to that container.
When a particular button is clicked I want another set of buttons to be added to the Panel, however at the moment when I do this, I can add them as many times as I want, I need this to be only possible once. Would the best way to do this be set the adding of the buttons and fields in a while loop?
if(e.getSource() == selectScript){
while(scriptB < 1 ){
imageID = new JTextField("INT");
imageDescription = new JTextField("imgDescription");
imagePath = new JTextField("imagePath");
manageImageTab.add(imageID);
manageImageTab.add(imageDescription);
manageImageTab.add(imagePath);
insertImage = new JButton("Add an Image");
insertImage.addActionListener(new dbaccess());
manageImageTab.add(insertImage);
manageImageTab.revalidate();
validate();
scriptB++;
}
}
Perhaps rather than add and remove the JButtons, you could add the buttons once at the code start, just don't make them visible until you need them, or perhaps better place them all on a JPanel that is not visible and then made visible when desired. Just don't forget to call revalidate() and repaint() on the container that holds the buttons and their panel.
If I understand you correctly, I would use a flag alreadyAdded that starts out false, gets set to true after the controls have been added, then don't allow it to add after that.
I have a tabbed view in my program and under each tab I have several panels which I rotate between with buttons. I've decided to implement a CardLayout for each one of these tabs, and given that I have about 7 tabs I decided to write a class to make things a bit neater. The class is called PanelSystem and it takes in JPanels which have already been created and adds them to a CardLayout. I will also implement a switchPanel method to move between panels. So far I have:
public class PanelSystem {
JPanel cards;
CardLayout cl;
public PanelSystem(JPanel...panels) {
// Create Panel with card layout
cards = new JPanel(new CardLayout());
// Add all the panels to the card system
for (JPanel p : panels) cards.add(p);
// Gains access to the card layout?
cl = (CardLayout)(cards.getLayout());
// Show starting card
cl.show(cards, *UNIQUE IDENTIFIER*);
}
}
Since there are different numbers of JPanels for each tab I had to implement the JPanels...panels line. I'm not sure if this works correctly yet, but the problem comes at the end of the constructor where I'm trying to show the first card since it doesn't have a unique identifier because of the way I added them. Any thoughts on how I could fix this?? Thanks in advance guys!
You can access the varargs as if it were an array (which it is, anyway). How about if you loop through it with a classical for loop
for (int i = 0; i < panels.length; i++) {
cards.add(panels[i], Integer.toString(i));
}
then at the end
cl.show(cards, "0");
Edit: I'm rusty on Swing layouts, can't remember exactly whether you need your identifier to be a String or just any Object, but you should be able to figure it out from here.
I am adding and deleting components dynamically in a JPanel.
Adding and deleting functionality works fine but when I delete the component it deletes the last component rather than the component to be deleted.
How can I solve this issue?
Interestingly enough I am coming across the same issue and I am surprised people are upvoting the other answer, as he is clearly asking about dynamically created Components, not components already created under a variable name which is obtainable, instead of anonymously created objects.
The answer is pretty simple. Use
getComponents() to iterate through an array of components added to the JPanel. Find the kind of component you want to remove, using instanceof for example. In my example, I remove any JCheckBoxes added to my JPanel.
Make sure to revalidate and repaint your panel, otherwise changes will not appear
Component is from java.awt.Component.
//Get the components in the panel
Component[] componentList = panelName.getComponents();
//Loop through the components
for(Component c : componentList){
//Find the components you want to remove
if(c instanceof JCheckBox){
//Remove it
clientPanel.remove(c);
}
}
//IMPORTANT
panelName.revalidate();
panelName.repaint();
Using the method Container.remove(Component), you can remove any component from the container. For example:
JPanel j = new JPanel();
JButton btn1 = new JButton();
JButton btn2 = new JButton();
j.add(btn1);
j.add(btn2);
j.remove(btn1);