How to get values of dynamically generated components? - java

I am dynamically generating a list of name boxes, sliders and labels, and am trying to figure out how to access the values of the sliders and change the labels. Other posts suggest using an array, but I have no idea where to begin with that.
My code is as such:
public Tailoring(int n) {
/*initComponents();*/
JPanel containerPanel = new JPanel();
containerPanel.setLayout(new BoxLayout(containerPanel, BoxLayout.PAGE_AXIS));
this.add(containerPanel);
JLabel Title = new JLabel("Tailoring:");
containerPanel.add(Title);
for(int i = 0; i < n; i++){
JPanel rowPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JTextField NameBox = new JTextField("Guest " + (i+1));
JSlider TipSlider = new JSlider();
JLabel TipCost = new JLabel();
rowPanel.add(NameBox);
rowPanel.add(TipSlider);
rowPanel.add(TipCost);
containerPanel.add(rowPanel);
}
}

You can create a new class YourPanel which extends JPanel.
Instead of the statement
JPanel rowPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
you can use
YourPanel rowPanel = new YourPanel(new FlowLayout(FlowLayout.LEFT));
Define textfield, slider and label as the properties of this YourPanel class.
Provide getters/setters for each field. Then use an array or ArrayList of YourPanel objects in your application. You will be able to reach the nth panel's label with a call like:
panels.get(n).getJLabel();

It appears that you'd like to change the value displayed in the JLabel when the associated JSlider is modified, right? The best way to associate pairs of objects in Java is with a Map structure:
Map<Component, JSlider> sliderToLabel = new HashMap<Component, JSlider>();
for (int i = 0; i < n; i++) {
// after your loop code
sliderToLabel.put(TipSlider, TipCost); // map the slider to its label
}
You will be able to get a reference to the JSlider in the code that listens for changes on that component.
JLabel updateLabel = sliderToLabel.get(targetedSlider);
updateLabel.setText("updated text");
Notes
As a matter of convention, variable names should begin with lower case letters
The event listener I alluded to should also be attached in the loop. See Writing Event ListenersOracle

Related

Java Gui won't display panels and components

im trying to make a program to add an admin to a ms access database
I researched many times, figured out all the components need to be in a panel, and only the same type of J stuff can be in a panel, so i made many panels and combined them in a big panel
//frame details
final int FRAME_WIDTH = 1000;
final int FRAME_HEIGHT = 1000;
JFrame aFrame = new JFrame("Add admin");
aFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
aFrame.setVisible(true);
aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//panel declaration
JPanel BigPanel = new JPanel();
JPanel adminnameenter = new JPanel();
JPanel typeadminname = new JPanel();
JPanel adminlastnameenter = new JPanel();
JPanel typeadminlastname = new JPanel();
JPanel buttonaddadmin = new JPanel();
//labels, textfields, and buttons
JLabel newAdminName = new JLabel("Enter admin name");
JTextField adminName = new JTextField(7);
JLabel newadminlastname = new JLabel("Enter admin last name");
JTextField adminlastname = new JTextField(7);
JButton addadmin = new JButton("Add Admin");
//add things to panel
adminnameenter.add(newAdminName);
typeadminname.add(adminName);
adminlastnameenter.add(newadminlastname);
typeadminlastname.add(adminlastname);
buttonaddadmin.add(addadmin);
//add things to big jPanel
BigPanel.add(adminnameenter);
BigPanel.add(typeadminname);
BigPanel.add(adminlastnameenter);
BigPanel.add(typeadminlastname);
BigPanel.add(buttonaddadmin);
//add things to frame
aFrame.add(BigPanel);
the only thing that popped up was a frame that said add admin
Add this code to the end of your function:
aFrame.setVisible(false);
aFrame.setVisible(true);
Or alternatively put
aFrame.setVisible(true);
at the end of your function instead of the beginning.
And all the components will appear. This is because whenever you change anything to your JFrame, it will only change on the user side once it is told to resize or refresh the frame. Also you don't need to put every single component in it's own JPanel, you can simply insert them directly in your BigPanel (small nitpick, but the b in bigPanel, shouldn't be capitalized, seeing as variables start with non-capitalized letters).
Also look into LayoutManagers, they will probably be useful for your application.
https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

Dynamically generated jbuttons

I'm trying to make a GUI for that simulates elevators in a building (really to test threading/c-scan), but when generating the buttons for the elevator control panel and the buttons for each individual floor, I'm kind of stuck. I thinking about trying to generate a new pair of buttons for each floor, and generating a new control panel per elevator. Also there's the difficulty of having a variable amount of floors. Anyway my question what is this best way to go about doing this? Perhaps it's not necessary to generate new buttons for everything and just use one set and change what the actions do per floor/elevator? I'm asking because I'm not very familiar with GUIs. Thanks for the help
If all the elevators, and the control panel are the same, you can use a singular method and pass in the elevator or the control panel. CustomPanel extends JPanel and has a method foo.
public void createElevatorButtons(final CustomPanel panel) {
ArrayList<JButton> buttons = new ArrayList<>(); //arraylist of buttons we can keep track of
JPanel buttonPanel = new JPanel(); //the visible component
for(int i = 1; i <= numberOfFloors;i++) {
JButton button = new JButton(String.valueOf(i)); //creates buttons for floors 1 to max
buttons.add(button);
buttonPanel.add(button);
}
panel.add(buttonPanel);
//add the action listeners
for(JButton button : buttons) {
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton floor = (JButton) e.getSource();
int floorNumber = Integer.parseInt(floor.getText());
panel.foo(floorNumber); //we tell the elevator/panel/whatever to do something, you will have to extend JPanel to do foo
}
});
}
}
In this case that the number of floors is variable you can create an array of buttons:
JButton[] buttons = new JButton[MAX_NUMBER_OF_FLOORS];
Then when you determine the exact of number of floors at runtime, you can go to instantiate and add the buttons:
for(int i=0; i<numberOfFloors; i++) {
buttons[i] = new JButton();
controlPanel.add(buttons[i]);
}
Something like this should work.
Assign MAX_NUMBER_OF_FLOORS a big number like 100, there should be a possible limit given by the problem.

