Can I add elements to a Java GUI? - java

I want to know how I can make a Java program where an unknown amount of objects can be added to a GUI depending on user input. I can program in objects one at a time within the program, but I haven't seen a more dynamic program.
Can I do that with Java? If not, what can I do it with?
For more information, here's a picture.
There can be more than one question per question block, and each question can have it's own question block.

Yes you can dynamically add and remove components. The basic code would be:
panel.add( ... );
panel.revalidate();
panel.repaint();

Ofcourse you can do it with Java Swings. All you gotta do is based on user input you gotta take a decision to add new JPanels. From the picture you've given in the example, you would need to add a Q&A block dynamically. Simply attach that to any event handler within your application so that it gets added dynamically
public getQandAPanel(){
JPanel questPanel = new JPanel();
JPanel answerPanel = new JPanel();
JPanel wrappingPanel = new JPanel();
wrappingPanel.setLayout(new GridLayout(0,1));
//CODE TO DECORATE question and answer panels should go here
wrappingPanel.add(questPanel);
wrappingPanel.add(answerPanel);
}
Now everytime when you call this getQandAPanel, this would return you a fresh JPanel everytime which you can add it to your parent JFrame. You should have a good idea of Java Swings to know what I'm talking about.

Related

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.

adding swing components at run time in netbeans [duplicate]

This question already has answers here:
Closed 10 years ago.
i have learnt core java and just started working with netbeans,but i am stuck at a point when i was trying to add the components like buttons,labels etc. at the run time in my project.I searched for it on google but the examples which i studied include some extra overhead of using panels in them,,,,but why can't i create the components at run time as i was creating them in the simple editor like notepad as follows
JButton b4=new JButton("ok");
add b4;
its not working.
To add Swing framework elements at runtime, you need to have a JFrame to add the elements to. A JFrame is just a window, like any other window you use (and just like NetBeans has), and it has a method called add(Component comp). The parameter is whichever Swing or AWT component you want to add to the JFrame. Here is some sample code to get you started:
// This line creates a new window to display the UI elements:
JFrame window = new JFrame("Window title goes here");
// Set a size for the window:
window.setSize(600, 400);
// Make the entire program close when the window closes:
// (Prevents unintentional background running)
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// This makes it so we can position elements freely:
window.setLayout(null);
// Create a new button:
JButton b4 = new JButton("ok");
// Set the location and size of the button:
b4.setLocation(10, 10);
b4.setSize(100, 26);
// Add the button to the window:
window.add(b4);
// Make the window visible (this is the only way to show the window):
window.setVisible(true);
Hopefully, this helps you out! I remember when I started Java, and I would highly recommend getting as good as possible at non-GUI related stuff first, but if you are ready for Swing, then the code above should work. Best of luck!

how can I use a variable in multiple jpanels?

