Dynamic fields addition in java/swing form - java

I'm pretty new to java, and using netbeans for design a UI.
What I am trying to do is...
in the form. there are a jComboBox and a JTextField, where user can input the service he is choosing and an observation. So far so good. JComboBox is populated from database entries.
The problem is, a user can input N different services at once (there are too much to be a bunch of checkboxes). I was thinking into add a "[+]" button (along with a "[-]" for removal). Thus, users click on [+] and another new line with a jcombobox + jtextfield appear right below the previous ones.
I'm stucked at this point. On [+] button ActionPerformed I just can't clone and add previous nodes. Any idea on how proceed.
My background is webdev. Doing this with javascript would be really quick. Well, I think you already know what I'm trying to do. Waiting for some light. Thx.

You're on the right track. Here's some source code to give you some ideas
The basic idea is that the EntryList is responsible for keeping track of the rows to display; each row has a plus/minus button, and then delegates out the actual adding/removing to this EntryList. It also exposes methods to disable the minus/plus button so that the list view can ensure that you don't remove a single entry (so that you don't have an empty display)
This doesn't work perfectly; you'll notice you need to resize the frame to get the new rows to show up correctly. But this should be enough to get you started.

Create your main panel to use a layout manager that displays component horizontally. The Box class is easy to use for this. Then you just create a new panel with the components you want to display and add this panel to your main panel. Something like:
JComboBox checkBox = new JComboBox(...);
JTextField textField = new JTextField(...);
JPanel row = new JPanel();
row.add( comboBox );
row.add( textfield );
mainPanel.add( row );
mainPanel.revalidate();

Related

Allow Textfield Inputs to be converted into a button

I am currently trying to develop a volunteer app where the administrator can add a volunteer's name into a textfield, and have this input but converted into a new button each time the admin enters a name. I am new to GUI development, so how would I do this? I have tried passing the input as a String into a method, but I am unsure on how to create multiple buttons with this design.
Defining UI elements
First to check what you need to implement this quickly.
You need a panel for your text field and I went for a button to enter current text field input.
You also need a panel where you are adding your generic buttons
I also added a list of buttons for convenience, because you likely intend to do something with those buttons later on, and so access is desired
// UI elements to type in input and create buttons
private JPanel inputPanel = new JPanel();
private JTextField textField = new JTextField();
private JButton addGenericButtonBtn = new JButton( "ADD NEW BUTTON" );
// UI elements to put your generic buttons into
private JPanel genericButtonsPanel;
private List<JButton> buttonList = new ArrayList<>();
Creating layouts
You will likely need layouts and button styling, e.g. setting sizes for the buttons at least might be necessary, though I will not post that specific code here. The layouts I chose will put your text field and the button to create a generic button horizontally in proximity to one another and the generic buttons will be stacked vertically in the container below:
inputPanel.setLayout( new BoxLayout( inputPanel, BoxLayout.X_AXIS ) );
genericButtonsPanel.setLayout( new BoxLayout( genericButtonsPanel, BoxLayout.Y_AXIS ) );
Adding your elements to the current hierarchy of UI elements
These pannels must be added to the parent container whichever it is you are working with. Let's say parentContainer is a JPanel and the one where you want to add all of those elements to:
parentContainer.inputPanel.add( textField );
parentContainer.inputPanel.add( addGenericButtonBtn );
parentContainer.add( inputPanel );
parentContainer.add( genericButtonsPanel );
Adding generic buttons via ActionListener
The way this is designed is so that you can type into the text field and then press the "ADD NEW BUTTON" button in order to create generic buttons and add them to the second container genericButtonsPanel. So what remains is an action listener for addGenericButtonsBtn in order to accomplish this:
addGenericButtonBtn.addActionListener( e ->
{
String txt = textField.getText();
JButton genericBtn = new JButton( txt );
buttonList.add( genericBtn ); // this is merely to store the generated buttons for future access
genericButtonsPanel.add( genericBtn );
text.setText( "" ); // optional clear of the text field
// this call is mandatory, otherwise the changes to the hierarchy of UI elements will not be reflected
revalidate();
});
Further reading
This is a very minimalistic example which fulfills the requirements you described. This was just tested on my machine and works as expected. There is also a myriad of ways to go about solving this, so you might see some different solutions.
The presented solution lacks details, such as setSize, setBackground, setBorder and other UI property setters, so you would have to style your UI the way you need it to look yourself.

