Using instanceof to change color of JLabels - java

I am looking for away to change the text color of all my JLabels with a function so I don´t have to use the setForegroundColor for each and every one of them.
I currently have a bunch of JLabels in a panel called Main. I did a bit of research and came across the instanceof and getComponents method. So I've come this far:
main = new JPanel();
main.setBackground(Color.red);
tf_search = createTF();
l_name1 = new JLabel("Name: "+ DB.findUser(1001).returnName());
l_nick = new JLabel("Nick: " + DB.findUser(1001).returnNick());
l_style = new JLabel("Style: ");
l_styleshow = new JLabel(DB.findUser(1001).returnStyle());
l_music = new JLabel("Favourite songs: ");
l_musicshow1 = new JLabel(DB.findUser(1001).returnMusic1());
l_musicshow2 = new JLabel(DB.findUser(1001).returnMusic2());
l_musicshow3 = new JLabel(DB.findUser(1001).returnMusic3());
l_blank = new JLabel("");
l_blank2 = new JLabel("");
l_inst = new JLabel("Instrument: ");
l_instshow = new JLabel(DB.findUser(1001).returnInst());
l_band = new JLabel("Band: ");
l_bandshow = new JLabel(DB.findUser(1001).returnBand());
b_search = new JButton("Sök");
b_musicchn = new JButton("Edit Profile");
b_return = new JButton("Return to profile");
main.setLayout(new GridLayout(9,2));
main.add(l_name1);
main.add(l_nick);
main.add(l_style);
main.add(l_styleshow);
main.add(l_music);
main.add(l_musicshow1);
main.add(l_blank);
main.add(l_musicshow2);
main.add(l_blank2);
main.add(l_musicshow3);
main.add(l_band);
main.add(l_bandshow);
main.add(l_inst);
main.add(l_instshow);
main.add(b_search);
b_search.addActionListener(new searchHandler());
main.add(b_musicchn);
b_musicchn.addActionListener(new editHandler());
main.add(tf_search);
main.add(b_return);
b_return.addActionListener(new returnHandler());
And all the Panels and stuff are declared, or what to call it. ex "private JLabel l_nick, etc"
So I thought this might select all JLabels and turn the text to white, but my code doesn't work hehe. Is this a legit way of doing things and can you correct it, or does someone know another way. Thanks in advance!
Note: I am a student and this is for my final project in my first programming year, so I just want the code variety. If it is not possible with a massive, advanced block of code don't bother typing it out, even though your help is appreciated!

don't do this:
main.getComponents(l_label instanceof JLabel).setForegroundColor(Color.White);
instead define a List<JLabel> mylabels = ...
populate the list:
myLabels.add(l_label);
myLabels.add(l_label2);
myLabels.add(l_label3);
and do a for enhanced
for(JLabel x:myLabels){
x.setForegroundColor(Color.White);
}

You may retrieve all child components, check if they are JLabel, and set the color accordingly .
for (Component component : panel.getComponents()) {
if (component instanceof JLabel) {
component.setForeground(Color.WHITE);
}
}

I don't know of a method getComponents that takes a filter argument. But you could use streams to filter. Something like this:
Stream.of(main.getComponents()).filter(component -> component instanceOf JLabel).forEach(label -> ((JLabel)label).setForegroundColor(Color.White));

Related

Programmatically Name Variables in Java for GUI

I am creating a GUI in java using gridLayout 6 x elevatorNum. My purpose is to create the number of columns based on the user input "elevatorNum" so that it can automatically be expanded. My problem now is that I want to populate each column with the same 6 JLabel fields and then be able to use these fields to change their values whenever I want to.
I am not able to do this since I will have to create a new set of 6 JLabels for each column but for that I would need to either hardcode each column or automatically expand them using user input. I want to automatically expand them using userInput but I don't know how to name each set of 6 JLabels without hardcoding them.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLayout(new GridLayout(7,elevatorNum));
JLabel totalFloors = new JLabel("Total floors: " + floorNum);
JLabel currentFloor = new JLabel("CurrentFloor : N/A");
JLabel destFloor = new JLabel("Destination Floor: N/A");
JLabel doorStatus = new JLabel("Doors Status: N/A");
JLabel motorStatus = new JLabel("Motor Status: N/A");
JLabel passengerStatus = new JLabel("Passenger Status: N/A");
JLabel elevatorStatus = new JLabel("Elevator Direction: N/A");
frame.add(totalFloors);
frame.add(currentFloor);
frame.add(destFloor);
frame.add(doorStatus);
frame.add(motorStatus);
frame.add(passengerStatus);
frame.add(elevatorStatus);
Now i want to create another 6 set of JLabels but I will have to use different name but I don't know the userinput so I cannot hardcode the 6 JLabels. I also want to use each set of JLabels later on to update/edit their values.
I would greatly appreciate your help.
I had a similar experience of populating the layout with buttons and need to change their values anytime I want. I think you don't need to have user input to create labels, try simply create JLabels in a for loop, and track them by adding each of them to a List. you could find exactly that label through its index in array.
for example, create a list to track them:
List<JLabel> labelList = new ArrayList<>();
then create a method to create JLabels:
private JLabel createLabel() {
JLabel newLabel = new JLabel("give_it_an_initial_name");
// maybe do something on each label
return newButton;
}
finally add them to frame:
for(int i = 0; i < 6 * elevatorNum; i++) {
JLabel addLabel = createLabel();
frame.add(addLabel);
labelList.add(addLabel);
}
when you want to change something on label, fetch it from list and edit, no need to give each of them a name.It's a very simple way, might not be very good, but it works.