I have a frame with a var , I added that var to a JPanel, and if I want to add the same var to another JPanel, it`s disappearing from the first JPanel. I want a logical explanation for my problem please, thank you !
I want to store my JLabel in both of my jpanels.
public class Gui {
JPanel panel1, panel2;
JLabel text = new JLabel("some text");
JFrame frame = new JFrame();
public Gui {
panel1 = new JPanel();
panel1.setLayout(null);
panel1.add(text);
panel1.getComponent(0).setBounds(50,50,50,50);
panel1.setBorder(BorderFactory.createLineBorder(Color.black));
panel1.setBounds(x,y,w,h);
// it`s working, the labels it`s visible
panel2 = new JPanel();
panel2.setLayout(null);
panel2.add(text);
panel2.getComponent(0).setBounds(100,100,50,50);
panel2.setBorder(BorderFactory.createLineBorder(Color.black));
panel2.setBounds(x,y,w,h);
//it`s not working, the label ins`t visible ...
frame.add(panel1);
frame.add(panel2);
}
}
Disclaimer: I am editing my answer in response to comments from the OP. However, I am still not entirely sure about some of the details of the question. I will gladly edit my answer as more clarifications are given.
Answer: One possible solution is to create subclasses of the Swing components you are using. For example,
public class MyPanel extends JPanel {
private JLabel label = new JLabel("some text");
public MyPanel() {
this.add(label);
}
}
Now you can create multiple instances of MyPanel which each have its own JLabel. Then you can add these panels to your frame.
Added: With the additional information given in the comments, I would go a step further and create a custom JFrame class:
public class MyFrame extends JFrame {
private MyPanel panel = new MyPanel();
public MyFrame() {
this.add(panel);
}
}
Now you can create several instances of MyFrame. If you want to go even further, you can add parameters to the constructors of both of these custom classes to set the JLabel text to different values in each instance MyFrame. I will leave the details as an exercise to the reader. (Of course, please ask if you get stuck, though.)
Just as it's discussed with in other posts. All Swing UI components (ie JLabel included) can only have one parent (ie JPanel). If you add it to another panel it will remove itself from the prior parent. There are very good reasons for this behavior. For example, JPanel 1 might not use the same Layout as JPanel 2 and hence the label would have to support two different placements within each JPanel. The whole point of using Objects as components is to provide encapsulation of data like (font, position within the parent, width, height, etc) inside that object. If you want two visual elements just create another element. Now that creates a problem "How do you synchronize the data across all of these controls?" That's basically scratching how do you build a proper Swing architecture for your program?
What you don't want to do is use the Swing component model (ie. Jabel, JTextField, etc) as your data model. And after reading your question and code I believe that's what you are doing. You may not realize it. UI Components should be used for display only. They reflect what is in the data model. So you'll want to create a model that doesn't involve Swing. It should model your problem regardless of how its displayed. That means you shouldn't assume it will always be Swing or web, etc.
There are very practical reasons for this. Say in a year you want to redesign your UI. If you combined the view components and data model together you pretty much have to start completely over. Even if you aren't switching technologies. Say you are switching from a JList to a JTable or a JTreeTable. Just simple changes of the types of components you have on the screen can be an absolute nightmare if you don't segment your view from the model. Plus the View displays thing, but the model might need information that isn't displayed to the user but is tied to what is being displayed. For example, the ID of the row in the database. If you stuff the view and data model together you have to play little hacks to store this invisible information in weird ways. Things that make it hard for other people to understand.
If you don't know what I mean you either will in 6 months when you have to make your first major redesign or you'll save yourself some pain now and try and understand what I mean now. Just simple POJOs will suffice. Then share those POJOs with your Swing components. For example:
MySpecialPanel panel1 = new MySpecialPanel();
MyOtherSPecialPanel panel2 = new MyOtherSpecialPanel();
frame.add( panel1 );
frame.add( panel2 );
...a little while later...
MySpecialPOJO specialPOJO = ...some call to a service...;
panel1.setSpecialPOJO( specialPOJO );
panel2.setSpecialPOJO( specialPOJO );
Notice that I created two subclasses of JPanel called MySpecialPanel and MyOtherSpecialPanel. Inside there they create the components contained within them. Then then expose a setter method taking a data model object of type MySpecialPOJO. Inside those methods we might see something like the following:
public void setSpecialPOJO( MySpecialPOJO specialPOJO ) {
this.model = specialPOJO;
textField1.setText( specialPOJO.getName() );
textField2.setText( specialPOJO.getDescription() );
radioButtonGroup.setSelected( specialPOJO.getGender() );
....
}
Now you have a way to take a model object, and update the relative UI components that make up that view. Notice it doesn't care about any other external dependencies (ie where it got the object from). It just updates the controls it owns to reflect what's carried by the POJO. Now if you follow these simple rules it makes instantiating your special panels easy. Whether you need only one instance or many instances. Also if you need to move panels within your program it's pretty easy to do that if you reduce your dependencies to just your POJOs. There's a lot more to this, but for now this will get you started. You still have to figure out how to get data out of the UI and back into your POJOs (events!). Controllers, Services, etc.
This might help you as well:
Up-to-date Swing MVC example + Question
You can't. As you noticed, a control can only be attached to one window at a time, and if you try to attach it to another one, it will remove itself from the first.
Suggestions:
panel2.add(text.clone()); // clone the existing label
panel2.add(new JLabel("some text")); // make a new label from scratch

Inconsistent results in Eclipse for Java Swing

I am teaching myself Java and I am reading "Java All in One Desk Reference For Dummies." I am currently using the code provided in the book to practice Swing. Here is the code I am using that comes from the book: `import javax.swing.*;
public class JavaBook6 extends JFrame
{
public static void main(String[] args)
{
new JavaBook6();
}
public JavaBook6()
{
this.setSize(400, 400);
this.setLocation(500, 0);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("Sample");
this.setVisible(true);
JPanel pnlMain = new JPanel();
JCheckBox chkMy = new JCheckBox("Save");
JButton btnMy = new JButton("Search");
JTextField txtMy = new JTextField(20);
pnlMain.add(chkMy);
pnlMain.add(txtMy);
pnlMain.add(btnMy);
this.add(pnlMain);
}
}
I seem to get inconsistent results when I press run. A window always shows up. However, sometimes the only thing displayed in the window is the Frame title and other times the components such as JCheckBox, JTextArea and JButton show up, as I would expect.
My question is why do the components show up sometimes and not others? I have tried using other components and get the same inconsistent results.
As I stated I am a beginner and I therefore have a very basic understanding of how java works, so please forgive me if the answer to my question is obvious.
I'm not too impressed with the text book:
The GUI should be created on the EDT. Read the section from the Swing tutorial on Concurrency for more information. I would also recommend you use the examples from the tutorials since they incorporate the suggestions from the tutorial.
Component must be added to the GUI before the setVisible( true ) method is invoked. (There are ways around this, but for now keep it simple and follow this rule).
You generally need to do...
this.pack();
before it will display everything.
I suspect if you resize the window, everything shows up?
Adding the pack() tells the layout manager to position and size all the components.
Also if you resize the window or force it to refresh in some way it will also display the components.