Java Button Action Command

I'm creating a simple Minesweeper game in Java. Size 9x9.
I create an array of JPanels and an array of buttons; I add each button to its respective JPanel. then i add the JPanels to the JFrame.
How do i distinguish between each button on the action event?
Here's some of my code:
int gridx = 9;
int gridy = 9;
JButton[] buttons = new JButton[gridx*gridy];
JPanel[] jpanels = new JPanel[gridx*gridy];
public Minesweeper(){
super("Minesweeper");
setLayout(new GridLayout(9,9));
JPanel panel = new JPanel();
int i = 0;
for(i = 0; i<gridx*gridy; i++){
jpanels[i] = new JPanel();
buttons[i] = new JButton();
buttons[i].addActionListener(buttonEvent);
jpanels[i].setLayout(new GridLayout(1,1));
jpanels[i].add(buttons[i]);
add(jpanels[i]);
}
//buttons[67].setEnabled(false);
setSize(300,300);
setVisible(true);
}
The only way i can think about doing this is adding text to the button like so:
buttons[i] = new JButton(i);
Then calling getActionCommand() but i dont want text to show up on the button. Any other ideas?
You can use AbstractButton#setActionCommand.
In your loop:
buttons[i].setActionCommand(i+"");
Then you'll get i back when you use getActionCommand
Note I did mention in a comment on another answer that I would create a new class Mine which extends JButton which I believe to be a better and more complete solution. This however gets the job done rather quickly.

Adding every element in a ArrayList to a JFrame

So I want to add some text to a window.
I added the text in a ArraList like this:
ArrayList<String> Text = new ArrayList<String>();
Text.add("text1");
Text.add("text2");
...
Text.add("text*n*");
I now want to add these items into a JFrame. Now, I am pretty new to programming, so there is probably a better solution than this. But here is what I tried (I am using a for loop, because I think this is also the easiest way for me to manage the bounds of the labels:
for(int i = 0; i<Text.size();i++){
JLabel jl = new JLabel(names.get(i));
jl.setBounds(50,100+20*i,200,50);
this.add(jl);
}
But only the last element in the ArrayList is added to the JFrame (text*n*). Not all of them.
How can I get every element in the arraylist to show in the jframe? Maybe I shouldn't use JFrame?
It sounds like you want to use a JList, not a grid of JLabel.
i.e.,
DefaultListModel<String> listModel = new DefaultListModel<String>();
JList<String> myJList = new JList<String>(listModel);
// assuming you have an array of String or ArrayList<String> called texts
for (String text : texts) {
listModel.addElement(text);
}
JScrollPane listScrollPane = new JScrollPane(myJList);
// then add the listScrollPane to your GUI
Also:
Please learn and follow Java naming rules. Variable names should begin with a lower case letter, so "text" not Text.
And you should know that every time someone uses a null layout and setBounds(...) a puppy dies. Please don't be cruel to puppies, and don't create rigid hard to maintain and upgrade GUI's. Learn and use the Swing layout managers. You won't regret this, and neither will the puppies.
You need a layout, otherwise they are added on top of each other. Try adding everything to a JPanel and only add the panel to the frame at the end.
JFrame frame = new JFrame("title");
JPanel panel = new JPanel();
// Y_AXIS means each component added will be added vertically
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
for (String str : Text) {
JLabel j1 = new JLabel(str);
panel.add(j1);
}
frame.add(panel);
frame.pack();
frame.setVisible(true);
Try with Replace names.get(i) as Text.get(i)
OR Try,
for(String str : Text){
JLabel jl = new JLabel(str);
}
Try this:
String output = "";
for(int i = 0; i<Text.size();i++)
{
output += Text.get[i] + "\n";
}
JLabel jl = new JLabel(output);
This will create a string named output that will add the text from each index, followed by creating a new line. Then at the end, the full string will be added to the JLabel. The only downside to this method is that one label will contain ALL of the text.
JLabel jl = new JLabel(names.get(i));
Here you always construct a new object for j1, and after the loop you just have the latest object.

java: how to make srollable panel with radio button and labels inside?

I got a JScrollPane in which I want to place a list of radio buttons and labels. My problem is the panel doesn't scroll, I suppose it's because i didn't set a viewport, but how can I set it when I have to many components?
My code looks something like this:
JScrollPane panel = new JScrollPane();
JRadioButton myRadio;
JLabel myLabel;
for(int i = 0; i<100; i++){
myRadio = new JRadioButton();
myLabel = new JLabel("text");
panel.add(myRadio);
panel.add(myLabel);
}
Thanks.
It is better to put your buttons and labels in a wrapper JPanel and then drop that into a JScrollPane.
try this:
JPanel panel = new JPanel(new GridLayout(0,1));
JRadioButton myRadio;
for(int i = 0; i<100; i++){
myRadio = new JRadioButton("text" + i);
panel.add(myRadio);
}
JScrollPane scrollPane = new JScrollPane(panel);
be sure to look into ButtonGroup as well. ButtonGroups allow you to enforce the single selection constraint common to radio buttons.

Categories