Making an interactive GUI in Java for own program

To start with -- I'm not sure, that I have properly formulated the question (I'm new in Java and in making programs with GUI).
It is the following thing, I'm trying to do. I have a window with several similar parameters (numbers are just for distinction between lines and it ist just very simplified example, of what should my GUI be):
Initial Window
Then, by clicking on the "+"-button I would like to add an new line, like here:
Line 35 is added
It should be also possible to delete lines, like here: Line 30 was deleted, by pressing "-"-Button.
As I wrote at the beginning, it is possible, that there was such a question, but I couldn't find anything (probably, because I do not now the keywords or I was looking with a wrong ones).
How such window can be done? The only idea I have is to draw a new window after every +/-.
Addition: Code (not working in the part of changing the number of rows).
import javax.swing.*;
import java.awt.event.*;
public class Test extends JFrame {
public Test() {
setSize(200, 600);
JButton plusButton[] = new JButton[100];
JButton minusButton[] = new JButton[100];
JTextField fields[] = new JTextField[100];
JPanel panel1 = new JPanel();
for (int i=0; i<plusButton.length; i++) {
plusButton[i]=new JButton("+");
minusButton[i]=new JButton("-");
fields[i] = new JTextField("Text "+ i);
}
for (int i=1; i<4; i++) {
panel1.add(plusButton[i*10]);
plusButton[i*10].setActionCommand("add after " +String.valueOf(i));
panel1.add(minusButton[i*10]);
minusButton[i*10].setActionCommand("remove " +String.valueOf(i));
panel1.add(fields[i*10]);
}
panel1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
this.getContentPane().add(panel1);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
for (int i=0; i<100; i++) {
String stand1 = "add after "+String.valueOf(i);
String stand2 = "remove "+String.valueOf(i);
if (stand1.equals(e.getActionCommand())) {
//add "row" of elements
panel1.add(plusButton[i]);
plusButton[i+1].setActionCommand("add");
panel1.add(minusButton[i+1]);
minusButton[i+1].setActionCommand("remove");
panel1.add(fields[i+1]);
} else if (stand2.equals(e.getActionCommand())) {
//delete "row" of elements
}
}
}
public static void main(String[] args) {
Test a = new Test();
}
}
The Problem, that is obvious -- when I want to add 2 rows (i think it is proper definition) of buttons after button 20, there will be an doubling of numbers. As a solution I see here a creation of a new panel for each new row. But it is sounds wrong for me.
P.S. Unfortunately I do not have time to end this topic or to post a working example. I actually found some kind of solution, beginning from the Question here, on Stack Overflow:
Adding JButton to JTable as cell.
So, in case somebody will be looking for such topic, it should sounds like "jButton in jTable".
There are multiple GUI frameworks for Java. First decide which one you wanna use.
As for your particular query
Add functionality to the + and - such that it will create an instance of a field object (that line with parameters as you call them) or destroy that particular instance of the object.
+ is clicked -> Create new object on consecutive line and increase the pointer-count(?) of the following fields.
- is clicked -> Call destructor for the particular object and decrease the pointer-count of the following fields.

How to create multiple field in swing and use the value in a for loop