Java GUI assignment, no idea how to tackle it?

Sorry about this question but I have been struggling with an assignment my professor gave us for days and have no idea where to begin. I don't want someone to do it for me or anything, I am just looking to learn/get some good pointers because I can't find a foothold in this at all.
The assignment is as follows :
Implement a graphical user interface with the GridLayout class with a 10 5 grid of JButtons and JLabels. The JButtons should be on the top five rows and the JLabels should be on the next five rows. (The first JButton should have the text 1-1 and the last the text 5-5.) The JButton on the i th row and j th column should have the text i - j on it. The text of the JLabels should be 0.
The purpose of the JLabels is to count the clicks of the corresponding JButtons. For example, when a user clicks button
i - j for the first time, the text of the JLabel of the (5 + i )th row and j th column should change to 1.
You are not allowed to use any instance variables.
Hint 1: use and inner class for the labels.
Hint 2: you can increment the “number” the label by getting the text of the label, parsing it to an int with Integer.parseInt( ), and by changing the text of the label.
You must also add one more JButton which resets the counters on the JLabels. The
text on the JButton should be reset.
So far I have just been studying notes with no understanding or cluelessly typing away and come up with a completely non-functioning desperate attempt which is as follows :
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class NewFrame extends JFrame {
private static JButton[] buttons;
public static void main ( String[] args ) {
NewFrame frame = new NewFrame( );
}
public void NewFrame( ){
JFrame frame = new JFrame ("JFrame");
JPanel panel = new JPanel( );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
int noOfButtons = 25;
buttons = new JButton[ noOfButtons ];
for(int i = 0; i<buttons.length ; i++){
buttons[i] = new JButton();
panel.add(buttons[i]);
JLabel label = new JLabel( "Initial Text" );
}
frame.getContentPane( ).add( panel );
frame.setSize( 500, 500);
frame.setVisible( true );
}
}
Can someone please offer me some advice or hints here as I have been struggling with this for an age ?
Please have a look at this link: So, You Need to Write a Program but Don't Know How to Start which will give you great tips on how to start. The key is to break down your big problem into small steps and then try to solve each step in isolation. Then if you get stuck at least you'll be able to post a much more specific question, one that is more easily answered with a specific and helpful answer. Another good resource are the Swing tutorials which can show you how to use the various Swing components including JFrames, JPanels, JButtons, text components, and what not. You can find them here: Using Swing Components
Best of luck!
Edit 1:
Your code now compiles but there are two glaring issues that first need to be fixed:
1) Your class has no constructor but rather a "pseudo-constructor". Remember constructors have no return type, not even void.
2) You don't use a GridLayout.
Other issues: again the key is to break the problem down. I recommend you do just that on paper, and then type your version of the steps you think you need to solve the problem. Then we can go through them one at a time.
Generally, when you write a Swing application, your main class extends JFrame. You do all the initialization / create the buttons / etc in the constructor, then create an instance of the class in main()
-- edit --
see hovercraft's comment - you don't have to do the following in the constructor of an extended JFrame. Just change this to your JFrame variable if you do it externally.
The java documentation is your best friend - use it. http://download.oracle.com/javase/6/docs/api/
Create a GridLayout object, assign it to your content pane (this.getContentPane()) with setLayout
Create your buttons / labels, add those to the content pane
etc, etc
Look at the documentation for JButton.setActionCommand, JButton.addActionListener
You can access the labels later to increment / reset them with this.getContentPane().getComponents(), or one of the other access methods
Before I look at the code, you will surely need the Java tutorials on buttons and actions:
http://download.oracle.com/javase/tutorial/uiswing/components/button.html
http://download.oracle.com/javase/tutorial/uiswing/misc/action.html
The first issue with your code is that you use an instance variable to store the buttons in an array. You don't need this, since you are already adding them to the panel immediately.
The second issue is actually getting your buttons to do stuff when clicked. You need to add an ActionListener of your own design to each button, as follows:
myButton = new JButton();
myButton.addActionListener(new MyButtonListener());
and declare some MyButtonListener:
public class MyButtonListener implements ActionListener
{
}
the contents of the ActionListener class are beyond the scope of my help for your homework. But the Java tutorials are a great resource if you have no idea how to implement ActionListener.

Categories