Creating Dynamic JLabels for sort of a messenger app using Java

So I am trying to make a messenger sort of app with Java Drag and Drop in Netbeans.
I am fairly new at it. I initially want to take a string from the text area and display it in a JLabel in another panel. I tried to do it in the following process but it did not work.Can someone please help?
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
int i=0;
message = messageType.getText();
JLabel messageLabel = new JLabel();
messageLabel.setText(message);
messageLabel.setSize(100, 100);
messageLabel.setAlignmentX(0);
messageLabel.setAlignmentY(0);
JOptionPane.showMessageDialog(null, message);
clientPanel.add(messageLabel);
messageLabel.setVisible(true);
}
We have no idea what layout manager clientPanel is using and so do not know how well it will accept a JLabel being dropped into it, so as asked your direct question is unanswerable, other than to say you should always call revalidate() on a container (clientPanel) and then repaint() after adding or removing components so that the container re-lays out its components and then redraws them.
I advise against creating new JLabels for this. Much easier to set up the GUI including all necessary JLabels from the very beginning, give them text, empty spaces if need be, and then during the program set the text of an existing JLabel.
If on the other hand you wish to show multiple messages on the cientPanel, then consider using a JList<String> or a non-focusable JTextArea.

Is there any better way then keeping multiple JTabbedPanes inside a single JFrame?

This is my menu screen. It is a JTabbedPane that when the user clicks on any of the tabs I set the menu's visibility to false and set visibility of another tabbed pane to true.
Say the user clicked on stock, then the window will look something like this:
When the user clicks on the "<<" tab it will set stock's visibility to false and menu's visibility to true.
Is it better to just create multiple JFrame files and do the same instead of adding multiple TabbedPanes inside a single frame? It's getting kind of hard to maintain the single .java file for the entire JFrame.
Yes you can also do this,in this way:
JTabbedPane preupdatetab = new JTabbedPane();
preupdatetab.setForeground(new Color(255,0,0).darker());
preupdatetab.setBounds(30,15,930,300);
preupdate.add(preupdatetab);
precomplete.setLayout(null);
preupdatetab.add(precomplete,"Complete Change");
preonce.setLayout(null);
preupdatetab.add(preonce,"Qty Change");
changelocationpanel = new JPanel();
changelocationpanel.setLayout(null);
preupdatetab.add(changelocationpanel,"Change Location");
changesaleprice = new JPanel();
changesaleprice.setLayout(null);
preupdatetab.add(changesaleprice,"Change Sale Price");
changebookprice = new JPanel();
changebookprice.setLayout(null);
preupdatetab.add(changebookprice,"Change Book Price");
changevendor = new JPanel();
changevendor.setLayout(null);
preupdatetab.add(changevendor,"Change Vendor");
changeitemname = new JPanel();
changeitemname.setLayout(null);
preupdatetab.add(changeitemname,"Change Item Name");
The other variables are globally declared JLabel so don't be confused
and the following picture will clear you more about this.
I have a similar menu style in one of my applications. I would do one of the following:
For better organization I would move your second JTabbedPane to another JFrame and swap the code out. This would be quick, give you no new functionality, but would make your code easier to keep track of.
As the other poster showed you can do both tabs above. This would separate the code and give the user the functionality of going "Up a level" without having to go "back".
What I like to do is a combination of the two. For the main menu, keep your tab on the left but for the sub menus have a separate JTabbedPane above that loads into the frame when the first menu is accessed. It gives your windows a clean look, a way to easily navigate everything, and it will train the users to look left for big changes and up for smaller ones. That way, once your users are comfortable with that you can make more menus act that way and it becomes more intuitive the more they use it.