I want to make a user interface where the user can select the caracteristic of each pizza he wants.
And I would like to be abl to use the value enter by said user.
So here's my code:
JPanel panelComm2 = new JPanel();
String[] crust = Crust.names();
String[] size = Size.names();
String[] drink = Drink.names();
Box verticalBox = Box.createVerticalBox();
for(int i=0;i<nbPizza;i++){
Box horizontalBox = Box.createHorizontalBox();
JLabel crustJLabel = new JLabel("Crust Pizza "+ (i+1)+": ");
horizontalBox.add(crustJLabel);
JComboBox comboCrust = new JComboBox(crust);
horizontalBox.add(comboCrust);
JLabel sizeJLabel = new JLabel("Size Pizza "+ (i+1)+": ");
horizontalBox.add(sizeJLabel);
JComboBox comboSize = new JComboBox(size);
horizontalBox.add(comboSize);
verticalBox.add(horizontalBox);
}
for (int j=0;j<nbDrink;j++){
Box horizontalBox = Box.createHorizontalBox();
JLabel drinkJLabel = new JLabel("Drink "+ (j+1) +": ");
horizontalBox.add(drinkJLabel);
JComboBox comboChooseDrink = new JComboBox(drink);
horizontalBox.add(comboChooseDrink);
verticalBox.add(horizontalBox);
}
panelComm2.add(verticalBox);
int p = JOptionPane.showOptionDialog(null, panelComm2, "Select option",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, options2, options2[0]);
if (p == JOptionPane.YES_OPTION) {
// Here I want to store the value enter by the user in the comboBox
// Without a for, I would do this
//
// String crust1 = comboCrust().getSelectedItem().toString();
//
//But comboCrust don't exist anymore cause it exist only in the for
System.out.println("To do");
}
You can see I generate my interface within some for loop, the size of those loop, is depending of some variable (define before by the user)
A JComboBox is created for chosing either the 'Crust','Size' or 'Drink'. (All three are enumerations)
And the inteface is organized with the help of "Box" horizontal and vertical. Which I put in my main panel "panelComm2" also use to make a JoptionPane at the end.
Here's what it looks like:
Yet with the way I've built my interface, I can't get the information selected by the user.
I'm looking for a way to add variables for each field of the interface, so that I could use them when the user clicks on 'Ok'.
I give up on the idea of making variables for each field, and use array of JcomboBox define prior the 'for' loop.
JComboBox[] arrayComboCrust = new JComboBox[nbPizza];
JComboBox[] arrayComboSize = new JComboBox[nbPizza];
JComboBox[] arrayComboDrink = new JComboBox[nbDrink];
And then within the loop I define the value of the array:
arrayComboCrust[i]=comboCrust;
And I set up a new 'for' loop to in my JOptionPane to read the value I wanted
Thanks to MadProgrammer

How do I get input from buttons I created using a loop?

I'm trying to make a simple calculator in Java using Swing, and I've created my buttons the following way:
//Our number keypad
public static JPanel numbers(){
//our panel to return
JPanel panel = new JPanel();
//Create and add 3x4 grid layout to panel
GridLayout gl = new GridLayout(3, 4);
panel.setLayout(gl);
//For creating and adding buttons to panel
for(int i = 0; i < 10; i++){
//Create a new button where the name is the value of i
String name = "" + i + "";
JButton button = new JButton(name);
//add action listener
button.addActionListener(handler);
//Add button to panel
panel.add(button);
}
return panel;
}
My question is how do I reference each specific button in my event handler? I can't think of a way to do this without having to manually create each button rather than using a loop.
Thanks.
In your listener, call event.getSource(), and that will return the button which has been pressed. Get the text of the button, and you have its number.
Or create a different instance of your handler for every button, and pass the value of the button (i) to the constructor of the handler. This last solution is cleaner, IMO, because it doesn't depend on the text of the button. If you replaced the text by an image, for example, the first technique wouldn't work anymore.
You can distinguish created buttons by adding the following inside handler:
String buttonText = ((JButton) e.getSource()).getText();
if (<text1>.equals(buttonText)){
//do the stuff
} else if (<text2>.equals(buttonText)){
//do the stuff
} else {
//do the stuff
}
Method #1: go through the child components of the parent JPanel (quite tedious, has to be rebuilt every time you modify the contents of that JPanel). Make sure they're JButtons by using an if . . instanceof clause.
Method #2: as you create them in that loop, add them to a List (or even better, a Map). I prefer a Map personally as it lets me customise the key for that specific JComponent
i.e.
HashMap<String, JComponent> buttonList = new HashMap<String, JComponent>();
for(. .) {
buttonList.put("nameForEachButton", button);
}
I recommend generating the button name based off of the loop counter. Either use your existing name value, or just set it to "button" + i;
Declare your buttons using an array.
JButton[] button = new JButton[9]; //outside the for loop
for (int i = 0; i < 10; i++) {
//put your code
button[i] = new JButton(name);
//your code
}

Java iterate through JList which contains JPanel - JLabel

I am trying to iterate over a JList where each item contains:
JPanel - JLabel
Currently what i have is:
System.out.println("Reading all list items:");
System.out.println("-----------------------");
for (int i = 0; i < menuList.getModel().getSize(); i++) {
Object item = menuList.getModel().getElementAt(i);;
System.out.println("Item = " + item);
}
The output i get is:
Item =
javax.swing.JPanel[,0,0,0x0,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
Instead i want to access the text that is inside the JPanel.
How could this be done?
Edit:
This is how i add my JPanel to the JList
menuList = new JList(v);
v = new Vector <String> ();
menuList.setListData(v);
.....
// get our images
Icon pingImage = new javax.swing.ImageIcon(getClass().getResource("/resources/icnNew.png"));
// add the images to jlabels with text
JLabel pingLabel = new JLabel("Hi there", pingImage, JLabel.LEFT);
// create the corresponding panels
JPanel pingPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
// add the labels onto the panels
pingPanel.add(pingLabel);
v.add(pingPanel);
So the text i want to find is "Hi there"
Then what you need is to check for the elements inside that JPanel. I mean, a panel is a container of UI elements, that said, you need to check for the elements, once you checked for that you need to compare whether it is a label or not, if it is a label then you will be able to get the text of that label.
Can't you show us the code, probably could be easier if you provide the snippet.

Categories

Resources