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.
Related
Okay, so I have this JFrame frame and I'm trying to load all of the components into a JLabel ArrayList. the frame has a LayeredPane and around 20 JLabels scattered across. Some of them have a different z-index/layer index
ArrayList<JLabel> labelList = new ArrayList<>();
for(Component i : frame.getComponents() ) {
if (i instanceof JLabel) {
labelList.add((JLabel) i);
}
}
System.out.println(labelList);
but when I try to print out the ArrayList, it just prints an empty Array.
When I hover over the .getComponents(), it actually shows that all of the JLabels are in fact contained in the method.
And it doesn't give out any errors either, like Component not being able to convert to JLabel etc.
edit: I did as #camickr suggested, and it show that only the contentPane is grabbed. I probably misunderstood how the .getComponents() works.
edit2 just changed the code to:
ArrayList<JLabel> labelList = new ArrayList<>();
for(Component i : layeredPane.getComponents() ) { //layeredPane being the name of the JLayeredPane, suprisingly
labelList.add((JLabel) i);
}
System.out.println(labelList.toArray().length);
And it works.
I am a very dumb indiviudal.
ArrayList<JLabel> labelList = new ArrayList<>();
for(Component i : layeredPane.getComponents() ) { //layeredPane being the name of the JLayeredPane, suprisingly
labelList.add((JLabel) i);
}
System.out.println(labelList.toArray().length);
is the solution. It didn't work due to me trying to grab everything from the frame, but the only thing on the frame was the layered Pane, where all the other components were.
Some swing components i have:
//JList
DefaultListModel listModel = new DefaultListModel();
JList list = new JList(listModel);
//JTabbedPane
JTabbedPane tabbedPane = new JTabbedPane();
frame.add(tabbedPane);
//JSplitPane split
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,list , tabbedPane);
splitPane.setDividerLocation(200);
frame.add(splitPane);
//JScrollPane & JTextPane to go inside the tabbed panes
JTextPane textPane = new JTextPane();
textPane.setFont(new Font("Calibri",Font.PLAIN,14));
JScrollPane scrollPane = new JScrollPane(textPane);
When a user "Opens" a text file, it should display it on a JList and on the JTextPane inside of the JTabbedPane. This is what I've tried:
int count = tabbedPane.getTabCount();
//Add the selected file's name as a string to tabbedPane & listModel.
tabbedPane.addTab(file, scrollPane);
tabbedPane.setSelectedIndex(count);
listModel.addElement(file);
list.setSelectedIndex(count);
The error I get:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1, Tab count: 1
I've been told to keep a reference to the original tabbed pane so that the code in an ActionListener can reference this variable and add more - but I didn't understand this (I'm new). Any help would be highly appreciated.
list.setSelectedIndex(count);
Java indexes are zero based. The code should be:
list.setSelectedIndex(count - 1);
I've been told to keep a reference to the original tabbed pane
and you are still not doing that.
JTabbedPane tabbedPane = new JTabbedPane();
That is a local variable, not an instance variable. How does that code look like the code from the link I provided you with in your last question???
Local variables and instance variable are basic Java. If you don't understand these you should not be working with a GUI. Read your text book first for Java basics. Read the tutorial link I gave you. Download the working code and take the time to understand it!!!
I'm using the graphic tool of netbeans and I have a JPanel on which I put a JTextArea.
Then, I need to create a JList on the JTextArea, but it is created below.
https://gyazo.com/7f8c3613317b49e72edea34c040115c1
Is there any way to sort the elements of a JPanel or how can I do it?
Thank you
The basic code would be something like:
int offset = textArea.getCaretPosition();
Rectangle location = textArea.modelToView(offset);
JList list = new JList(...);
list.setVisibleRowCount(...);
JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setSize(scrollPane.getPreferredSize();
scrollPane.setLocation(location.x, location.y);
textArea.add(scrollPane);
Once you select an item from the list you would then need to remove the scrollpane from the text area.
I am trying to make a 2x2 grid layout that has a JLabel on the top left, and three buttons on the other three spaces. When I do this, I get the unexpected result of one big button (filling up the entire JDialog) that says "Do you want to push me". I don't know why this result shows up, please help, Thanks!
public void sinceyoupressedthecoolbutton() {
JDialog replacementwindow = new JDialog(); //Like a window
JButton best = new JButton("best");
JButton first = new JButton("FIRST");
JButton second = new JButton("Second");
replacementwindow.setLayout(new GridLayout(2,3,0,0)); //Row, column, distance horizontally, distance vertical
JPanel panel = new JPanel();
replacementwindow.add(panel); //adding the JPanel itself
replacementwindow.add(first);
replacementwindow.add(second);
replacementwindow.add(best);
replacementwindow.setSize(500, 500);
replacementwindow.setTitle("NEW WINDOW!");
replacementwindow.setVisible(true);
}
It's because you set the layout of your JButton, and not of your JDialog
Change
label.setLayout(new GridLayout(2,2,0,0));
to
YES.setLayout(new GridLayout(2,2,0,0));
Also, your variable called label is a JButton, you probably want to change that.
Don't add components to a button. You add components to a panel.
So the basic code should be:
JDialog dialog = new JDialog(...);
JPanel panel = new JPanel( new GridLayout(...) );
panel.add(label);
panel.add(button1);
...
dialog.add(panel);
Also, variable names should NOT start with an upper case character! "Yes" does not follow Java standards. The other variables do. Be consistent!
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