JList and JScrollPane don't respond/are inaccessible

I am trying to implement a basic GUI where a user can move objects from one JList to another. The JLists should be contained within a ScrollPane so size is not an issue. Basic functionality is good, items will move and remove with button presses. However, the JList and JScrollPane that items are added to will display correctly and detect if a ScrollBar is necessary but do not interact AT ALL with the user for some reason. The user cannot select from the JList nor scroll the ScrollPane. Rough idea of the code below;
public void createJList(Type[] dataToList){
someScrollPane = new JScrollPane(); //someScrollPane is private global
someScrollPane.setBounds(numbers here);
this.add(someScrollPane); //this is a custom frame class
aList = new JList<Type>(dataToList);
someScrollPane.setViewportView(aList);
This is a rough idea. I also add a listener at some stage but since the scrollpane isn't working either I may as well leave that for later. I use this code for both the working and non-responsive JLists and ScrollPanes exactly the same.
Of note, I call this method everytime the list I want to display is changed. I'm thinking maybe because the JList and ScrollPane keep getting created, something is broken?

Java Swing Scrollpane in NetBeans

I have Java application which adds JTextFields # runtime to JPanel. Basically user clicks a button and new JTextField is added, clicks again added again...
Each new JTextField is directly below the previous one. Obviously I run out of space pretty soon so I'm trying to use JScrollPane and thats where the hell begins, because it just doesnt work no matter what I try.
Right click on JPanel and Enclose in Scroll Pane. Didnt work.
After reading some examples I realized I must have JPanel as an argument for JScrollPane constructor. Which I did via right clicking on ScrollPane and CustomizeCode. Because apparently auto-generated code is protected in NetBeans and I cannot just change all those declarations, etc. manually. Still doesnt work.
I did try to set PreferedSize to null for JPanel and/or JScrollPane, didnt help.
JScrollPane is a child of lets call it TabJPanel (which in turn is a tab of TabbedPane). I tried to mess with their relationships, basically trying every possible way of parentship between JFrame, JPanel(holding textfields), TabJPanel and JScrollPane, but nothing worked.
I also made VerticalScrollBar "always visible" just in a case. So I see the scrollbar, it's just that populating that JPanel with JTextFields does not affect it.
When there are too many JTextFields I they go "below" the bottom border of JPanel and I cannot see them anymore.
Code for adding new JTextFields is like this, in a case it's relevant.
JTextField newField = new JTextField( columns );
Rectangle coordinates = previousTextField.getBounds();
newField.setBounds(coordinates.x , coordinates.y + 50, coordinates.width, coordinates.height);
JPanel.add(newField);
JPanel.revalidate();
JPanel.repaint();
Sorry for a long post I'm just trying to provide as much info as possible, because being newbie I dont know whats exactly relevant and whats not. Thanks in advance :)
As there is another answer now, I'm adding my suggestion too.
This sounds exactly like a problem to use a JTable with a single column. JList is not yet editable (and might never be).
JTable would handle the layout problems for you, and you can easily access the values via the table.
Use your own TableModel (a simple Vector should be sufficient in your case), and add values to it.
An option you have is to utilize a LayoutManager, instead of setting the bounds directly on the components. To test this, a simple single column GridLayout with the alignment set to vertical should prove the concept.
panel.setLayout(new GridLayout(0,1));
zero in the rows param allows for rows to be added to the layout as needed.
I do this way to add a scrollpane, create a panel and fill it with few components, then create a scrollpane in the component you want to add it, cut and paste the panel in which all your details will fall in and resize the scrollpane.Because the components take a larger space than the one visible right click on the scrollpane and select design this container, there you can increase the size of the scrollpane and add as many components as you have.

Categories